@@ -1717,13 +1717,12 @@ let componentConfigs = { | |||||
let newLabels = newData.map(d => d.label); | let newLabels = newData.map(d => d.label); | ||||
let oldPos = this.oldData.map(d => d.position); | let oldPos = this.oldData.map(d => d.position); | ||||
let oldLabels = this.oldData.map(d => d.label); | |||||
this.render(oldPos.map((pos, i) => { | this.render(oldPos.map((pos, i) => { | ||||
return { | return { | ||||
position: oldPos[i], | position: oldPos[i], | ||||
label: newLabels[i] | label: newLabels[i] | ||||
} | |||||
}; | |||||
})); | })); | ||||
return this.store.map((line, i) => { | return this.store.map((line, i) => { | ||||
@@ -1738,27 +1737,26 @@ let componentConfigs = { | |||||
layerClass: 'y-regions', | layerClass: 'y-regions', | ||||
makeElements(data) { | makeElements(data) { | ||||
return data.map(region => | return data.map(region => | ||||
yRegion(region.start, region.end, this.constants.width, | |||||
yRegion(region.startPos, region.endPos, this.constants.width, | |||||
region.label) | region.label) | ||||
); | ); | ||||
}, | }, | ||||
animateElements(newData) { | animateElements(newData) { | ||||
[this.oldData, newData] = equilizeNoOfElements(this.oldData, newData); | [this.oldData, newData] = equilizeNoOfElements(this.oldData, newData); | ||||
let newPos = newData.map(d => d.end); | |||||
let newPos = newData.map(d => d.endPos); | |||||
let newLabels = newData.map(d => d.label); | let newLabels = newData.map(d => d.label); | ||||
let newStarts = newData.map(d => d.start); | |||||
let newStarts = newData.map(d => d.startPos); | |||||
let oldPos = this.oldData.map(d => d.end); | |||||
let oldLabels = this.oldData.map(d => d.label); | |||||
let oldStarts = this.oldData.map(d => d.start); | |||||
let oldPos = this.oldData.map(d => d.endPos); | |||||
let oldStarts = this.oldData.map(d => d.startPos); | |||||
this.render(oldPos.map((pos, i) => { | this.render(oldPos.map((pos, i) => { | ||||
return { | return { | ||||
start: oldStarts[i], | |||||
end: oldPos[i], | |||||
startPos: oldStarts[i], | |||||
endPos: oldPos[i], | |||||
label: newLabels[i] | label: newLabels[i] | ||||
} | |||||
}; | |||||
})); | })); | ||||
let animateElements = []; | let animateElements = []; | ||||
@@ -1792,7 +1790,7 @@ let componentConfigs = { | |||||
barsWidth: data.barsWidth, | barsWidth: data.barsWidth, | ||||
minHeight: c.minHeight | minHeight: c.minHeight | ||||
} | } | ||||
) | |||||
); | |||||
}); | }); | ||||
return this.units; | return this.units; | ||||
}, | }, | ||||
@@ -1830,7 +1828,7 @@ let componentConfigs = { | |||||
this.store.map((bar, i) => { | this.store.map((bar, i) => { | ||||
animateElements = animateElements.concat(animateBar( | animateElements = animateElements.concat(animateBar( | ||||
bar, newXPos[i], newYPos[i], newData.barWidth, newOffsets[i], c.index, | bar, newXPos[i], newYPos[i], newData.barWidth, newOffsets[i], c.index, | ||||
{zeroLine: newData.zeroLine} | |||||
{zeroLine: newData.zeroLine} | |||||
)); | )); | ||||
}); | }); | ||||
@@ -1870,7 +1868,7 @@ let componentConfigs = { | |||||
c.color, | c.color, | ||||
(c.valuesOverPoints ? data.values[j] : ''), | (c.valuesOverPoints ? data.values[j] : ''), | ||||
j | j | ||||
) | |||||
); | |||||
}); | }); | ||||
} | } | ||||
@@ -1881,7 +1879,6 @@ let componentConfigs = { | |||||
let newYPos = newData.yPositions; | let newYPos = newData.yPositions; | ||||
let newValues = newData.values; | let newValues = newData.values; | ||||
let oldXPos = this.oldData.xPositions; | let oldXPos = this.oldData.xPositions; | ||||
let oldYPos = this.oldData.yPositions; | let oldYPos = this.oldData.yPositions; | ||||
let oldValues = this.oldData.values; | let oldValues = this.oldData.values; | ||||
@@ -2720,6 +2717,7 @@ class AxisChart extends BaseChart { | |||||
this.lineOptions = args.lineOptions || {}; | this.lineOptions = args.lineOptions || {}; | ||||
this.type = args.type || 'line'; | this.type = args.type || 'line'; | ||||
this.init = 1; | |||||
this.setup(); | this.setup(); | ||||
} | } | ||||
@@ -2850,8 +2848,8 @@ class AxisChart extends BaseChart { | |||||
} | } | ||||
if(this.data.yRegions) { | if(this.data.yRegions) { | ||||
this.state.yRegions = this.data.yRegions.map(d => { | this.state.yRegions = this.data.yRegions.map(d => { | ||||
d.start = scale(d.start, s.yAxis); | |||||
d.end = scale(d.end, s.yAxis); | |||||
d.startPos = scale(d.start, s.yAxis); | |||||
d.endPos = scale(d.end, s.yAxis); | |||||
return d; | return d; | ||||
}); | }); | ||||
} | } | ||||
@@ -2870,7 +2868,17 @@ class AxisChart extends BaseChart { | |||||
}); | }); | ||||
} | } | ||||
return [].concat(...this.data.datasets.map(d => d[key])); | |||||
let allValueLists = this.data.datasets.map(d => d[key]); | |||||
if(this.data.yMarkers) { | |||||
allValueLists.push(this.data.yMarkers.map(d => d.value)); | |||||
} | |||||
if(this.data.yRegions) { | |||||
this.data.yRegions.map(d => { | |||||
allValueLists.push([d.end, d.start]); | |||||
}); | |||||
} | |||||
return [].concat(...allValueLists); | |||||
} | } | ||||
setupComponents() { | setupComponents() { | ||||
@@ -3106,6 +3114,10 @@ class AxisChart extends BaseChart { | |||||
} | } | ||||
makeOverlay() { | makeOverlay() { | ||||
if(this.init) { | |||||
this.init = 0; | |||||
return; | |||||
} | |||||
if(this.overlayGuides) { | if(this.overlayGuides) { | ||||
this.overlayGuides.forEach(g => { | this.overlayGuides.forEach(g => { | ||||
let o = g.overlay; | let o = g.overlay; | ||||
@@ -3202,7 +3214,6 @@ class AxisChart extends BaseChart { | |||||
} | } | ||||
// API | // API | ||||
addDataPoint(label, datasetValues, index=this.state.datasetLength) { | addDataPoint(label, datasetValues, index=this.state.datasetLength) { | ||||
super.addDataPoint(label, datasetValues, index); | super.addDataPoint(label, datasetValues, index); | ||||
this.data.labels.splice(index, 0, label); | this.data.labels.splice(index, 0, label); | ||||
@@ -3213,6 +3224,9 @@ class AxisChart extends BaseChart { | |||||
} | } | ||||
removeDataPoint(index = this.state.datasetLength-1) { | removeDataPoint(index = this.state.datasetLength-1) { | ||||
if (this.data.labels.length <= 1) { | |||||
return; | |||||
} | |||||
super.removeDataPoint(index); | super.removeDataPoint(index); | ||||
this.data.labels.splice(index, 1); | this.data.labels.splice(index, 1); | ||||
this.data.datasets.map(d => { | this.data.datasets.map(d => { | ||||
@@ -93,7 +93,6 @@ let lineCompositeChart = new Chart (c1, { | |||||
height: 190, | height: 190, | ||||
colors: ['green'], | colors: ['green'], | ||||
isNavigable: 1, | isNavigable: 1, | ||||
isSeries: 1, | |||||
valuesOverPoints: 1, | valuesOverPoints: 1, | ||||
lineOptions: { | lineOptions: { | ||||
@@ -108,7 +107,6 @@ let barCompositeChart = new Chart (c2, { | |||||
type: 'bar', | type: 'bar', | ||||
height: 190, | height: 190, | ||||
colors: ['violet', 'light-blue', '#46a9f9'], | colors: ['violet', 'light-blue', '#46a9f9'], | ||||
isSeries: 1, | |||||
valuesOverPoints: 1, | valuesOverPoints: 1, | ||||
axisOptions: { | axisOptions: { | ||||
xAxisMode: 'tick' | xAxisMode: 'tick' | ||||
@@ -135,34 +133,20 @@ let typeData = { | |||||
yMarkers: [ | yMarkers: [ | ||||
{ | { | ||||
label: "Marker 1", | |||||
value: 42, | |||||
type: 'dashed' | |||||
}, | |||||
{ | |||||
label: "Marker 2", | |||||
value: 25, | |||||
type: 'dashed' | |||||
label: "Marker", | |||||
value: 43, | |||||
// type: 'dashed' | |||||
} | } | ||||
], | ], | ||||
yRegions: [ | yRegions: [ | ||||
{ | { | ||||
label: "Region Y 1", | |||||
label: "Region", | |||||
start: -10, | start: -10, | ||||
end: 50 | end: 50 | ||||
}, | }, | ||||
], | ], | ||||
// will depend on series code for calculating X values | |||||
// xRegions: [ | |||||
// { | |||||
// label: "Region X 2", | |||||
// start: , | |||||
// end: , | |||||
// } | |||||
// ], | |||||
datasets: [ | datasets: [ | ||||
{ | { | ||||
name: "Some Data", | name: "Some Data", | ||||
@@ -181,66 +165,41 @@ let typeData = { | |||||
values: [15, 20, -3, -15, 58, 12, -17, 37], | values: [15, 20, -3, -15, 58, 12, -17, 37], | ||||
chartType: 'line' | chartType: 'line' | ||||
} | } | ||||
// temp : Stacked | |||||
// { | |||||
// name: "Some Data", | |||||
// values:[25, 30, 50, 45, 18, 12, 27, 14] | |||||
// }, | |||||
// { | |||||
// name: "Another Set", | |||||
// values: [18, 20, 30, 35, 8, 7, 17, 4] | |||||
// }, | |||||
// { | |||||
// name: "Another Set", | |||||
// values: [11, 8, 19, 15, 3, 4, 10, 2] | |||||
// }, | |||||
] | ] | ||||
}; | }; | ||||
let typeChart = new Chart("#chart-types", { | |||||
title: "My Awesome Chart", | |||||
data: typeData, | |||||
type: 'bar', | |||||
height: 250, | |||||
colors: ['purple', 'magenta', 'light-blue'], | |||||
isSeries: 1, | |||||
valuesOverPoints: 1, | |||||
// maxLegendPoints: 6, | |||||
// maxSlices: 3, | |||||
isNavigable: 1, | |||||
barOptions: { | |||||
stacked: 1 | |||||
}, | |||||
tooltipOptions: { | |||||
formatTooltipX: d => (d + '').toUpperCase(), | |||||
formatTooltipY: d => d + ' pts', | |||||
} | |||||
}); | |||||
// let typeChart = new Chart("#chart-types", { | |||||
// title: "My Awesome Chart", | |||||
// data: typeData, | |||||
// type: 'bar', | |||||
// height: 250, | |||||
// colors: ['purple', 'magenta', 'red'], | |||||
// tooltipOptions: { | |||||
// formatTooltipX: d => (d + '').toUpperCase(), | |||||
// formatTooltipY: d => d + ' pts', | |||||
// } | |||||
// }); | |||||
// Aggregation chart | // Aggregation chart | ||||
// ================================================================================ | // ================================================================================ | ||||
let aggrChart = new Chart("#chart-aggr", { | |||||
let args = { | |||||
data: typeData, | data: typeData, | ||||
type: 'pie', | |||||
type: 'axis-mixed', | |||||
height: 250, | height: 250, | ||||
colors: ['purple', 'magenta', 'light-blue'], | colors: ['purple', 'magenta', 'light-blue'], | ||||
isSeries: 1, | |||||
maxLegendPoints: 6, | maxLegendPoints: 6, | ||||
maxSlices: 10, | maxSlices: 10, | ||||
barOptions: { | |||||
stacked: 1 | |||||
}, | |||||
tooltipOptions: { | tooltipOptions: { | ||||
formatTooltipX: d => (d + '').toUpperCase(), | formatTooltipX: d => (d + '').toUpperCase(), | ||||
formatTooltipY: d => d + ' pts', | formatTooltipY: d => d + ' pts', | ||||
} | } | ||||
}); | |||||
} | |||||
let aggrChart = new Chart("#chart-aggr", args); | |||||
Array.prototype.slice.call( | Array.prototype.slice.call( | ||||
document.querySelectorAll('.aggr-type-buttons button') | document.querySelectorAll('.aggr-type-buttons button') | ||||
@@ -248,8 +207,9 @@ Array.prototype.slice.call( | |||||
el.addEventListener('click', (e) => { | el.addEventListener('click', (e) => { | ||||
let btn = e.target; | let btn = e.target; | ||||
let type = btn.getAttribute('data-type'); | let type = btn.getAttribute('data-type'); | ||||
args.type = type; | |||||
let newChart = aggrChart.getDifferentChart(type); | |||||
let newChart = new Chart("#chart-aggr", args);; | |||||
if(newChart){ | if(newChart){ | ||||
aggrChart = newChart; | aggrChart = newChart; | ||||
} | } | ||||
@@ -266,7 +226,9 @@ Array.prototype.slice.call( | |||||
let update_data_all_labels = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Mon", "Tue", | let update_data_all_labels = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Mon", "Tue", | ||||
"Wed", "Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", | "Wed", "Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", | ||||
"Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Mon"]; | "Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Mon"]; | ||||
let update_data_all_values = Array.from({length: 30}, () => Math.floor(Math.random() * 75 - 15)); | |||||
let getRandom = () => Math.floor(Math.random() * 75 - 15); | |||||
let update_data_all_values = Array.from({length: 30}, getRandom); | |||||
// We're gonna be shuffling this | // We're gonna be shuffling this | ||||
let update_data_all_indices = update_data_all_labels.map((d,i) => i); | let update_data_all_indices = update_data_all_labels.map((d,i) => i); | ||||
@@ -281,22 +243,27 @@ let update_data = { | |||||
datasets: [{ | datasets: [{ | ||||
"values": get_update_data(update_data_all_values) | "values": get_update_data(update_data_all_values) | ||||
}], | }], | ||||
"specific_values": [ | |||||
yMarkers: [ | |||||
{ | { | ||||
name: "Altitude", | |||||
// name: "A very long text", | |||||
line_type: "dashed", | |||||
value: 38 | |||||
label: "Altitude", | |||||
value: 25, | |||||
type: 'dashed' | |||||
} | |||||
], | |||||
yRegions: [ | |||||
{ | |||||
label: "Range", | |||||
start: 10, | |||||
end: 45 | |||||
}, | }, | ||||
] | |||||
], | |||||
}; | }; | ||||
let update_chart = new Chart("#chart-update", { | let update_chart = new Chart("#chart-update", { | ||||
data: update_data, | data: update_data, | ||||
type: 'line', | type: 'line', | ||||
height: 250, | height: 250, | ||||
colors: ['red'], | |||||
isSeries: 1, | |||||
colors: ['#ff6c03'], | |||||
lineOptions: { | lineOptions: { | ||||
// hideLine: 1, | // hideLine: 1, | ||||
regionFill: 1 | regionFill: 1 | ||||
@@ -307,9 +274,26 @@ let chart_update_buttons = document.querySelector('.chart-update-buttons'); | |||||
chart_update_buttons.querySelector('[data-update="random"]').addEventListener("click", (e) => { | chart_update_buttons.querySelector('[data-update="random"]').addEventListener("click", (e) => { | ||||
shuffle(update_data_all_indices); | shuffle(update_data_all_indices); | ||||
let value = getRandom(); | |||||
let start = getRandom(); | |||||
let end = getRandom(); | |||||
let data = { | let data = { | ||||
labels: update_data_all_labels.slice(0, 10), | labels: update_data_all_labels.slice(0, 10), | ||||
datasets: [{values: get_update_data(update_data_all_values)}], | datasets: [{values: get_update_data(update_data_all_values)}], | ||||
yMarkers: [ | |||||
{ | |||||
label: "Altitude", | |||||
value: value, | |||||
type: 'dashed' | |||||
} | |||||
], | |||||
yRegions: [ | |||||
{ | |||||
label: "Range", | |||||
start: start, | |||||
end: end | |||||
}, | |||||
], | |||||
} | } | ||||
update_chart.update(data); | update_chart.update(data); | ||||
}); | }); | ||||
@@ -350,8 +334,7 @@ let plotChartArgs = { | |||||
data: trends_data, | data: trends_data, | ||||
type: 'line', | type: 'line', | ||||
height: 250, | height: 250, | ||||
colors: ['blue'], | |||||
isSeries: 1, | |||||
colors: ['#238e38'], | |||||
lineOptions: { | lineOptions: { | ||||
hideDots: 1, | hideDots: 1, | ||||
heatline: 1, | heatline: 1, | ||||
@@ -469,7 +452,8 @@ new Chart("#chart-heatmap", { | |||||
type: 'heatmap', | type: 'heatmap', | ||||
legendScale: [0, 1, 2, 4, 5], | legendScale: [0, 1, 2, 4, 5], | ||||
height: 115, | height: 115, | ||||
discreteDomains: 1 | |||||
discreteDomains: 1, | |||||
legendColors: ['#ebedf0', '#fdf436', '#ffc700', '#ff9100', '#06001c'] | |||||
}); | }); | ||||
Array.prototype.slice.call( | Array.prototype.slice.call( | ||||
@@ -18,6 +18,8 @@ | |||||
<link rel="shortcut icon" href="https://frappe.github.io/frappe/assets/img/favicon.png" type="image/x-icon"> | <link rel="shortcut icon" href="https://frappe.github.io/frappe/assets/img/favicon.png" type="image/x-icon"> | ||||
<link rel="icon" href="https://frappe.github.io/frappe/assets/img/favicon.png" type="image/x-icon"> | <link rel="icon" href="https://frappe.github.io/frappe/assets/img/favicon.png" type="image/x-icon"> | ||||
<script async defer src="https://buttons.github.io/buttons.js"></script> | |||||
</head> | </head> | ||||
<body> | <body> | ||||
@@ -66,24 +68,37 @@ | |||||
label: "Yet Another", type: 'line', | label: "Yet Another", type: 'line', | ||||
values: [15, 20, -3, -15, 58, 12, -17, 37] | values: [15, 20, -3, -15, 58, 12, -17, 37] | ||||
} | } | ||||
] | |||||
], | |||||
yMarkers: [{ label: "Marker", value: 70 }], | |||||
yRegions: [{ label: "Region", start: -10, end: 50 }] | |||||
}, | }, | ||||
title: "My Awesome Chart", | title: "My Awesome Chart", | ||||
type: 'axis-mixed', // or 'bar', 'line', 'pie', 'percentage' | type: 'axis-mixed', // or 'bar', 'line', 'pie', 'percentage' | ||||
height: 250, | height: 250, | ||||
colors: ['#7cd6fd', 'violet', 'blue'] | |||||
colors: ['purple', '#ffa3ef', 'red'] | |||||
});</code></pre> | });</code></pre> | ||||
<div id="chart-types" class="border"></div> | |||||
<!-- <div class="btn-group chart-type-buttons margin-vertical-px mx-auto" role="group"> | |||||
<button type="button" class="btn btn-sm btn-secondary active" data-type='bar'>Bar Chart</button> | |||||
<button type="button" class="btn btn-sm btn-secondary" data-type='line'>Line Chart</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 id="chart-types" class="border" style="margin-bottom: 15px"></div> --> | |||||
<!-- <div > | |||||
<div class="btn-group x-axis-buttons margin-vertical-px" role="group"> | |||||
<button type="button" class="btn btn-sm btn-secondary active" data-type='span'>X span</button> | |||||
<button type="button" class="btn btn-sm btn-secondary" data-type='tick'>X tick</button> | |||||
</div> | |||||
<div class="btn-group y-axis-buttons margin-vertical-px" role="group"> | |||||
<button type="button" class="btn btn-sm btn-secondary active" data-type='span'>Y span</button> | |||||
<button type="button" class="btn btn-sm btn-secondary" data-type='tick'>Y tick</button> | |||||
</div> | |||||
<div class="input-group input-group-sm"> | |||||
<span class="input-group-addon">.00</span> | |||||
<input type="text" class="form-control" aria-label="Amount (rounded to the nearest dollar)"> | |||||
</div> | |||||
</div> --> | </div> --> | ||||
<div id="chart-aggr" class="border"></div> | <div id="chart-aggr" class="border"></div> | ||||
<div class="btn-group aggr-type-buttons margin-vertical-px mx-auto" role="group"> | <div class="btn-group aggr-type-buttons margin-vertical-px mx-auto" role="group"> | ||||
<button type="button" class="btn btn-sm btn-secondary active" data-type='pie'>Pie Chart</button> | |||||
<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> | <button type="button" class="btn btn-sm btn-secondary" data-type='percentage'>Percentage Chart</button> | ||||
</div> | </div> | ||||
<!-- <p class="text-muted"> | <!-- <p class="text-muted"> | ||||
@@ -173,8 +188,8 @@ | |||||
<button type="button" class="btn btn-sm btn-secondary" data-mode="continuous">Continuous</button> | <button type="button" class="btn btn-sm btn-secondary" data-mode="continuous">Continuous</button> | ||||
</div> | </div> | ||||
<div class="heatmap-color-buttons btn-group mt-1 mx-auto" role="group"> | <div class="heatmap-color-buttons btn-group mt-1 mx-auto" role="group"> | ||||
<button type="button" class="btn btn-sm btn-secondary active" data-color="default">Default green</button> | |||||
<button type="button" class="btn btn-sm btn-secondary" data-color="halloween">GitHub's Halloween</button> | |||||
<button type="button" class="btn btn-sm btn-secondary" data-color="default">Default green</button> | |||||
<button type="button" class="btn btn-sm btn-secondary active" data-color="halloween">GitHub's Halloween</button> | |||||
</div> | </div> | ||||
<pre><code class="hljs javascript margin-vertical-px"> let heatmap = new Chart({ | <pre><code class="hljs javascript margin-vertical-px"> let heatmap = new Chart({ | ||||
parent: "#heatmap", | parent: "#heatmap", | ||||
@@ -200,35 +215,69 @@ | |||||
<div class="col-sm-10 push-sm-1"> | <div class="col-sm-10 push-sm-1"> | ||||
<div class="dashboard-section"> | <div class="dashboard-section"> | ||||
<h6 class="margin-vertical-rem">All available options:</h6> | |||||
<pre><code class="hljs javascript"> // Javascript | |||||
let data = { | |||||
labels: ["12am-3am", "3am-6am", "6am-9am", "9am-12pm", | |||||
"12pm-3pm", "3pm-6pm", "6pm-9pm", "9pm-12am"], | |||||
<h6 class="margin-vertical-rem">Available options:</h6> | |||||
<pre><code class="hljs javascript"> | |||||
... | |||||
{ | |||||
data: { | |||||
labels: [], | |||||
datasets: [], | |||||
yRegions: [], | |||||
yMarkers: [] | |||||
} | |||||
title: '', | |||||
colors: [], | |||||
height: 200, | |||||
datasets: [ | |||||
{ | |||||
label: "Some Data", type: 'bar', | |||||
values: [25, 40, 30, 35, 8, 52, 17, -4] | |||||
}, | |||||
{ | |||||
label: "Another Set", type: 'bar', | |||||
values: [25, 50, -10, 15, 18, 32, 27, 14] | |||||
}, | |||||
{ | |||||
label: "Yet Another", type: 'line', | |||||
values: [15, 20, -3, -15, 58, 12, -17, 37] | |||||
} | |||||
] | |||||
}; | |||||
let chart = new Chart( "#chart", { // or DOM element | |||||
title: "My Awesome Chart", | |||||
data: data, | |||||
type: 'axis-mixed', // or 'bar', 'line', 'pie', 'percentage' | |||||
height: 250, | |||||
colors: ['#7cd6fd', 'violet', 'blue'] | |||||
});</code></pre> | |||||
tooltipOptions: { | |||||
formatTooltipX: d => (d + '').toUpperCase(), | |||||
formatTooltipY: d => d + ' pts', | |||||
} | |||||
// Axis charts | |||||
isNavigable: 1, // default: 0 | |||||
valuesOverPoints: 1, // default: 0 | |||||
barOptions: { | |||||
stacked: 1 // default: 0 | |||||
} | |||||
lineOptions: { | |||||
dotSize: 6, // default: 4 | |||||
hideLine: 0, // default: 0 | |||||
hideDots: 1, // default: 0 | |||||
heatline: 1, // default: 0 | |||||
regionFill: 1 // default: 0 | |||||
} | |||||
axisOptions: { | |||||
yAxisMode: 'span', // Axis lines, default | |||||
xAxisMode: 'tick', // No axis lines, only short ticks | |||||
xIsSeries: 1 // Allow skipping x values for space | |||||
// default: 0 | |||||
}, | |||||
// Pie/Percentage charts | |||||
maxLegendPoints: 6, // default: 20 | |||||
maxSlices: 10, // default: 20 | |||||
// Heatmap | |||||
discreteDomains: 1, // default: 1 | |||||
start: startDate, // Date object | |||||
legendColors: [] | |||||
} | |||||
... | |||||
// Updating values | |||||
chart.update(data); | |||||
// Axis charts: | |||||
chart.addDataPoint(label, valueFromEachDataset, index) | |||||
chart.removeDataPoint(index) | |||||
chart.updateDataset(datasetValues, index) | |||||
</code></pre> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
@@ -252,7 +301,9 @@ | |||||
<div class="text-center" style="margin-top: 70px"> | <div class="text-center" style="margin-top: 70px"> | ||||
<a href="https://github.com/frappe/charts/archive/master.zip"><button class="large blue button">Download</button></a> | <a href="https://github.com/frappe/charts/archive/master.zip"><button class="large blue button">Download</button></a> | ||||
<p style="margin-top: 3rem;margin-bottom: 1.5rem;"><a href="https://github.com/frappe/charts" target="_blank">View on GitHub</a></p> | <p style="margin-top: 3rem;margin-bottom: 1.5rem;"><a href="https://github.com/frappe/charts" target="_blank">View on GitHub</a></p> | ||||
<p style="margin-top: 1rem;"><iframe src="https://ghbtns.com/github-btn.html?user=frappe&repo=charts&type=star&count=true" frameborder="0" scrolling="0" width="94px" height="20px"></iframe></p> | |||||
<p style="margin-top: 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> | <p>License: MIT</p> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
@@ -264,7 +315,7 @@ | |||||
</div> | </div> | ||||
<div class="built-with-frappe text-center" style="margin-top: -20px"> | <div class="built-with-frappe text-center" style="margin-top: -20px"> | ||||
<img style="padding: 5px; width: 40px; background: #fff" class="frappe-bird" src="https://frappe.github.io/frappe/assets/img/frappe-bird-grey.svg"> | |||||
<img style="padding: 5px; width: 40px; background: #fff" class="frappe-bird" src="./assets/img/frappe-bird.png"> | |||||
<p style="margin: 24px 0 0px 0; font-size: 15px"> | <p style="margin: 24px 0 0px 0; font-size: 15px"> | ||||
Project maintained by <a href="https://frappe.io" target="_blank">Frappe</a>. | Project maintained by <a href="https://frappe.io" target="_blank">Frappe</a>. | ||||
Used in <a href="https://erpnext.com" target="_blank">ERPNext</a>. | Used in <a href="https://erpnext.com" target="_blank">ERPNext</a>. | ||||
@@ -16,6 +16,7 @@ export default class AxisChart extends BaseChart { | |||||
this.lineOptions = args.lineOptions || {}; | this.lineOptions = args.lineOptions || {}; | ||||
this.type = args.type || 'line'; | this.type = args.type || 'line'; | ||||
this.init = 1; | |||||
this.setup(); | this.setup(); | ||||
} | } | ||||
@@ -146,8 +147,8 @@ export default class AxisChart extends BaseChart { | |||||
} | } | ||||
if(this.data.yRegions) { | if(this.data.yRegions) { | ||||
this.state.yRegions = this.data.yRegions.map(d => { | this.state.yRegions = this.data.yRegions.map(d => { | ||||
d.start = scale(d.start, s.yAxis); | |||||
d.end = scale(d.end, s.yAxis); | |||||
d.startPos = scale(d.start, s.yAxis); | |||||
d.endPos = scale(d.end, s.yAxis); | |||||
return d; | return d; | ||||
}); | }); | ||||
} | } | ||||
@@ -166,7 +167,17 @@ export default class AxisChart extends BaseChart { | |||||
}); | }); | ||||
} | } | ||||
return [].concat(...this.data.datasets.map(d => d[key])); | |||||
let allValueLists = this.data.datasets.map(d => d[key]); | |||||
if(this.data.yMarkers) { | |||||
allValueLists.push(this.data.yMarkers.map(d => d.value)); | |||||
} | |||||
if(this.data.yRegions) { | |||||
this.data.yRegions.map(d => { | |||||
allValueLists.push([d.end, d.start]); | |||||
}) | |||||
} | |||||
return [].concat(...allValueLists); | |||||
} | } | ||||
setupComponents() { | setupComponents() { | ||||
@@ -402,6 +413,10 @@ export default class AxisChart extends BaseChart { | |||||
} | } | ||||
makeOverlay() { | makeOverlay() { | ||||
if(this.init) { | |||||
this.init = 0; | |||||
return; | |||||
} | |||||
if(this.overlayGuides) { | if(this.overlayGuides) { | ||||
this.overlayGuides.forEach(g => { | this.overlayGuides.forEach(g => { | ||||
let o = g.overlay; | let o = g.overlay; | ||||
@@ -498,7 +513,6 @@ export default class AxisChart extends BaseChart { | |||||
} | } | ||||
// API | // API | ||||
addDataPoint(label, datasetValues, index=this.state.datasetLength) { | addDataPoint(label, datasetValues, index=this.state.datasetLength) { | ||||
super.addDataPoint(label, datasetValues, index); | super.addDataPoint(label, datasetValues, index); | ||||
this.data.labels.splice(index, 0, label); | this.data.labels.splice(index, 0, label); | ||||
@@ -509,6 +523,9 @@ export default class AxisChart extends BaseChart { | |||||
} | } | ||||
removeDataPoint(index = this.state.datasetLength-1) { | removeDataPoint(index = this.state.datasetLength-1) { | ||||
if (this.data.labels.length <= 1) { | |||||
return; | |||||
} | |||||
super.removeDataPoint(index); | super.removeDataPoint(index); | ||||
this.data.labels.splice(index, 1); | this.data.labels.splice(index, 1); | ||||
this.data.datasets.map(d => { | this.data.datasets.map(d => { | ||||
@@ -55,7 +55,7 @@ class ChartComponent { | |||||
update(animate = true) { | update(animate = true) { | ||||
this.refresh(); | this.refresh(); | ||||
let animateElements = [] | |||||
let animateElements = []; | |||||
if(animate) { | if(animate) { | ||||
animateElements = this.animateElements(this.data); | animateElements = this.animateElements(this.data); | ||||
} | } | ||||
@@ -157,13 +157,12 @@ let componentConfigs = { | |||||
let newLabels = newData.map(d => d.label); | let newLabels = newData.map(d => d.label); | ||||
let oldPos = this.oldData.map(d => d.position); | let oldPos = this.oldData.map(d => d.position); | ||||
let oldLabels = this.oldData.map(d => d.label); | |||||
this.render(oldPos.map((pos, i) => { | this.render(oldPos.map((pos, i) => { | ||||
return { | return { | ||||
position: oldPos[i], | position: oldPos[i], | ||||
label: newLabels[i] | label: newLabels[i] | ||||
} | |||||
}; | |||||
})); | })); | ||||
return this.store.map((line, i) => { | return this.store.map((line, i) => { | ||||
@@ -178,27 +177,26 @@ let componentConfigs = { | |||||
layerClass: 'y-regions', | layerClass: 'y-regions', | ||||
makeElements(data) { | makeElements(data) { | ||||
return data.map(region => | return data.map(region => | ||||
yRegion(region.start, region.end, this.constants.width, | |||||
yRegion(region.startPos, region.endPos, this.constants.width, | |||||
region.label) | region.label) | ||||
); | ); | ||||
}, | }, | ||||
animateElements(newData) { | animateElements(newData) { | ||||
[this.oldData, newData] = equilizeNoOfElements(this.oldData, newData); | [this.oldData, newData] = equilizeNoOfElements(this.oldData, newData); | ||||
let newPos = newData.map(d => d.end); | |||||
let newPos = newData.map(d => d.endPos); | |||||
let newLabels = newData.map(d => d.label); | let newLabels = newData.map(d => d.label); | ||||
let newStarts = newData.map(d => d.start); | |||||
let newStarts = newData.map(d => d.startPos); | |||||
let oldPos = this.oldData.map(d => d.end); | |||||
let oldLabels = this.oldData.map(d => d.label); | |||||
let oldStarts = this.oldData.map(d => d.start); | |||||
let oldPos = this.oldData.map(d => d.endPos); | |||||
let oldStarts = this.oldData.map(d => d.startPos); | |||||
this.render(oldPos.map((pos, i) => { | this.render(oldPos.map((pos, i) => { | ||||
return { | return { | ||||
start: oldStarts[i], | |||||
end: oldPos[i], | |||||
startPos: oldStarts[i], | |||||
endPos: oldPos[i], | |||||
label: newLabels[i] | label: newLabels[i] | ||||
} | |||||
}; | |||||
})); | })); | ||||
let animateElements = []; | let animateElements = []; | ||||
@@ -232,7 +230,7 @@ let componentConfigs = { | |||||
barsWidth: data.barsWidth, | barsWidth: data.barsWidth, | ||||
minHeight: c.minHeight | minHeight: c.minHeight | ||||
} | } | ||||
) | |||||
); | |||||
}); | }); | ||||
return this.units; | return this.units; | ||||
}, | }, | ||||
@@ -270,7 +268,7 @@ let componentConfigs = { | |||||
this.store.map((bar, i) => { | this.store.map((bar, i) => { | ||||
animateElements = animateElements.concat(animateBar( | animateElements = animateElements.concat(animateBar( | ||||
bar, newXPos[i], newYPos[i], newData.barWidth, newOffsets[i], c.index, | bar, newXPos[i], newYPos[i], newData.barWidth, newOffsets[i], c.index, | ||||
{zeroLine: newData.zeroLine} | |||||
{zeroLine: newData.zeroLine} | |||||
)); | )); | ||||
}); | }); | ||||
@@ -297,10 +295,10 @@ let componentConfigs = { | |||||
svgDefs: c.svgDefs, | svgDefs: c.svgDefs, | ||||
zeroLine: data.zeroLine | zeroLine: data.zeroLine | ||||
} | } | ||||
) | |||||
); | |||||
} | } | ||||
this.units = [] | |||||
this.units = []; | |||||
if(!c.hideDots) { | if(!c.hideDots) { | ||||
this.units = data.yPositions.map((y, j) => { | this.units = data.yPositions.map((y, j) => { | ||||
return datasetDot( | return datasetDot( | ||||
@@ -310,20 +308,17 @@ let componentConfigs = { | |||||
c.color, | c.color, | ||||
(c.valuesOverPoints ? data.values[j] : ''), | (c.valuesOverPoints ? data.values[j] : ''), | ||||
j | j | ||||
) | |||||
); | |||||
}); | }); | ||||
} | } | ||||
return Object.values(this.paths).concat(this.units); | return Object.values(this.paths).concat(this.units); | ||||
}, | }, | ||||
animateElements(newData) { | animateElements(newData) { | ||||
let c = this.constants; | |||||
let newXPos = newData.xPositions; | let newXPos = newData.xPositions; | ||||
let newYPos = newData.yPositions; | let newYPos = newData.yPositions; | ||||
let newValues = newData.values; | let newValues = newData.values; | ||||
let oldXPos = this.oldData.xPositions; | let oldXPos = this.oldData.xPositions; | ||||
let oldYPos = this.oldData.yPositions; | let oldYPos = this.oldData.yPositions; | ||||
let oldValues = this.oldData.values; | let oldValues = this.oldData.values; | ||||
@@ -358,7 +353,7 @@ let componentConfigs = { | |||||
return animateElements; | return animateElements; | ||||
} | } | ||||
} | } | ||||
} | |||||
}; | |||||
export function getComponent(name, constants, getData) { | export function getComponent(name, constants, getData) { | ||||
let keys = Object.keys(componentConfigs).filter(k => name.includes(k)); | let keys = Object.keys(componentConfigs).filter(k => name.includes(k)); | ||||
@@ -366,6 +361,6 @@ export function getComponent(name, constants, getData) { | |||||
Object.assign(config, { | Object.assign(config, { | ||||
constants: constants, | constants: constants, | ||||
getData: getData | getData: getData | ||||
}) | |||||
}); | |||||
return new ChartComponent(config); | return new ChartComponent(config); | ||||
} | } |