[DOCS] Docs builder

This commit is contained in:
Prateeksha Singh 2018-04-30 04:59:49 +05:30
parent d474d583ec
commit b4d098d1e8
15 changed files with 900 additions and 489 deletions

View File

@ -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,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -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;
}

View File

@ -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
};

View File

@ -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,
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"],
tooltipOptions: {
formatTooltipX: d => (d + '').toUpperCase(),
formatTooltipY: d => d + ' pts',
}
}
}
}
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']
});`,
}
],
}
}

View File

@ -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);}
});
});
}
}

File diff suppressed because one or more lines are too long

View File

@ -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 lineComposite = new Chart("#line-composite-1", dc.lineComposite.config);
let barComposite = new Chart("#bar-composite-1", dc.barComposite.config);
let bc = demoConfig.barComposite;
let barCompositeChart = new Chart (bc.elementID, bc.options);
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();

View File

@ -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,
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);
lineOptions: {
dotSize: 8
}
}
},
var dataPoints = {};
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
}
}
},
var startTs = timestampSec(start);
var endTs = timestampSec(end);
demoMain: {
elementID: "",
options: {
title: "My Awesome Chart",
data: "typeData",
type: "axis-mixed",
height: 300,
colors: ["purple", "magenta", "light-blue"],
maxSlices: 10,
startTs = timestampToMidnight(startTs);
endTs = timestampToMidnight(endTs, true);
tooltipOptions: {
formatTooltipX: function formatTooltipX(d) {
return (d + '').toUpperCase();
},
formatTooltipY: function formatTooltipY(d) {
return d + ' pts';
}
}
}
}
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;
}
}, {
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);
}
}
}, {
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));
}
});
});
}
}]);
return docSectionBuilder;
}();
var Chart = frappe.Chart; // eslint-disable-line no-undef
var dcb = new docSectionBuilder(Chart);
var lc = demoConfig.lineComposite;
var lineCompositeChart = new Chart(lc.elementID, lc.options);
var lineComposite = new Chart("#line-composite-1", dc.lineComposite.config);
var barComposite = new Chart("#bar-composite-1", dc.barComposite.config);
var bc = demoConfig.barComposite;
var barCompositeChart = new Chart(bc.elementID, bc.options);
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();
}());

View File

@ -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>

View File

@ -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}`);
forEachNode($children, (node, i) => {
if (typeof $child === 'string') {
$child = $parent.querySelector($child);
}
this.forEachNode($children, (node, i) => {
if(index >= 0 && i <= index) return;
node.classList.remove(activeClass);
});
})
$child.classList.add(activeClass);
}