瀏覽代碼

[DOCS] Docs builder

docs
Prateeksha Singh 7 年之前
父節點
當前提交
b4d098d1e8
共有 15 個檔案被更改,包括 901 行新增490 行删除
  1. +3
    -5
      dist/frappe-charts.esm.js
  2. +1
    -1
      dist/frappe-charts.min.cjs.js
  3. +1
    -1
      dist/frappe-charts.min.cjs.js.map
  4. +1
    -1
      dist/frappe-charts.min.esm.js
  5. +1
    -1
      dist/frappe-charts.min.esm.js.map
  6. +1
    -2
      dist/frappe-charts.min.iife.js
  7. +13
    -7
      docs/assets/css/index.css
  8. +29
    -1
      docs/assets/js/data.js
  9. +196
    -22
      docs/assets/js/demoConfig.js
  10. +108
    -0
      docs/assets/js/docSectionBuilder.js
  11. +1
    -2
      docs/assets/js/frappe-charts.min.js
  12. +17
    -174
      docs/assets/js/index.js
  13. +500
    -206
      docs/assets/js/index.min.js
  14. +18
    -63
      docs/index.html
  15. +11
    -4
      src/js/utils/dom.js

+ 3
- 5
dist/frappe-charts.esm.js 查看文件

@@ -18,6 +18,9 @@ $.create = (tag, o) => {
ref.parentNode.insertBefore(element, ref);
element.appendChild(ref);

} else if (i === "onClick" ) {
element.addEventListener('click', val);

} else if (i === "styles") {
if(typeof val === "object") {
Object.keys(val).map(prop => {
@@ -298,10 +301,6 @@ class SvgTip {
}
}

/**
* Returns the value of a number upto 2 decimal places.
* @param {Number} d Any number
*/
function floatTwo(d) {
return parseFloat(d.toFixed(2));
}
@@ -3677,7 +3676,6 @@ class AxisChart extends BaseChart {
// removeDataPoint(index = 0) {}
}

// import MultiAxisChart from './charts/MultiAxisChart';
const chartTypes = {
bar: AxisChart,
line: AxisChart,


+ 1
- 1
dist/frappe-charts.min.cjs.js
文件差異過大導致無法顯示
查看文件


+ 1
- 1
dist/frappe-charts.min.cjs.js.map
文件差異過大導致無法顯示
查看文件


+ 1
- 1
dist/frappe-charts.min.esm.js
文件差異過大導致無法顯示
查看文件


+ 1
- 1
dist/frappe-charts.min.esm.js.map
文件差異過大導致無法顯示
查看文件


+ 1
- 2
dist/frappe-charts.min.iife.js
文件差異過大導致無法顯示
查看文件


+ 13
- 7
docs/assets/css/index.css 查看文件

@@ -46,6 +46,14 @@ header .lead-text {
section {
margin: 4em 0; /* SAME 1 */
}
section figure {
border: 1px solid #ddd; /* SAME 3 */
border-radius: 3px;
overflow: auto;
}
section code {
margin-top: 1rem; /* SAME 2 */
}
h1 {
font-size: 3.5rem;
margin-bottom: 1.5rem;
@@ -79,16 +87,19 @@ a, a:focus, a:hover {


/* BaseCSS */
.margin-top {
.mt1 {
margin-top: 1rem; /* SAME 2 */
}
.mv1 {
margin: 2em 0 1em 0;
}
.border {
border: 1px solid #ddd;
border: 1px solid #ddd; /* SAME 3 */
border-radius: 3px;
}
.text-center {
text-align: center;
}


/* Moon images */
@@ -103,8 +114,3 @@ a, a:focus, a:hover {
margin-bottom: 5px;
font-size: 12px;
}


.text-center {
text-align: center;
}

+ 29
- 1
docs/assets/js/data.js 查看文件

@@ -1,4 +1,6 @@
import { MONTH_NAMES_SHORT } from '../../../src/js/utils/date-utils';
import { MONTH_NAMES_SHORT, SEC_IN_DAY, clone, timestampToMidnight,
timestampSec, addDays } from '../../../src/js/utils/date-utils';
import { shuffle, getRandomBias } from '../../../src/js/utils/helpers';

// Composite Chart
// ================================================================================
@@ -177,3 +179,29 @@ export const moonData = {

// ================================================================================

let today = new Date();
let start = clone(today);
addDays(start, 4);
let end = clone(start);
start.setFullYear( start.getFullYear() - 2 );
end.setFullYear( end.getFullYear() - 1 );

let dataPoints = {};

let startTs = timestampSec(start);
let endTs = timestampSec(end);

startTs = timestampToMidnight(startTs);
endTs = timestampToMidnight(endTs, true);

while (startTs < endTs) {
dataPoints[parseInt(startTs)] = Math.floor(getRandomBias(0, 5, 0.2, 1));
startTs += SEC_IN_DAY;
}

export const heatmapData = {
dataPoints: dataPoints,
start: start,
end: end
};


+ 196
- 22
docs/assets/js/demoConfig.js 查看文件

@@ -1,9 +1,9 @@
import { lineCompositeData, barCompositeData } from './data';
import { lineCompositeData, barCompositeData, trendsData, heatmapData } from './data';
import { HEATMAP_COLORS_YELLOW, HEATMAP_COLORS_BLUE } from '../../../src/js/utils/constants';

export default {
lineComposite: {
elementID: "#chart-composite-1",
options: {
config: {
title: "Fireball/Bolide Events - Yearly (reported)",
data: lineCompositeData,
type: "line",
@@ -19,8 +19,7 @@ export default {
},

barComposite: {
elementID: "#chart-composite-2",
options: {
config: {
data: barCompositeData,
type: "bar",
height: 210,
@@ -35,20 +34,195 @@ export default {
}
},

demoMain: {
elementID: "",
options: {
title: "My Awesome Chart",
data: "typeData",
type: "axis-mixed",
height: 300,
colors: ["purple", "magenta", "light-blue"],
maxSlices: 10,

tooltipOptions: {
formatTooltipX: d => (d + '').toUpperCase(),
formatTooltipY: d => d + ' pts',
}
}
}
}
demoMain: {
title: "Creating a Chart",
contentBlocks: [
{
type: "text",
content: `Booga wooga wooga Booga Booga wooga`,
},
{
type: "code",
lang: "html",
content: ` &lt!--HTML--&gt;
&lt;figure id="frost-chart"&gt;&lt;/figure&gt;`,
},
{
type: "code",
lang: "javascript",
content: ` // Javascript
let chart = new frappe.Chart( "#frost-chart", { // or DOM element
data: {
labels: ["12am-3am", "3am-6am", "6am-9am", "9am-12pm",
"12pm-3pm", "3pm-6pm", "6pm-9pm", "9pm-12am"],

datasets: [
{
name: "Some Data", chartType: 'bar',
values: [25, 40, 30, 35, 8, 52, 17, -4]
},
{
name: "Another Set", chartType: 'bar',
values: [25, 50, -10, 15, 18, 32, 27, 14]
},
{
name: "Yet Another", chartType: 'line',
values: [15, 20, -3, -15, 58, 12, -17, 37]
}
],

yMarkers: [{ label: "Marker", value: 70,
options: { labelPos: 'left' }}],
yRegions: [{ label: "Region", start: -10, end: 50,
options: { labelPos: 'right' }}]
},

title: "My Awesome Chart",
type: 'axis-mixed', // or 'bar', 'line', 'pie', 'percentage'
height: 300,
colors: ['purple', '#ffa3ef', 'light-blue'],

tooltipOptions: {
formatTooltipX: d => (d + '').toUpperCase(),
formatTooltipY: d => d + ' pts',
}
});

chart.export();`,
},
{
type: "demo",
config: {
title: "My Awesome Chart",
data: "typeData",
type: "axis-mixed",
height: 300,
colors: ["purple", "magenta", "light-blue"],
maxSlices: 10,

tooltipOptions: {
formatTooltipX: d => (d + '').toUpperCase(),
formatTooltipY: d => d + ' pts',
}
},
sideContent: {},
options: [
{
name: "lineOptions",
path: ["lineOptions"],
type: "map",
mapKeys: ['hideLine', 'hideDots', 'heatline', 'regionFill'],
states: {
"Line": [0, 1, 0, 0],
"Dots": [1, 0, 0, 0],
"HeatLine": [0, 1, 1, 0],
"Region": [0, 1, 0, 1]
},
activeState: "HeatLine"
}
],
actions: [{ name: "Export ...", fn: "export", args: [] }],
}
]
},

updateValues: { },

trendsPlot: {
title: "Plot Trends",
contentBlocks: [
{
type: "demo",
config: {
title: "Mean Total Sunspot Count - Yearly",
data: trendsData,
type: 'line',
height: 300,
colors: ['#238e38'],
axisOptions: {
xAxisMode: 'tick',
yAxisMode: 'span',
xIsSeries: 1
}
},
options: [
{
name: "lineOptions",
path: ["lineOptions"],
type: "map",
mapKeys: ['hideLine', 'hideDots', 'heatline', 'regionFill'],
states: {
"Line": [0, 1, 0, 0],
"Dots": [1, 0, 0, 0],
"HeatLine": [0, 1, 1, 0],
"Region": [0, 1, 0, 1]
},
activeState: "HeatLine"
}
],
actions: [{ name: "Export ...", fn: "export", args: [] }]
}
],

},

stateChange: {},

heatmap: {
title: "And a Month-wise Heatmap",
contentBlocks: [
{
type: "demo",
config: {
title: "Monthly Distribution",
data: heatmapData,
type: 'heatmap',
discreteDomains: 1,
countLabel: 'Level',
colors: HEATMAP_COLORS_BLUE,
legendScale: [0, 1, 2, 4, 5]
},
options: [
{
name: "Discrete domains",
path: ["discreteDomains"],
type: 'boolean',
// boolNames: ["Continuous", "Discrete"],
states: { "Discrete": 1, "Continuous": 0 }
},
{
name: "Colors",
path: ["colors"],
type: "object",
states: {
"Green (Default)": [],
"Blue": HEATMAP_COLORS_BLUE,
"GitHub's Halloween": HEATMAP_COLORS_YELLOW
}
}
],
actions: [{ name: "Export ...", fn: "export", args: [] }]
},
{
type: "code",
lang: "javascript",
content: ` let heatmap = new frappe.Chart("#heatmap", {
type: 'heatmap',
title: "Monthly Distribution",
data: {
dataPoints: {'1524064033': 8, /* ... */},
// object with timestamp-value pairs
start: startDate
end: endDate // Date objects
},
countLabel: 'Level',
discreteDomains: 0 // default: 1
colors: ['#ebedf0', '#c0ddf9', '#73b3f3', '#3886e1', '#17459e'],
// Set of five incremental colors,
// preferably with a low-saturation color for zero data;
// def: ['#ebedf0', '#c6e48b', '#7bc96f', '#239a3b', '#196127']
});`,
}
],
}
}

+ 108
- 0
docs/assets/js/docSectionBuilder.js 查看文件

@@ -0,0 +1,108 @@
import { $ } from '../../../src/js/utils/dom';

export class docSectionBuilder {
constructor(LIB_OBJ) {
this.LIB_OBJ = LIB_OBJ;
}

setParent(parent) {
// this.parent = parent;
this.section = parent;
}

setSys(sys) {
this.sys = sys;
this.blockMap = {};
}

make() {
// const section = document.querySelector(this.section);
let s = this.sys;
$.create('h6', { inside: this.section, innerHTML: s.title });

s.contentBlocks.forEach((blockConf, index) => {
this.blockMap[index] = this.getBlock(blockConf);
});
}

getBlock(blockConf) {
let block;
let type = blockConf.type;

if(type === "text") {
block = this.getText(blockConf);
} else if(type === "code") {
block = this.getCode(blockConf);
} else {
block = this.getDemo(blockConf);
}
}
getText(blockConf) {}
getCode(blockConf) {
let pre = $.create('pre', { inside: this.section });
let code = $.create('code', {
inside: pre,
className: `hljs ${blockConf.lang}`,
innerHTML: blockConf.content
});
}
getDemo(blockConf) {
let args = blockConf.config;
let figure = $.create('figure', { inside: this.section });
this.libObj = new this.LIB_OBJ(figure, args);

this.getDemoOptions(blockConf.options, args, figure);
this.getDemoActions(blockConf.actions, args);
}
getDemoOptions(options, args, figure) {
options.forEach(o => {
const btnGroup = $.create('div', {
inside: this.section,
className: `btn-group ${o.name}`
});
const mapKeys = o.mapKeys;

if(o.type === "map") {
args[o.path[0]] = {};
}

Object.keys(o.states).forEach(key => {
let state = o.states[key];
let activeClass = key === o.activeState ? 'active' : '';

let button = $.create('button', {
inside: btnGroup,
className: `btn btn-sm btn-secondary ${activeClass}`,
innerHTML: key,
onClick: (e) => {
// map
if(o.type === "map") {
mapKeys.forEach((attr, i) => {
args[o.path[0]][attr] = state[i];
})
} else {
// boolean, number, object
args[o.path[0]] = state;
}
this.libObj = new this.LIB_OBJ(figure, args);
}
});

if(activeClass) { button.click(); }
});
});
}

getDemoActions(actions, args) {
actions.forEach(o => {
let args = o.args || [];
$.create('button', {
inside: this.section,
className: `btn btn-sm btn-secondary`,
innerHTML: o.name,
onClick: () => {this.libObj[o.fn](...o.args);}
});
});
}
}


+ 1
- 2
docs/assets/js/frappe-charts.min.js
文件差異過大導致無法顯示
查看文件


+ 17
- 174
docs/assets/js/index.js 查看文件

@@ -1,23 +1,19 @@
import { $ } from '../../../src/js/utils/dom';
import { shuffle, getRandomBias } from '../../../src/js/utils/helpers';
import { HEATMAP_COLORS_YELLOW, HEATMAP_COLORS_BLUE } from '../../../src/js/utils/constants';
import { SEC_IN_DAY, clone, timestampToMidnight, timestampSec, addDays } from '../../../src/js/utils/date-utils';
import { fireballOver25, fireball_2_5, fireball_5_25, lineCompositeData,
barCompositeData, typeData, trendsData, moonData } from './data';
import demoConfig from './demoConfig';
// import { lineComposite, barComposite } from './demoConfig';
// ================================================================================
import dc from './demoConfig';
import { docSectionBuilder } from './docSectionBuilder';

let Chart = frappe.Chart; // eslint-disable-line no-undef
let dcb = new docSectionBuilder(Chart);

let lc = demoConfig.lineComposite;
let lineCompositeChart = new Chart (lc.elementID, lc.options);

let bc = demoConfig.barComposite;
let barCompositeChart = new Chart (bc.elementID, bc.options);
let lineComposite = new Chart("#line-composite-1", dc.lineComposite.config);
let barComposite = new Chart("#bar-composite-1", dc.barComposite.config);

lineCompositeChart.parent.addEventListener('data-select', (e) => {
lineComposite.parent.addEventListener('data-select', (e) => {
let i = e.index;
barCompositeChart.updateDatasets([
barComposite.updateDatasets([
fireballOver25[i], fireball_5_25[i], fireball_2_5[i]
]);
});
@@ -31,6 +27,7 @@ let typeChartArgs = {
type: 'axis-mixed',
height: 300,
colors: customColors,
valuesOverPoints: 1,

// maxLegendPoints: 6,
maxSlices: 10,
@@ -174,59 +171,10 @@ document.querySelector('.export-update').addEventListener('click', () => {
// Trends Chart
// ================================================================================

let plotChartArgs = {
title: "Mean Total Sunspot Count - Yearly",
data: trendsData,
type: 'line',
height: 300,
colors: ['#238e38'],
lineOptions: {
hideDots: 1,
heatline: 1,
},
axisOptions: {
xAxisMode: 'tick',
yAxisMode: 'span',
xIsSeries: 1
}
};

let trendsChart = new Chart("#chart-trends", plotChartArgs);

Array.prototype.slice.call(
document.querySelectorAll('.chart-plot-buttons button')
).map(el => {
el.addEventListener('click', (e) => {
let btn = e.target;
let type = btn.getAttribute('data-type');
let config = {};
config[type] = 1;

if(['regionFill', 'heatline'].includes(type)) {
config.hideDots = 1;
}

// plotChartArgs.init = false;
plotChartArgs.lineOptions = config;

new Chart("#chart-trends", plotChartArgs);

Array.prototype.slice.call(
btn.parentNode.querySelectorAll('button')).map(el => {
el.classList.remove('active');
});
btn.classList.add('active');
});
});

document.querySelector('.export-trends').addEventListener('click', () => {
trendsChart.export();
});


// Event chart
// ================================================================================

let section = document.querySelector('.trends-plot');
dcb.setParent(section);
dcb.setSys(dc.trendsPlot);
dcb.make();


let eventsData = {
@@ -262,112 +210,7 @@ eventsChart.parent.addEventListener('data-select', (e) => {
// Heatmap
// ================================================================================

let today = new Date();
let start = clone(today);
addDays(start, 4);
let end = clone(start);
start.setFullYear( start.getFullYear() - 2 );
end.setFullYear( end.getFullYear() - 1 );

let dataPoints = {};

let startTs = timestampSec(start);
let endTs = timestampSec(end);

startTs = timestampToMidnight(startTs);
endTs = timestampToMidnight(endTs, true);

while (startTs < endTs) {
dataPoints[parseInt(startTs)] = Math.floor(getRandomBias(0, 5, 0.2, 1));
startTs += SEC_IN_DAY;
}

const heatmapData = {
dataPoints: dataPoints,
start: start,
end: end
};

let heatmapArgs = {
title: "Monthly Distribution",
data: heatmapData,
type: 'heatmap',
discreteDomains: 1,
countLabel: 'Level',
colors: HEATMAP_COLORS_BLUE,
legendScale: [0, 1, 2, 4, 5]
};
let heatmapChart = new Chart("#chart-heatmap", heatmapArgs);

Array.prototype.slice.call(
document.querySelectorAll('.heatmap-mode-buttons button')
).map(el => {
el.addEventListener('click', (e) => {
let btn = e.target;
let mode = btn.getAttribute('data-mode');
let discreteDomains = 0;

if(mode === 'discrete') {
discreteDomains = 1;
}

let colors = [];
let colors_mode = document
.querySelector('.heatmap-color-buttons .active')
.getAttribute('data-color');
if(colors_mode === 'halloween') {
colors = HEATMAP_COLORS_YELLOW;
} else if (colors_mode === 'blue') {
colors = HEATMAP_COLORS_BLUE;
}

heatmapArgs.discreteDomains = discreteDomains;
heatmapArgs.colors = colors;
new Chart("#chart-heatmap", heatmapArgs);

Array.prototype.slice.call(
btn.parentNode.querySelectorAll('button')).map(el => {
el.classList.remove('active');
});
btn.classList.add('active');
});
});

Array.prototype.slice.call(
document.querySelectorAll('.heatmap-color-buttons button')
).map(el => {
el.addEventListener('click', (e) => {
let btn = e.target;
let colors_mode = btn.getAttribute('data-color');
let colors = [];

if(colors_mode === 'halloween') {
colors = HEATMAP_COLORS_YELLOW;
} else if (colors_mode === 'blue') {
colors = HEATMAP_COLORS_BLUE;
}

let discreteDomains = 1;

let view_mode = document
.querySelector('.heatmap-mode-buttons .active')
.getAttribute('data-mode');
if(view_mode === 'continuous') {
discreteDomains = 0;
}

heatmapArgs.discreteDomains = discreteDomains;
heatmapArgs.colors = colors;
new Chart("#chart-heatmap", heatmapArgs);

Array.prototype.slice.call(
btn.parentNode.querySelectorAll('button')).map(el => {
el.classList.remove('active');
});
btn.classList.add('active');
});
});

document.querySelector('.export-heatmap').addEventListener('click', () => {
heatmapChart.export();
});
section = document.querySelector('.heatmap');
dcb.setParent(section);
dcb.setSys(dc.heatmap);
dcb.make();

+ 500
- 206
docs/assets/js/index.min.js 查看文件

@@ -28,6 +28,171 @@ function __$styleInject(css, ref) {
}
}

var asyncGenerator = function () {
function AwaitValue(value) {
this.value = value;
}

function AsyncGenerator(gen) {
var front, back;

function send(key, arg) {
return new Promise(function (resolve, reject) {
var request = {
key: key,
arg: arg,
resolve: resolve,
reject: reject,
next: null
};

if (back) {
back = back.next = request;
} else {
front = back = request;
resume(key, arg);
}
});
}

function resume(key, arg) {
try {
var result = gen[key](arg);
var value = result.value;

if (value instanceof AwaitValue) {
Promise.resolve(value.value).then(function (arg) {
resume("next", arg);
}, function (arg) {
resume("throw", arg);
});
} else {
settle(result.done ? "return" : "normal", result.value);
}
} catch (err) {
settle("throw", err);
}
}

function settle(type, value) {
switch (type) {
case "return":
front.resolve({
value: value,
done: true
});
break;

case "throw":
front.reject(value);
break;

default:
front.resolve({
value: value,
done: false
});
break;
}

front = front.next;

if (front) {
resume(front.key, front.arg);
} else {
back = null;
}
}

this._invoke = send;

if (typeof gen.return !== "function") {
this.return = undefined;
}
}

if (typeof Symbol === "function" && Symbol.asyncIterator) {
AsyncGenerator.prototype[Symbol.asyncIterator] = function () {
return this;
};
}

AsyncGenerator.prototype.next = function (arg) {
return this._invoke("next", arg);
};

AsyncGenerator.prototype.throw = function (arg) {
return this._invoke("throw", arg);
};

AsyncGenerator.prototype.return = function (arg) {
return this._invoke("return", arg);
};

return {
wrap: function (fn) {
return function () {
return new AsyncGenerator(fn.apply(this, arguments));
};
},
await: function (value) {
return new AwaitValue(value);
}
};
}();

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

function $(expr, con) {
return typeof expr === "string" ? (con || document).querySelector(expr) : expr || null;
}



$.create = function (tag, o) {
var element = document.createElement(tag);

for (var i in o) {
var val = o[i];

if (i === "inside") {
$(val).appendChild(element);
} else if (i === "around") {
var ref = $(val);
ref.parentNode.insertBefore(element, ref);
element.appendChild(ref);
} else if (i === "onClick") {
element.addEventListener('click', val);
} else if (i === "styles") {
if ((typeof val === "undefined" ? "undefined" : _typeof(val)) === "object") {
Object.keys(val).map(function (prop) {
element.style[prop] = val[prop];
});
}
} else if (i in element) {
element[i] = val;
} else {
element.setAttribute(i, val);
}
}

return element;
};













// https://css-tricks.com/snippets/javascript/loop-queryselectorall-matches/

// Fixed 5-color theme,
// More colors are difficult to parse visually

@@ -267,74 +432,342 @@ var moonData = {

// ================================================================================

var demoConfig = {
lineComposite: {
elementID: "#chart-composite-1",
options: {
title: "Fireball/Bolide Events - Yearly (reported)",
data: lineCompositeData,
type: "line",
height: 190,
colors: ["green"],
isNavigable: 1,
valuesOverPoints: 1,

lineOptions: {
dotSize: 8
}
var today = new Date();
var start = clone(today);
addDays(start, 4);
var end = clone(start);
start.setFullYear(start.getFullYear() - 2);
end.setFullYear(end.getFullYear() - 1);

var dataPoints = {};

var startTs = timestampSec(start);
var endTs = timestampSec(end);

startTs = timestampToMidnight(startTs);
endTs = timestampToMidnight(endTs, true);

while (startTs < endTs) {
dataPoints[parseInt(startTs)] = Math.floor(getRandomBias(0, 5, 0.2, 1));
startTs += SEC_IN_DAY;
}

var heatmapData = {
dataPoints: dataPoints,
start: start,
end: end
};

var dc = {
lineComposite: {
config: {
title: "Fireball/Bolide Events - Yearly (reported)",
data: lineCompositeData,
type: "line",
height: 190,
colors: ["green"],
isNavigable: 1,
valuesOverPoints: 1,

lineOptions: {
dotSize: 8
}
}
},

barComposite: {
config: {
data: barCompositeData,
type: "bar",
height: 210,
colors: ["violet", "light-blue", "#46a9f9"],
valuesOverPoints: 1,
axisOptions: {
xAxisMode: "tick"
},
barOptions: {
stacked: 1
}
}
},

demoMain: {
title: "Creating a Chart",
contentBlocks: [{
type: "text",
content: 'Booga wooga wooga Booga Booga wooga'
}, {
type: "code",
lang: "html",
content: ' &lt!--HTML--&gt;\n &lt;figure id="frost-chart"&gt;&lt;/figure&gt;'
}, {
type: "code",
lang: "javascript",
content: ' // Javascript\n let chart = new frappe.Chart( "#frost-chart", { // or DOM element\n data: {\n labels: ["12am-3am", "3am-6am", "6am-9am", "9am-12pm",\n "12pm-3pm", "3pm-6pm", "6pm-9pm", "9pm-12am"],\n\n datasets: [\n {\n name: "Some Data", chartType: \'bar\',\n values: [25, 40, 30, 35, 8, 52, 17, -4]\n },\n {\n name: "Another Set", chartType: \'bar\',\n values: [25, 50, -10, 15, 18, 32, 27, 14]\n },\n {\n name: "Yet Another", chartType: \'line\',\n values: [15, 20, -3, -15, 58, 12, -17, 37]\n }\n ],\n\n yMarkers: [{ label: "Marker", value: 70,\n options: { labelPos: \'left\' }}],\n yRegions: [{ label: "Region", start: -10, end: 50,\n options: { labelPos: \'right\' }}]\n },\n\n title: "My Awesome Chart",\n type: \'axis-mixed\', // or \'bar\', \'line\', \'pie\', \'percentage\'\n height: 300,\n colors: [\'purple\', \'#ffa3ef\', \'light-blue\'],\n\n tooltipOptions: {\n formatTooltipX: d => (d + \'\').toUpperCase(),\n formatTooltipY: d => d + \' pts\',\n }\n });\n\n chart.export();'
}, {
type: "demo",
config: {
title: "My Awesome Chart",
data: "typeData",
type: "axis-mixed",
height: 300,
colors: ["purple", "magenta", "light-blue"],
maxSlices: 10,

tooltipOptions: {
formatTooltipX: function formatTooltipX(d) {
return (d + '').toUpperCase();
},
formatTooltipY: function formatTooltipY(d) {
return d + ' pts';
}
}
},
sideContent: {},
options: [{
name: "lineOptions",
path: ["lineOptions"],
type: "map",
mapKeys: ['hideLine', 'hideDots', 'heatline', 'regionFill'],
states: {
"Line": [0, 1, 0, 0],
"Dots": [1, 0, 0, 0],
"HeatLine": [0, 1, 1, 0],
"Region": [0, 1, 0, 1]
},
activeState: "HeatLine"
}],
actions: [{ name: "Export ...", fn: "export", args: [] }]
}]
},

updateValues: {},

trendsPlot: {
title: "Plot Trends",
contentBlocks: [{
type: "demo",
config: {
title: "Mean Total Sunspot Count - Yearly",
data: trendsData,
type: 'line',
height: 300,
colors: ['#238e38'],
axisOptions: {
xAxisMode: 'tick',
yAxisMode: 'span',
xIsSeries: 1
}
},
options: [{
name: "lineOptions",
path: ["lineOptions"],
type: "map",
mapKeys: ['hideLine', 'hideDots', 'heatline', 'regionFill'],
states: {
"Line": [0, 1, 0, 0],
"Dots": [1, 0, 0, 0],
"HeatLine": [0, 1, 1, 0],
"Region": [0, 1, 0, 1]
},
activeState: "HeatLine"
}],
actions: [{ name: "Export ...", fn: "export", args: [] }]
}]

},

stateChange: {},

heatmap: {
title: "And a Month-wise Heatmap",
contentBlocks: [{
type: "demo",
config: {
title: "Monthly Distribution",
data: heatmapData,
type: 'heatmap',
discreteDomains: 1,
countLabel: 'Level',
colors: HEATMAP_COLORS_BLUE,
legendScale: [0, 1, 2, 4, 5]
},
options: [{
name: "Discrete domains",
path: ["discreteDomains"],
type: 'boolean',
// boolNames: ["Continuous", "Discrete"],
states: { "Discrete": 1, "Continuous": 0 }
}, {
name: "Colors",
path: ["colors"],
type: "object",
states: {
"Green (Default)": [],
"Blue": HEATMAP_COLORS_BLUE,
"GitHub's Halloween": HEATMAP_COLORS_YELLOW
}
}],
actions: [{ name: "Export ...", fn: "export", args: [] }]
}, {
type: "code",
lang: "javascript",
content: ' let heatmap = new frappe.Chart("#heatmap", {\n type: \'heatmap\',\n title: "Monthly Distribution",\n data: {\n dataPoints: {\'1524064033\': 8, /* ... */},\n // object with timestamp-value pairs\n start: startDate\n end: endDate // Date objects\n },\n countLabel: \'Level\',\n discreteDomains: 0 // default: 1\n colors: [\'#ebedf0\', \'#c0ddf9\', \'#73b3f3\', \'#3886e1\', \'#17459e\'],\n // Set of five incremental colors,\n // preferably with a low-saturation color for zero data;\n // def: [\'#ebedf0\', \'#c6e48b\', \'#7bc96f\', \'#239a3b\', \'#196127\']\n });'
}]
}
};

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var docSectionBuilder = function () {
function docSectionBuilder(LIB_OBJ) {
_classCallCheck(this, docSectionBuilder);

this.LIB_OBJ = LIB_OBJ;
}

_createClass(docSectionBuilder, [{
key: 'setParent',
value: function setParent(parent) {
// this.parent = parent;
this.section = parent;
}
},

barComposite: {
elementID: "#chart-composite-2",
options: {
data: barCompositeData,
type: "bar",
height: 210,
colors: ["violet", "light-blue", "#46a9f9"],
valuesOverPoints: 1,
axisOptions: {
xAxisMode: "tick"
},
barOptions: {
stacked: 1
}, {
key: 'setSys',
value: function setSys(sys) {
this.sys = sys;
this.blockMap = {};
}
}, {
key: 'make',
value: function make() {
var _this = this;

// const section = document.querySelector(this.section);
var s = this.sys;
$.create('h6', { inside: this.section, innerHTML: s.title });

s.contentBlocks.forEach(function (blockConf, index) {
_this.blockMap[index] = _this.getBlock(blockConf);
});
}
}, {
key: 'getBlock',
value: function getBlock(blockConf) {
var block = void 0;
var type = blockConf.type;

if (type === "text") {
block = this.getText(blockConf);
} else if (type === "code") {
block = this.getCode(blockConf);
} else {
block = this.getDemo(blockConf);
}
}
},

demoMain: {
elementID: "",
options: {
title: "My Awesome Chart",
data: "typeData",
type: "axis-mixed",
height: 300,
colors: ["purple", "magenta", "light-blue"],
maxSlices: 10,

tooltipOptions: {
formatTooltipX: function formatTooltipX(d) {
return (d + '').toUpperCase();
},
formatTooltipY: function formatTooltipY(d) {
return d + ' pts';
}, {
key: 'getText',
value: function getText(blockConf) {}
}, {
key: 'getCode',
value: function getCode(blockConf) {
var pre = $.create('pre', { inside: this.section });
var code = $.create('code', {
inside: pre,
className: 'hljs ' + blockConf.lang,
innerHTML: blockConf.content
});
}
}, {
key: 'getDemo',
value: function getDemo(blockConf) {
var args = blockConf.config;
var figure = $.create('figure', { inside: this.section });
this.libObj = new this.LIB_OBJ(figure, args);

this.getDemoOptions(blockConf.options, args, figure);
this.getDemoActions(blockConf.actions, args);
}
}, {
key: 'getDemoOptions',
value: function getDemoOptions(options, args, figure) {
var _this2 = this;

options.forEach(function (o) {
var btnGroup = $.create('div', {
inside: _this2.section,
className: 'btn-group ' + o.name
});
var mapKeys = o.mapKeys;

if (o.type === "map") {
args[o.path[0]] = {};
}
}

Object.keys(o.states).forEach(function (key) {
var state = o.states[key];
var activeClass = key === o.activeState ? 'active' : '';

var button = $.create('button', {
inside: btnGroup,
className: 'btn btn-sm btn-secondary ' + activeClass,
innerHTML: key,
onClick: function onClick(e) {
// map
if (o.type === "map") {
mapKeys.forEach(function (attr, i) {
args[o.path[0]][attr] = state[i];
});
} else {
// boolean, number, object
args[o.path[0]] = state;
}
_this2.libObj = new _this2.LIB_OBJ(figure, args);
}
});

if (activeClass) {
button.click();
}
});
});
}
}
};
}, {
key: 'getDemoActions',
value: function getDemoActions(actions, args) {
var _this3 = this;

actions.forEach(function (o) {
$.create('button', {
inside: _this3.section,
className: 'btn btn-sm btn-secondary',
innerHTML: o.name,
onClick: function onClick() {
var _libObj;

(_libObj = _this3.libObj)[o.fn].apply(_libObj, _toConsumableArray(o.args));
}
});
});
}
}]);

var Chart = frappe.Chart; // eslint-disable-line no-undef
return docSectionBuilder;
}();

var lc = demoConfig.lineComposite;
var lineCompositeChart = new Chart(lc.elementID, lc.options);
var Chart = frappe.Chart; // eslint-disable-line no-undef
var dcb = new docSectionBuilder(Chart);

var bc = demoConfig.barComposite;
var barCompositeChart = new Chart(bc.elementID, bc.options);
var lineComposite = new Chart("#line-composite-1", dc.lineComposite.config);
var barComposite = new Chart("#bar-composite-1", dc.barComposite.config);

lineCompositeChart.parent.addEventListener('data-select', function (e) {
lineComposite.parent.addEventListener('data-select', function (e) {
var i = e.index;
barCompositeChart.updateDatasets([fireballOver25[i], fireball_5_25[i], fireball_2_5[i]]);
barComposite.updateDatasets([fireballOver25[i], fireball_5_25[i], fireball_2_5[i]]);
});

// ================================================================================
@@ -346,6 +779,7 @@ var typeChartArgs = {
type: 'axis-mixed',
height: 300,
colors: customColors,
valuesOverPoints: 1,

// maxLegendPoints: 6,
maxSlices: 10,
@@ -486,55 +920,10 @@ document.querySelector('.export-update').addEventListener('click', function () {
// Trends Chart
// ================================================================================

var plotChartArgs = {
title: "Mean Total Sunspot Count - Yearly",
data: trendsData,
type: 'line',
height: 300,
colors: ['#238e38'],
lineOptions: {
hideDots: 1,
heatline: 1
},
axisOptions: {
xAxisMode: 'tick',
yAxisMode: 'span',
xIsSeries: 1
}
};

var trendsChart = new Chart("#chart-trends", plotChartArgs);

Array.prototype.slice.call(document.querySelectorAll('.chart-plot-buttons button')).map(function (el) {
el.addEventListener('click', function (e) {
var btn = e.target;
var type = btn.getAttribute('data-type');
var config = {};
config[type] = 1;

if (['regionFill', 'heatline'].includes(type)) {
config.hideDots = 1;
}

// plotChartArgs.init = false;
plotChartArgs.lineOptions = config;

new Chart("#chart-trends", plotChartArgs);

Array.prototype.slice.call(btn.parentNode.querySelectorAll('button')).map(function (el) {
el.classList.remove('active');
});
btn.classList.add('active');
});
});

document.querySelector('.export-trends').addEventListener('click', function () {
trendsChart.export();
});

// Event chart
// ================================================================================

var section = document.querySelector('.trends-plot');
dcb.setParent(section);
dcb.setSys(dc.trendsPlot);
dcb.make();

var eventsData = {
labels: ["Ganymede", "Callisto", "Io", "Europa"],
@@ -569,104 +958,9 @@ eventsChart.parent.addEventListener('data-select', function (e) {
// Heatmap
// ================================================================================

var today = new Date();
var start = clone(today);
addDays(start, 4);
var end = clone(start);
start.setFullYear(start.getFullYear() - 2);
end.setFullYear(end.getFullYear() - 1);

var dataPoints = {};

var startTs = timestampSec(start);
var endTs = timestampSec(end);

startTs = timestampToMidnight(startTs);
endTs = timestampToMidnight(endTs, true);

while (startTs < endTs) {
dataPoints[parseInt(startTs)] = Math.floor(getRandomBias(0, 5, 0.2, 1));
startTs += SEC_IN_DAY;
}

var heatmapData = {
dataPoints: dataPoints,
start: start,
end: end
};

var heatmapArgs = {
title: "Monthly Distribution",
data: heatmapData,
type: 'heatmap',
discreteDomains: 1,
countLabel: 'Level',
colors: HEATMAP_COLORS_BLUE,
legendScale: [0, 1, 2, 4, 5]
};
var heatmapChart = new Chart("#chart-heatmap", heatmapArgs);

Array.prototype.slice.call(document.querySelectorAll('.heatmap-mode-buttons button')).map(function (el) {
el.addEventListener('click', function (e) {
var btn = e.target;
var mode = btn.getAttribute('data-mode');
var discreteDomains = 0;

if (mode === 'discrete') {
discreteDomains = 1;
}

var colors = [];
var colors_mode = document.querySelector('.heatmap-color-buttons .active').getAttribute('data-color');
if (colors_mode === 'halloween') {
colors = HEATMAP_COLORS_YELLOW;
} else if (colors_mode === 'blue') {
colors = HEATMAP_COLORS_BLUE;
}

heatmapArgs.discreteDomains = discreteDomains;
heatmapArgs.colors = colors;
new Chart("#chart-heatmap", heatmapArgs);

Array.prototype.slice.call(btn.parentNode.querySelectorAll('button')).map(function (el) {
el.classList.remove('active');
});
btn.classList.add('active');
});
});

Array.prototype.slice.call(document.querySelectorAll('.heatmap-color-buttons button')).map(function (el) {
el.addEventListener('click', function (e) {
var btn = e.target;
var colors_mode = btn.getAttribute('data-color');
var colors = [];

if (colors_mode === 'halloween') {
colors = HEATMAP_COLORS_YELLOW;
} else if (colors_mode === 'blue') {
colors = HEATMAP_COLORS_BLUE;
}

var discreteDomains = 1;

var view_mode = document.querySelector('.heatmap-mode-buttons .active').getAttribute('data-mode');
if (view_mode === 'continuous') {
discreteDomains = 0;
}

heatmapArgs.discreteDomains = discreteDomains;
heatmapArgs.colors = colors;
new Chart("#chart-heatmap", heatmapArgs);

Array.prototype.slice.call(btn.parentNode.querySelectorAll('button')).map(function (el) {
el.classList.remove('active');
});
btn.classList.add('active');
});
});

document.querySelector('.export-heatmap').addEventListener('click', function () {
heatmapChart.export();
});
section = document.querySelector('.heatmap');
dcb.setParent(section);
dcb.setSys(dc.heatmap);
dcb.make();

}());

+ 18
- 63
docs/index.html 查看文件

@@ -4,7 +4,8 @@
<meta charset="UTF-8">
<title>Frappe Charts</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="keywords" content="open source javascript js charts library svg zero-dependency interactive data visualization beautiful drag resize">
<meta name="keywords" content="open source javascript js charts library svg zero-dependency
interactive data visualization beautiful drag resize">
<meta name="description" content="A simple, responsive, modern charts library for the web.">

<link rel="stylesheet" type="text/css" href="assets/css/reset.css" media="screen">
@@ -24,18 +25,20 @@
<body>
<header>
<h1>Frappe Charts</h1>
<p class="lead-text">GitHub-inspired simple and modern SVG charts for the web<br>with zero dependencies.</p>
<div id="chart-composite-1" class="border"></div>
<p class="lead-text">GitHub-inspired simple and modern SVG charts for the web
<br>with zero dependencies.</p>
<figure id="line-composite-1" class="border"></figure>
<p class="demo-tip">Click or use arrow keys to navigate data points</p>
<div id="chart-composite-2" class="border"></div>
<figure id="bar-composite-1" class="border"></figure>
</header>

<section>
<h6>Create a chart</h6>
<p>Click or use arrow keys to navigate data points</p>
<pre><code class="hljs html"> &lt!--HTML--&gt;
&lt;div id="chart"&gt;&lt;/div&gt;</code></pre>
&lt;figure id="frost-chart"&gt;&lt;/figure&gt;</code></pre>
<pre><code class="hljs javascript"> // Javascript
let chart = new frappe.Chart( "#chart", { // or DOM element
let chart = new frappe.Chart( "#frost-chart", { // or DOM element
data: {
labels: ["12am-3am", "3am-6am", "6am-9am", "9am-12pm",
"12pm-3pm", "3pm-6pm", "6pm-9pm", "9pm-12am"],
@@ -76,14 +79,13 @@
</code></pre>

<div id="chart-aggr" class="border"></div>
<div class="btn-group aggr-type-buttons margin-top mx-auto" role="group">
<div class="btn-group aggr-type-buttons mt1 mx-auto" role="group">
<button type="button" class="btn btn-sm btn-secondary active" data-type='axis-mixed'>Mixed</button>
<button type="button" class="btn btn-sm btn-secondary" data-type='pie'>Pie Chart</button>
<button type="button" class="btn btn-sm btn-secondary" data-type='percentage'>Percentage Chart</button>
</div>
<div class="btn-group export-buttons margin-top mx-auto" role="group">
<button type="button" class="btn btn-sm btn-secondary export-aggr">Export ...</button>
</div>
<button type="button" class="btn btn-sm btn-secondary export-aggr mt1">Export ...</button>

</section>

<section>
@@ -98,20 +100,7 @@
</div>
</section>

<section>
<h6>Plot Trends</h6>
<div id="chart-trends" class="border"></div>

<div class="btn-group chart-plot-buttons mt-1 mx-auto" role="group">
<button type="button" class="btn btn-sm btn-secondary" data-type="hideDots">Line</button>
<button type="button" class="btn btn-sm btn-secondary" data-type="hideLine">Dots</button>
<button type="button" class="btn btn-sm btn-secondary active" data-type="heatline">HeatLine</button>
<button type="button" class="btn btn-sm btn-secondary" data-type="regionFill">Region</button>
</div>
<div class="btn-group export-buttons mt-1 mx-auto" role="group">
<button type="button" class="btn btn-sm btn-secondary export-trends">Export ...</button>
</div>
</section>
<section class="trends-plot"></section>

<section>
<h6>Listen to state change</h6>
@@ -123,7 +112,7 @@
<div class="image-container border">
<img class="moon-image" src="./assets/img/europa.jpg">
</div>
<div class="content-data margin-top">
<div class="content-data mt1">
<h6 class="moon-name">Europa</h6>
<p>Semi-major-axis: <span class="semi-major-axis">671034</span> km</p>
<p>Mass: <span class="mass">4800000</span> x 10^16 kg</p>
@@ -131,7 +120,7 @@
</div>
</div>
</div>
<pre><code class="hljs javascript margin-top"> ...
<pre><code class="hljs javascript mt1"> ...
isNavigable: 1, // Navigate across data points; default 0
...

@@ -140,41 +129,7 @@
});</code></pre>
</section>

<section>
<h6>
And a Month-wise Heatmap
</h6>
<div id="chart-heatmap" class="border"
style="overflow: scroll;"></div>
<div class="heatmap-mode-buttons btn-group mt-1 mx-auto" role="group">
<button type="button" class="btn btn-sm btn-secondary active" data-mode="discrete">Discrete</button>
<button type="button" class="btn btn-sm btn-secondary" data-mode="continuous">Continuous</button>
</div>
<div class="heatmap-color-buttons btn-group mt-1 mx-auto" role="group">
<button type="button" class="btn btn-sm btn-secondary" data-color="default">Green (Default)</button>
<button type="button" class="btn btn-sm btn-secondary active" data-color="blue">Blue</button>
<button type="button" class="btn btn-sm btn-secondary" data-color="halloween">GitHub's Halloween</button>
</div>
<div class="btn-group export-buttons mt-1 mx-auto" role="group">
<button type="button" class="btn btn-sm btn-secondary export-heatmap">Export ...</button>
</div>
<pre><code class="hljs javascript margin-top"> let heatmap = new frappe.Chart("#heatmap", {
type: 'heatmap',
title: "Monthly Distribution",
data: {
dataPoints: {'1524064033': 8, /* ... */},
// object with timestamp-value pairs
start: startDate
end: endDate // Date objects
},
countLabel: 'Level',
discreteDomains: 0 // default: 1
colors: ['#ebedf0', '#c0ddf9', '#73b3f3', '#3886e1', '#17459e'],
// Set of five incremental colors,
// preferably with a low-saturation color for zero data;
// def: ['#ebedf0', '#c6e48b', '#7bc96f', '#239a3b', '#196127']
});</code></pre>
</section>
<section class="heatmap"></section>

<section>
<h6>Demo</h6>
@@ -279,11 +234,11 @@
<section class="text-center">
<!-- Closing -->
<a href="https://github.com/frappe/charts/archive/master.zip"><button class="large blue button btn">Download</button></a>
<p style="margin-top: 3rem;margin-bottom: 1.5rem;">
<p style="mt1: 3rem;margin-bottom: 1.5rem;">
<!-- <a href="docs.html" style="margin-right: 1rem;" target="_blank">Documentation</a> -->
<a href="https://github.com/frappe/charts" target="_blank">View on GitHub</a>
</p>
<p style="margin-top: 1rem;">
<p style="mt1: 1rem;">
<a class="github-button" href="https://github.com/frappe/charts" data-icon="octicon-star" data-show-count="true" aria-label="Star frappe/charts on GitHub">Star</a>
</p>
<p>License: MIT</p>


+ 11
- 4
src/js/utils/dom.js 查看文件

@@ -26,6 +26,9 @@ $.create = (tag, o) => {
ref.parentNode.insertBefore(element, ref);
element.appendChild(ref);

} else if (i === "onClick" ) {
element.addEventListener('click', val);

} else if (i === "styles") {
if(typeof val === "object") {
Object.keys(val).map(prop => {
@@ -118,13 +121,17 @@ export function forEachNode(nodeList, callback, scope) {
}
}

export function activate($parent, $child, commonClass, activeClass='active', index = -1) {
let $children = $parent.querySelectorAll(`.${commonClass}.${activeClass}`);
export function activate($parent, $child, commonSelector, activeClass='active', index = -1) {
let $children = $parent.querySelectorAll(`${commonSelector}.${activeClass}`);

if (typeof $child === 'string') {
$child = $parent.querySelector($child);
}

forEachNode($children, (node, i) => {
this.forEachNode($children, (node, i) => {
if(index >= 0 && i <= index) return;
node.classList.remove(activeClass);
});
})

$child.classList.add(activeClass);
}

Loading…
取消
儲存