[start] state and data separation
This commit is contained in:
parent
4ca6166c8d
commit
f41c501c3a
291
dist/frappe-charts.esm.js
vendored
291
dist/frappe-charts.esm.js
vendored
@ -878,27 +878,29 @@ class BaseChart {
|
||||
this.currentIndex = 0;
|
||||
}
|
||||
|
||||
this.data = this.prepareData(data);
|
||||
this.colors = [];
|
||||
this.config = {};
|
||||
this.state = {};
|
||||
this.options = {};
|
||||
|
||||
this.configure(arguments[0]);
|
||||
}
|
||||
|
||||
configure(args) {
|
||||
// Make a this.config, that has stuff like showTooltip,
|
||||
// showLegend, which then all functions will check
|
||||
|
||||
this.setColors();
|
||||
|
||||
// constants
|
||||
this.config = {
|
||||
showTooltip: 1, // calculate
|
||||
showLegend: 1,
|
||||
isNavigable: 0,
|
||||
// animate: 1
|
||||
animate: 0
|
||||
animate: 1
|
||||
};
|
||||
|
||||
this.state = {
|
||||
colors: this.colors
|
||||
};
|
||||
this.setMargins();
|
||||
|
||||
// Bind window events
|
||||
window.addEventListener('resize', () => this.draw());
|
||||
window.addEventListener('orientationchange', () => this.draw());
|
||||
}
|
||||
|
||||
setColors() {
|
||||
@ -925,10 +927,7 @@ class BaseChart {
|
||||
this.height = height - 40; // change
|
||||
this.translateY = 20;
|
||||
|
||||
this.setHorizontalMargin();
|
||||
}
|
||||
|
||||
setHorizontalMargin() {
|
||||
// Horizontal margins
|
||||
this.translateXLeft = 60;
|
||||
this.translateXRight = 40;
|
||||
}
|
||||
@ -938,18 +937,6 @@ class BaseChart {
|
||||
console.error("No parent element to render on was provided.");
|
||||
return false;
|
||||
}
|
||||
if(!this.parseData()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
parseData() {
|
||||
let data = this.rawChartArgs.data;
|
||||
let valid = this.checkData(data);
|
||||
if(!valid) return false;
|
||||
|
||||
this.data = data;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -960,29 +947,15 @@ class BaseChart {
|
||||
}
|
||||
|
||||
_setup() {
|
||||
this.bindWindowEvents();
|
||||
this.setupConstants();
|
||||
|
||||
this.setMargins();
|
||||
this.makeContainer();
|
||||
this.makeTooltip(); // without binding
|
||||
|
||||
this.calcWidth();
|
||||
this.makeChartArea();
|
||||
this.initComponents();
|
||||
|
||||
this.setupComponents();
|
||||
this.draw(true);
|
||||
}
|
||||
|
||||
bindWindowEvents() {
|
||||
window.addEventListener('resize orientationchange', () => this.draw());
|
||||
}
|
||||
|
||||
setupConstants() {}
|
||||
initComponents() {}
|
||||
|
||||
setupComponents() {
|
||||
// Components config
|
||||
this.components = [];
|
||||
}
|
||||
|
||||
@ -1014,13 +987,22 @@ class BaseChart {
|
||||
bindTooltip() {}
|
||||
|
||||
draw(init=false) {
|
||||
this.calcWidth();
|
||||
this.makeChartArea();
|
||||
|
||||
this.initComponents(); // Only depend on the drawArea made in makeChartArea
|
||||
|
||||
this.setupComponents();
|
||||
|
||||
this.components.forEach(c => c.make()); // or c.build()
|
||||
this.renderLegend();
|
||||
|
||||
this.setupNavigation(init);
|
||||
|
||||
// TODO: remove timeout and decrease post animate time in chart component
|
||||
setTimeout(() => {this.update();}, 1000);
|
||||
if(init) {
|
||||
setTimeout(() => {this.update();}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
calcWidth() {
|
||||
@ -1037,15 +1019,13 @@ class BaseChart {
|
||||
}
|
||||
|
||||
update(data=this.data) {
|
||||
this.prepareData(data);
|
||||
this.data = this.prepareData(data);
|
||||
this.calc(); // builds state
|
||||
this.render();
|
||||
}
|
||||
|
||||
prepareData() {}
|
||||
|
||||
renderConstants() {}
|
||||
|
||||
calc() {} // builds state
|
||||
|
||||
render(animate=true) {
|
||||
@ -1063,6 +1043,9 @@ class BaseChart {
|
||||
}
|
||||
|
||||
makeChartArea() {
|
||||
if(this.svg) {
|
||||
this.chartWrapper.removeChild(this.svg);
|
||||
}
|
||||
this.svg = makeSVGContainer(
|
||||
this.chartWrapper,
|
||||
'chart',
|
||||
@ -1125,37 +1108,25 @@ class BaseChart {
|
||||
onDownArrow() {}
|
||||
onEnterKey() {}
|
||||
|
||||
// updateData() {
|
||||
// update();
|
||||
// }
|
||||
|
||||
getDataPoint() {}
|
||||
setCurrentDataPoint() {}
|
||||
|
||||
|
||||
// ????????????
|
||||
// Update the data here, then do relevant updates
|
||||
// and drawing in child classes by overriding
|
||||
// The Child chart will only know what a particular update means
|
||||
// and what components are affected,
|
||||
// BaseChart shouldn't be doing the animating
|
||||
|
||||
getDataPoint(index = 0) {}
|
||||
setCurrentDataPoint(point) {}
|
||||
|
||||
updateDataset(dataset, index) {}
|
||||
|
||||
updateDatasets(datasets) {
|
||||
//
|
||||
}
|
||||
|
||||
addDataset(dataset, index) {}
|
||||
|
||||
removeDataset(index = 0) {}
|
||||
|
||||
addDataPoint(dataPoint, index = 0) {}
|
||||
|
||||
removeDataPoint(index = 0) {}
|
||||
updateDatasets(datasets) {}
|
||||
|
||||
updateDataPoint(dataPoint, index = 0) {}
|
||||
|
||||
|
||||
addDataPoint(dataPoint, index = 0) {}
|
||||
removeDataPoint(index = 0) {}
|
||||
|
||||
getDifferentChart(type) {
|
||||
return getDifferentChart(type, this.type, this.rawChartArgs);
|
||||
@ -1164,6 +1135,56 @@ class BaseChart {
|
||||
|
||||
const Y_AXIS_MARGIN = 60;
|
||||
|
||||
|
||||
const DEFAULT_AXIS_CHART_TYPE = 'line';
|
||||
|
||||
function dataPrep(data, type) {
|
||||
data.labels = data.labels || [];
|
||||
|
||||
let datasetLength = data.labels.length;
|
||||
|
||||
// Datasets
|
||||
let datasets = data.datasets;
|
||||
let zeroArray = new Array(datasetLength).fill(0);
|
||||
if(!datasets) {
|
||||
// default
|
||||
datasets = [{
|
||||
values: zeroArray
|
||||
}];
|
||||
}
|
||||
|
||||
datasets.map((d, i)=> {
|
||||
// Set values
|
||||
if(!d.values) {
|
||||
d.values = zeroArray;
|
||||
} else {
|
||||
// Check for non values
|
||||
let vals = d.values;
|
||||
vals = vals.map(val => (!isNaN(val) ? val : 0));
|
||||
|
||||
// Trim or extend
|
||||
if(vals.length > datasetLength) {
|
||||
vals = vals.slice(0, datasetLength);
|
||||
} else {
|
||||
vals = fillArray(vals, datasetLength - vals.length, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Set index
|
||||
d.index = i;
|
||||
|
||||
// Set type
|
||||
if(!d.chartType ) {
|
||||
d.chartType = type || DEFAULT_AXIS_CHART_TYPE;
|
||||
}
|
||||
});
|
||||
|
||||
// Markers
|
||||
// Regions
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
class ChartComponent$1 {
|
||||
constructor({
|
||||
layerClass = '',
|
||||
@ -1790,7 +1811,7 @@ class AxisChart extends BaseChart {
|
||||
this.yAxisMode = args.yAxisMode || 'span';
|
||||
|
||||
this.zeroLine = this.height;
|
||||
this.setPrimitiveData();
|
||||
this.setTrivialState();
|
||||
this.setup();
|
||||
}
|
||||
|
||||
@ -1801,8 +1822,20 @@ class AxisChart extends BaseChart {
|
||||
this.config.yAxisMode = args.yAxisMode;
|
||||
}
|
||||
|
||||
setPrimitiveData() {
|
||||
setTrivialState() {
|
||||
// Define data and stuff
|
||||
let xLabels = this.data.labels;
|
||||
this.state = {
|
||||
xAxis: {
|
||||
positions: [],
|
||||
labels: xLabels,
|
||||
},
|
||||
yAxis: {
|
||||
positions: [],
|
||||
labels: [],
|
||||
},
|
||||
datasetLength: xLabels.length
|
||||
};
|
||||
this.setObservers();
|
||||
}
|
||||
|
||||
@ -1811,78 +1844,19 @@ class AxisChart extends BaseChart {
|
||||
// set an observe() on each of those keys for that component
|
||||
}
|
||||
|
||||
setHorizontalMargin() {
|
||||
setMargins() {
|
||||
super.setMargins();
|
||||
this.translateXLeft = Y_AXIS_MARGIN;
|
||||
this.translateXRight = Y_AXIS_MARGIN;
|
||||
}
|
||||
|
||||
checkData(data) {
|
||||
return true;
|
||||
}
|
||||
|
||||
setupConstants() {
|
||||
this.state = {
|
||||
xAxisLabels: [],
|
||||
xAxisPositions: [],
|
||||
xAxisMode: this.config.xAxisMode,
|
||||
yAxisMode: this.config.yAxisMode
|
||||
};
|
||||
|
||||
this.data.datasets.map(d => {
|
||||
if(!d.chartType ) {
|
||||
d.chartType = this.type;
|
||||
}
|
||||
});
|
||||
|
||||
// Prepare Y Axis
|
||||
this.state.yAxis = {
|
||||
labels: [],
|
||||
positions: []
|
||||
};
|
||||
}
|
||||
|
||||
prepareData(data) {
|
||||
let s = this.state;
|
||||
s.xAxisLabels = data.labels || [];
|
||||
s.datasetLength = s.xAxisLabels.length;
|
||||
|
||||
let zeroArray = new Array(s.datasetLength).fill(0);
|
||||
s.datasets = data.datasets; // whole dataset info too
|
||||
if(!data.datasets) {
|
||||
// default
|
||||
s.datasets = [{
|
||||
values: zeroArray // Proof that state version will be seen instead of this.data
|
||||
}];
|
||||
}
|
||||
|
||||
s.datasets.map((d, i)=> {
|
||||
let vals = d.values;
|
||||
if(!vals) {
|
||||
vals = zeroArray;
|
||||
} else {
|
||||
// Check for non values
|
||||
vals = vals.map(val => (!isNaN(val) ? val : 0));
|
||||
|
||||
// Trim or extend
|
||||
if(vals.length > s.datasetLength) {
|
||||
vals = vals.slice(0, s.datasetLength);
|
||||
} else {
|
||||
vals = fillArray(vals, s.datasetLength - vals.length, 0);
|
||||
}
|
||||
}
|
||||
|
||||
d.index = i;
|
||||
});
|
||||
|
||||
s.noOfDatasets = s.datasets.length;
|
||||
s.yMarkers = data.yMarkers;
|
||||
s.yRegions = data.yRegions;
|
||||
prepareData(data=this.data) {
|
||||
return dataPrep(data, this.type);
|
||||
}
|
||||
|
||||
calc() {
|
||||
let s = this.state;
|
||||
|
||||
s.xAxisLabels = this.data.labels;
|
||||
this.calcXPositions();
|
||||
|
||||
s.datasetsLabels = this.data.datasets.map(d => d.name);
|
||||
@ -1901,11 +1875,11 @@ class AxisChart extends BaseChart {
|
||||
calcXPositions() {
|
||||
let s = this.state;
|
||||
this.setUnitWidthAndXOffset();
|
||||
s.xAxisPositions = s.xAxisLabels.map((d, i) =>
|
||||
s.xAxisPositions = s.xAxis.labels.map((d, i) =>
|
||||
floatTwo(s.xOffset + i * s.unitWidth)
|
||||
);
|
||||
|
||||
s.xUnitPositions = new Array(s.noOfDatasets).fill(s.xAxisPositions);
|
||||
s.xUnitPositions = new Array(this.data.datasets.length).fill(s.xAxisPositions);
|
||||
}
|
||||
|
||||
calcYAxisParameters(yAxis, dataValues, withMinimum = 'false') {
|
||||
@ -1921,13 +1895,13 @@ class AxisChart extends BaseChart {
|
||||
|
||||
calcYUnits() {
|
||||
let s = this.state;
|
||||
s.datasets.map(d => {
|
||||
this.data.datasets.map(d => {
|
||||
d.positions = d.values.map(val =>
|
||||
floatTwo(s.yAxis.zeroLine - val * s.yAxis.scaleMultiplier));
|
||||
});
|
||||
|
||||
if(this.barOptions && this.barOptions.stacked) {
|
||||
s.datasets.map((d, i) => {
|
||||
this.data.datasets.map((d, i) => {
|
||||
d.cumulativePositions = d.cumulativeYs.map(val =>
|
||||
floatTwo(s.yAxis.zeroLine - val * s.yAxis.scaleMultiplier));
|
||||
});
|
||||
@ -1937,11 +1911,11 @@ class AxisChart extends BaseChart {
|
||||
calcYMaximums() {
|
||||
let s = this.state;
|
||||
if(this.barOptions && this.barOptions.stacked) {
|
||||
s.yExtremes = s.datasets[s.datasets.length - 1].cumulativePositions;
|
||||
s.yExtremes = this.data.datasets[this.data.datasets.length - 1].cumulativePositions;
|
||||
return;
|
||||
}
|
||||
s.yExtremes = new Array(s.datasetLength).fill(9999);
|
||||
s.datasets.map((d, i) => {
|
||||
this.data.datasets.map((d, i) => {
|
||||
d.positions.map((pos, j) => {
|
||||
if(pos < s.yExtremes[j]) {
|
||||
s.yExtremes[j] = pos;
|
||||
@ -1956,15 +1930,15 @@ class AxisChart extends BaseChart {
|
||||
|
||||
calcYRegions() {
|
||||
let s = this.state;
|
||||
if(s.yMarkers) {
|
||||
s.yMarkers = s.yMarkers.map(d => {
|
||||
if(this.data.yMarkers) {
|
||||
this.data.yMarkers = this.data.yMarkers.map(d => {
|
||||
d.position = floatTwo(s.yAxis.zeroLine - d.value * s.yAxis.scaleMultiplier);
|
||||
d.label += ': ' + d.value;
|
||||
return d;
|
||||
});
|
||||
}
|
||||
if(s.yRegions) {
|
||||
s.yRegions = s.yRegions.map(d => {
|
||||
if(this.data.yRegions) {
|
||||
this.data.yRegions = this.data.yRegions.map(d => {
|
||||
if(d.end < d.start) {
|
||||
[d.start, d.end] = [d.end, start];
|
||||
}
|
||||
@ -1989,13 +1963,13 @@ class AxisChart extends BaseChart {
|
||||
if(this.barOptions && this.barOptions.stacked) {
|
||||
key = 'cumulativeYs';
|
||||
let cumulative = new Array(this.state.datasetLength).fill(0);
|
||||
this.state.datasets.map((d, i) => {
|
||||
let values = this.state.datasets[i].values;
|
||||
this.data.datasets.map((d, i) => {
|
||||
let values = this.data.datasets[i].values;
|
||||
d[key] = cumulative = cumulative.map((c, i) => c + values[i]);
|
||||
});
|
||||
}
|
||||
|
||||
return [].concat(...this.state.datasets.map(d => d[key]));
|
||||
return [].concat(...this.data.datasets.map(d => d[key]));
|
||||
}
|
||||
|
||||
initComponents() {
|
||||
@ -2037,7 +2011,7 @@ class AxisChart extends BaseChart {
|
||||
let s = this.state;
|
||||
return {
|
||||
positions: s.xAxisPositions,
|
||||
labels: s.xAxisLabels,
|
||||
labels: s.xAxis.labels,
|
||||
}
|
||||
}.bind(this)
|
||||
],
|
||||
@ -2058,7 +2032,7 @@ class AxisChart extends BaseChart {
|
||||
}
|
||||
],
|
||||
function() {
|
||||
return this.state.yRegions || [];
|
||||
return this.data.yRegions || [];
|
||||
}.bind(this)
|
||||
],
|
||||
|
||||
@ -2077,7 +2051,7 @@ class AxisChart extends BaseChart {
|
||||
}
|
||||
],
|
||||
function() {
|
||||
return this.state.yMarkers || [];
|
||||
return this.data.yMarkers || [];
|
||||
}.bind(this)
|
||||
]
|
||||
];
|
||||
@ -2110,7 +2084,7 @@ class AxisChart extends BaseChart {
|
||||
layerClass: 'dataset-units dataset-' + index,
|
||||
makeElements: () => {
|
||||
// yPositions, xPostions, color, valuesOverPoints,
|
||||
let d = this.state.datasets[index];
|
||||
let d = this.data.datasets[index];
|
||||
|
||||
return d.positions.map((y, j) => {
|
||||
return unitRenderer.draw(
|
||||
@ -2129,7 +2103,7 @@ class AxisChart extends BaseChart {
|
||||
this.layer.setAttribute('transform', `translate(${unitRenderer.consts.width * index}, 0)`);
|
||||
};
|
||||
|
||||
// let d = this.state.datasets[index];
|
||||
// let d = this.data.datasets[index];
|
||||
|
||||
if(this.meta.type === 'bar' && (!this.meta.barOptions
|
||||
|| !this.meta.barOptions.stacked)) {
|
||||
@ -2140,7 +2114,7 @@ class AxisChart extends BaseChart {
|
||||
animate: (svgUnits) => {
|
||||
// have been updated in axis render;
|
||||
let newX = this.state.xAxisPositions;
|
||||
let newY = this.state.datasets[index].positions;
|
||||
let newY = this.data.datasets[index].positions;
|
||||
|
||||
let lastUnit = svgUnits[svgUnits.length - 1];
|
||||
let parentNode = lastUnit.parentNode;
|
||||
@ -2160,7 +2134,7 @@ class AxisChart extends BaseChart {
|
||||
newX[i],
|
||||
newY[i],
|
||||
index,
|
||||
this.state.noOfDatasets
|
||||
this.data.datasets.length
|
||||
));
|
||||
});
|
||||
}
|
||||
@ -2172,7 +2146,7 @@ class AxisChart extends BaseChart {
|
||||
layerClass: 'path dataset-path',
|
||||
setData: () => {},
|
||||
makeElements: () => {
|
||||
let d = this.state.datasets[index];
|
||||
let d = this.data.datasets[index];
|
||||
let color = this.colors[index];
|
||||
|
||||
return getPaths(
|
||||
@ -2185,7 +2159,7 @@ class AxisChart extends BaseChart {
|
||||
},
|
||||
animate: (paths) => {
|
||||
let newX = this.state.xAxisPositions;
|
||||
let newY = this.state.datasets[index].positions;
|
||||
let newY = this.data.datasets[index].positions;
|
||||
|
||||
let oldX = this.oldState.xAxisPositions;
|
||||
let oldY = this.oldState.datasets[index].positions;
|
||||
@ -2232,7 +2206,7 @@ class AxisChart extends BaseChart {
|
||||
let s = this.state;
|
||||
if(!s.yExtremes) return;
|
||||
|
||||
let titles = s.xAxisLabels;
|
||||
let titles = s.xAxis.labels;
|
||||
if(this.formatTooltipX && this.formatTooltipX(titles[0])) {
|
||||
titles = titles.map(d=>this.formatTooltipX(d));
|
||||
}
|
||||
@ -2246,7 +2220,7 @@ class AxisChart extends BaseChart {
|
||||
let x = xVal + this.translateXLeft;
|
||||
let y = s.yExtremes[i] + this.translateY;
|
||||
|
||||
let values = s.datasets.map((set, j) => {
|
||||
let values = this.data.datasets.map((set, j) => {
|
||||
return {
|
||||
title: set.title,
|
||||
value: formatY ? this.formatTooltipY(set.values[i]) : set.values[i],
|
||||
@ -2271,14 +2245,14 @@ class AxisChart extends BaseChart {
|
||||
let data_key = key.slice(0, key.length-1);
|
||||
data_point[data_key] = y[key][index];
|
||||
});
|
||||
data_point.label = this.xAxisLabels[index];
|
||||
data_point.label = this.xAxis.labels[index];
|
||||
return data_point;
|
||||
}
|
||||
|
||||
setCurrentDataPoint(index) {
|
||||
index = parseInt(index);
|
||||
if(index < 0) index = 0;
|
||||
if(index >= this.xAxisLabels.length) index = this.xAxisLabels.length - 1;
|
||||
if(index >= this.xAxis.labels.length) index = this.xAxis.labels.length - 1;
|
||||
if(index === this.current_index) return;
|
||||
this.current_index = index;
|
||||
$.fire(this.parent, "data-select", this.getDataPoint());
|
||||
@ -2394,7 +2368,8 @@ class MultiAxisChart extends AxisChart {
|
||||
this.type = 'multiaxis';
|
||||
}
|
||||
|
||||
setHorizontalMargin() {
|
||||
setMargins() {
|
||||
super.setMargins();
|
||||
let noOfLeftAxes = this.data.datasets.filter(d => d.axisPosition === 'left').length;
|
||||
this.translateXLeft = (noOfLeftAxes) * Y_AXIS_MARGIN || Y_AXIS_MARGIN;
|
||||
this.translateXRight = (this.data.datasets.length - noOfLeftAxes) * Y_AXIS_MARGIN || Y_AXIS_MARGIN;
|
||||
@ -2452,6 +2427,7 @@ class MultiAxisChart extends AxisChart {
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: function doesn't exist, handle with components
|
||||
renderConstants() {
|
||||
this.state.datasets.map(d => {
|
||||
let guidePos = d.yAxis.position === 'left'
|
||||
@ -2949,7 +2925,8 @@ class Heatmap extends BaseChart {
|
||||
return valid;
|
||||
}
|
||||
|
||||
setupConstants() {
|
||||
configure() {
|
||||
super.configure();
|
||||
this.today = new Date();
|
||||
|
||||
if(!this.start) {
|
||||
|
||||
2
dist/frappe-charts.min.cjs.js
vendored
2
dist/frappe-charts.min.cjs.js
vendored
File diff suppressed because one or more lines are too long
2
dist/frappe-charts.min.esm.js
vendored
2
dist/frappe-charts.min.esm.js
vendored
File diff suppressed because one or more lines are too long
2
dist/frappe-charts.min.iife.js
vendored
2
dist/frappe-charts.min.iife.js
vendored
File diff suppressed because one or more lines are too long
2
dist/frappe-charts.min.iife.js.map
vendored
2
dist/frappe-charts.min.iife.js.map
vendored
File diff suppressed because one or more lines are too long
2
docs/assets/js/frappe-charts.min.js
vendored
2
docs/assets/js/frappe-charts.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -476,100 +476,100 @@ document.querySelector('[data-aggregation="average"]').addEventListener("click",
|
||||
// Heatmap
|
||||
// ================================================================================
|
||||
|
||||
let heatmap_data = {};
|
||||
let current_date = new Date();
|
||||
let timestamp = current_date.getTime()/1000;
|
||||
timestamp = Math.floor(timestamp - (timestamp % 86400)).toFixed(1); // convert to midnight
|
||||
for (var i = 0; i< 375; i++) {
|
||||
heatmap_data[parseInt(timestamp)] = Math.floor(Math.random() * 5);
|
||||
timestamp = Math.floor(timestamp - 86400).toFixed(1);
|
||||
}
|
||||
// let heatmap_data = {};
|
||||
// let current_date = new Date();
|
||||
// let timestamp = current_date.getTime()/1000;
|
||||
// timestamp = Math.floor(timestamp - (timestamp % 86400)).toFixed(1); // convert to midnight
|
||||
// for (var i = 0; i< 375; i++) {
|
||||
// heatmap_data[parseInt(timestamp)] = Math.floor(Math.random() * 5);
|
||||
// timestamp = Math.floor(timestamp - 86400).toFixed(1);
|
||||
// }
|
||||
|
||||
new Chart({
|
||||
parent: "#chart-heatmap",
|
||||
data: heatmap_data,
|
||||
type: 'heatmap',
|
||||
legend_scale: [0, 1, 2, 4, 5],
|
||||
height: 115,
|
||||
discrete_domains: 1 // default 0
|
||||
});
|
||||
// new Chart({
|
||||
// parent: "#chart-heatmap",
|
||||
// data: heatmap_data,
|
||||
// type: 'heatmap',
|
||||
// legend_scale: [0, 1, 2, 4, 5],
|
||||
// height: 115,
|
||||
// discrete_domains: 1 // default 0
|
||||
// });
|
||||
|
||||
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 discrete_domains = 0;
|
||||
// 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 discrete_domains = 0;
|
||||
|
||||
if(mode === 'discrete') {
|
||||
discrete_domains = 1;
|
||||
}
|
||||
// if(mode === 'discrete') {
|
||||
// discrete_domains = 1;
|
||||
// }
|
||||
|
||||
let colors = [];
|
||||
let colors_mode = document
|
||||
.querySelector('.heatmap-color-buttons .active')
|
||||
.getAttribute('data-color');
|
||||
if(colors_mode === 'halloween') {
|
||||
colors = ['#ebedf0', '#fdf436', '#ffc700', '#ff9100', '#06001c'];
|
||||
}
|
||||
// let colors = [];
|
||||
// let colors_mode = document
|
||||
// .querySelector('.heatmap-color-buttons .active')
|
||||
// .getAttribute('data-color');
|
||||
// if(colors_mode === 'halloween') {
|
||||
// colors = ['#ebedf0', '#fdf436', '#ffc700', '#ff9100', '#06001c'];
|
||||
// }
|
||||
|
||||
new Chart({
|
||||
parent: "#chart-heatmap",
|
||||
data: heatmap_data,
|
||||
type: 'heatmap',
|
||||
legend_scale: [0, 1, 2, 4, 5],
|
||||
height: 115,
|
||||
discrete_domains: discrete_domains,
|
||||
legend_colors: colors
|
||||
});
|
||||
// new Chart({
|
||||
// parent: "#chart-heatmap",
|
||||
// data: heatmap_data,
|
||||
// type: 'heatmap',
|
||||
// legend_scale: [0, 1, 2, 4, 5],
|
||||
// height: 115,
|
||||
// discrete_domains: discrete_domains,
|
||||
// legend_colors: colors
|
||||
// });
|
||||
|
||||
Array.prototype.slice.call(
|
||||
btn.parentNode.querySelectorAll('button')).map(el => {
|
||||
el.classList.remove('active');
|
||||
});
|
||||
btn.classList.add('active');
|
||||
});
|
||||
});
|
||||
// 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 = [];
|
||||
// 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 = ['#ebedf0', '#fdf436', '#ffc700', '#ff9100', '#06001c'];
|
||||
}
|
||||
// if(colors_mode === 'halloween') {
|
||||
// colors = ['#ebedf0', '#fdf436', '#ffc700', '#ff9100', '#06001c'];
|
||||
// }
|
||||
|
||||
let discrete_domains = 1;
|
||||
// let discrete_domains = 1;
|
||||
|
||||
let view_mode = document
|
||||
.querySelector('.heatmap-mode-buttons .active')
|
||||
.getAttribute('data-mode');
|
||||
if(view_mode === 'continuous') {
|
||||
discrete_domains = 0;
|
||||
}
|
||||
// let view_mode = document
|
||||
// .querySelector('.heatmap-mode-buttons .active')
|
||||
// .getAttribute('data-mode');
|
||||
// if(view_mode === 'continuous') {
|
||||
// discrete_domains = 0;
|
||||
// }
|
||||
|
||||
new Chart({
|
||||
parent: "#chart-heatmap",
|
||||
data: heatmap_data,
|
||||
type: 'heatmap',
|
||||
legend_scale: [0, 1, 2, 4, 5],
|
||||
height: 115,
|
||||
discrete_domains: discrete_domains,
|
||||
legend_colors: colors
|
||||
});
|
||||
// new Chart({
|
||||
// parent: "#chart-heatmap",
|
||||
// data: heatmap_data,
|
||||
// type: 'heatmap',
|
||||
// legend_scale: [0, 1, 2, 4, 5],
|
||||
// height: 115,
|
||||
// discrete_domains: discrete_domains,
|
||||
// legend_colors: colors
|
||||
// });
|
||||
|
||||
Array.prototype.slice.call(
|
||||
btn.parentNode.querySelectorAll('button')).map(el => {
|
||||
el.classList.remove('active');
|
||||
});
|
||||
btn.classList.add('active');
|
||||
});
|
||||
});
|
||||
// Array.prototype.slice.call(
|
||||
// btn.parentNode.querySelectorAll('button')).map(el => {
|
||||
// el.classList.remove('active');
|
||||
// });
|
||||
// btn.classList.add('active');
|
||||
// });
|
||||
// });
|
||||
|
||||
// Helpers
|
||||
// ================================================================================
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import BaseChart from './BaseChart';
|
||||
import { Y_AXIS_MARGIN } from '../utils/margins';
|
||||
import { dataPrep } from './axis-chart-utils';
|
||||
import { Y_AXIS_MARGIN } from '../utils/constants';
|
||||
import { getComponent } from '../objects/ChartComponents';
|
||||
import { BarChartController, LineChartController, getPaths } from '../objects/AxisChartControllers';
|
||||
import { AxisChartRenderer } from '../utils/draw';
|
||||
@ -9,7 +10,7 @@ import { Animator, translateHoriLine } from '../utils/animate';
|
||||
import { runSMILAnimation } from '../utils/animation';
|
||||
import { getRealIntervals, calcChartIntervals, getIntervalSize, getValueRange, getZeroIndex } from '../utils/intervals';
|
||||
import { floatTwo, fillArray } from '../utils/helpers';
|
||||
import { MIN_BAR_PERCENT_HEIGHT } from '../utils/constants';
|
||||
import { MIN_BAR_PERCENT_HEIGHT, DEFAULT_AXIS_CHART_TYPE } from '../utils/constants';
|
||||
|
||||
export default class AxisChart extends BaseChart {
|
||||
constructor(args) {
|
||||
@ -26,7 +27,7 @@ export default class AxisChart extends BaseChart {
|
||||
this.yAxisMode = args.yAxisMode || 'span';
|
||||
|
||||
this.zeroLine = this.height;
|
||||
this.setPrimitiveData();
|
||||
this.setTrivialState();
|
||||
this.setup();
|
||||
}
|
||||
|
||||
@ -37,8 +38,20 @@ export default class AxisChart extends BaseChart {
|
||||
this.config.yAxisMode = args.yAxisMode;
|
||||
}
|
||||
|
||||
setPrimitiveData() {
|
||||
setTrivialState() {
|
||||
// Define data and stuff
|
||||
let xLabels = this.data.labels;
|
||||
this.state = {
|
||||
xAxis: {
|
||||
positions: [],
|
||||
labels: xLabels,
|
||||
},
|
||||
yAxis: {
|
||||
positions: [],
|
||||
labels: [],
|
||||
},
|
||||
datasetLength: xLabels.length
|
||||
}
|
||||
this.setObservers();
|
||||
}
|
||||
|
||||
@ -47,78 +60,19 @@ export default class AxisChart extends BaseChart {
|
||||
// set an observe() on each of those keys for that component
|
||||
}
|
||||
|
||||
setHorizontalMargin() {
|
||||
setMargins() {
|
||||
super.setMargins();
|
||||
this.translateXLeft = Y_AXIS_MARGIN;
|
||||
this.translateXRight = Y_AXIS_MARGIN;
|
||||
}
|
||||
|
||||
checkData(data) {
|
||||
return true;
|
||||
}
|
||||
|
||||
setupConstants() {
|
||||
this.state = {
|
||||
xAxisLabels: [],
|
||||
xAxisPositions: [],
|
||||
xAxisMode: this.config.xAxisMode,
|
||||
yAxisMode: this.config.yAxisMode
|
||||
}
|
||||
|
||||
this.data.datasets.map(d => {
|
||||
if(!d.chartType ) {
|
||||
d.chartType = this.type;
|
||||
}
|
||||
});
|
||||
|
||||
// Prepare Y Axis
|
||||
this.state.yAxis = {
|
||||
labels: [],
|
||||
positions: []
|
||||
};
|
||||
}
|
||||
|
||||
prepareData(data) {
|
||||
let s = this.state;
|
||||
s.xAxisLabels = data.labels || [];
|
||||
s.datasetLength = s.xAxisLabels.length;
|
||||
|
||||
let zeroArray = new Array(s.datasetLength).fill(0);
|
||||
s.datasets = data.datasets; // whole dataset info too
|
||||
if(!data.datasets) {
|
||||
// default
|
||||
s.datasets = [{
|
||||
values: zeroArray // Proof that state version will be seen instead of this.data
|
||||
}];
|
||||
}
|
||||
|
||||
s.datasets.map((d, i)=> {
|
||||
let vals = d.values;
|
||||
if(!vals) {
|
||||
vals = zeroArray;
|
||||
} else {
|
||||
// Check for non values
|
||||
vals = vals.map(val => (!isNaN(val) ? val : 0));
|
||||
|
||||
// Trim or extend
|
||||
if(vals.length > s.datasetLength) {
|
||||
vals = vals.slice(0, s.datasetLength);
|
||||
} else {
|
||||
vals = fillArray(vals, s.datasetLength - vals.length, 0);
|
||||
}
|
||||
}
|
||||
|
||||
d.index = i;
|
||||
});
|
||||
|
||||
s.noOfDatasets = s.datasets.length;
|
||||
s.yMarkers = data.yMarkers;
|
||||
s.yRegions = data.yRegions;
|
||||
prepareData(data=this.data) {
|
||||
return dataPrep(data, this.type);
|
||||
}
|
||||
|
||||
calc() {
|
||||
let s = this.state;
|
||||
|
||||
s.xAxisLabels = this.data.labels;
|
||||
this.calcXPositions();
|
||||
|
||||
s.datasetsLabels = this.data.datasets.map(d => d.name);
|
||||
@ -137,11 +91,11 @@ export default class AxisChart extends BaseChart {
|
||||
calcXPositions() {
|
||||
let s = this.state;
|
||||
this.setUnitWidthAndXOffset();
|
||||
s.xAxisPositions = s.xAxisLabels.map((d, i) =>
|
||||
s.xAxisPositions = s.xAxis.labels.map((d, i) =>
|
||||
floatTwo(s.xOffset + i * s.unitWidth)
|
||||
);
|
||||
|
||||
s.xUnitPositions = new Array(s.noOfDatasets).fill(s.xAxisPositions);
|
||||
s.xUnitPositions = new Array(this.data.datasets.length).fill(s.xAxisPositions);
|
||||
}
|
||||
|
||||
calcYAxisParameters(yAxis, dataValues, withMinimum = 'false') {
|
||||
@ -157,13 +111,13 @@ export default class AxisChart extends BaseChart {
|
||||
|
||||
calcYUnits() {
|
||||
let s = this.state;
|
||||
s.datasets.map(d => {
|
||||
this.data.datasets.map(d => {
|
||||
d.positions = d.values.map(val =>
|
||||
floatTwo(s.yAxis.zeroLine - val * s.yAxis.scaleMultiplier));
|
||||
});
|
||||
|
||||
if(this.barOptions && this.barOptions.stacked) {
|
||||
s.datasets.map((d, i) => {
|
||||
this.data.datasets.map((d, i) => {
|
||||
d.cumulativePositions = d.cumulativeYs.map(val =>
|
||||
floatTwo(s.yAxis.zeroLine - val * s.yAxis.scaleMultiplier));
|
||||
});
|
||||
@ -173,11 +127,11 @@ export default class AxisChart extends BaseChart {
|
||||
calcYMaximums() {
|
||||
let s = this.state;
|
||||
if(this.barOptions && this.barOptions.stacked) {
|
||||
s.yExtremes = s.datasets[s.datasets.length - 1].cumulativePositions;
|
||||
s.yExtremes = this.data.datasets[this.data.datasets.length - 1].cumulativePositions;
|
||||
return;
|
||||
}
|
||||
s.yExtremes = new Array(s.datasetLength).fill(9999);
|
||||
s.datasets.map((d, i) => {
|
||||
this.data.datasets.map((d, i) => {
|
||||
d.positions.map((pos, j) => {
|
||||
if(pos < s.yExtremes[j]) {
|
||||
s.yExtremes[j] = pos;
|
||||
@ -192,15 +146,15 @@ export default class AxisChart extends BaseChart {
|
||||
|
||||
calcYRegions() {
|
||||
let s = this.state;
|
||||
if(s.yMarkers) {
|
||||
s.yMarkers = s.yMarkers.map(d => {
|
||||
if(this.data.yMarkers) {
|
||||
this.data.yMarkers = this.data.yMarkers.map(d => {
|
||||
d.position = floatTwo(s.yAxis.zeroLine - d.value * s.yAxis.scaleMultiplier);
|
||||
d.label += ': ' + d.value;
|
||||
return d;
|
||||
});
|
||||
}
|
||||
if(s.yRegions) {
|
||||
s.yRegions = s.yRegions.map(d => {
|
||||
if(this.data.yRegions) {
|
||||
this.data.yRegions = this.data.yRegions.map(d => {
|
||||
if(d.end < d.start) {
|
||||
[d.start, d.end] = [d.end, start];
|
||||
}
|
||||
@ -225,13 +179,13 @@ export default class AxisChart extends BaseChart {
|
||||
if(this.barOptions && this.barOptions.stacked) {
|
||||
key = 'cumulativeYs';
|
||||
let cumulative = new Array(this.state.datasetLength).fill(0);
|
||||
this.state.datasets.map((d, i) => {
|
||||
let values = this.state.datasets[i].values;
|
||||
this.data.datasets.map((d, i) => {
|
||||
let values = this.data.datasets[i].values;
|
||||
d[key] = cumulative = cumulative.map((c, i) => c + values[i]);
|
||||
});
|
||||
}
|
||||
|
||||
return [].concat(...this.state.datasets.map(d => d[key]));
|
||||
return [].concat(...this.data.datasets.map(d => d[key]));
|
||||
}
|
||||
|
||||
initComponents() {
|
||||
@ -273,7 +227,7 @@ export default class AxisChart extends BaseChart {
|
||||
let s = this.state;
|
||||
return {
|
||||
positions: s.xAxisPositions,
|
||||
labels: s.xAxisLabels,
|
||||
labels: s.xAxis.labels,
|
||||
}
|
||||
}.bind(this)
|
||||
],
|
||||
@ -294,7 +248,7 @@ export default class AxisChart extends BaseChart {
|
||||
}
|
||||
],
|
||||
function() {
|
||||
return this.state.yRegions || [];
|
||||
return this.data.yRegions || [];
|
||||
}.bind(this)
|
||||
],
|
||||
|
||||
@ -313,7 +267,7 @@ export default class AxisChart extends BaseChart {
|
||||
}
|
||||
],
|
||||
function() {
|
||||
return this.state.yMarkers || [];
|
||||
return this.data.yMarkers || [];
|
||||
}.bind(this)
|
||||
]
|
||||
];
|
||||
@ -346,7 +300,7 @@ export default class AxisChart extends BaseChart {
|
||||
layerClass: 'dataset-units dataset-' + index,
|
||||
makeElements: () => {
|
||||
// yPositions, xPostions, color, valuesOverPoints,
|
||||
let d = this.state.datasets[index];
|
||||
let d = this.data.datasets[index];
|
||||
|
||||
return d.positions.map((y, j) => {
|
||||
return unitRenderer.draw(
|
||||
@ -365,7 +319,7 @@ export default class AxisChart extends BaseChart {
|
||||
this.layer.setAttribute('transform', `translate(${unitRenderer.consts.width * index}, 0)`);
|
||||
}
|
||||
|
||||
// let d = this.state.datasets[index];
|
||||
// let d = this.data.datasets[index];
|
||||
|
||||
if(this.meta.type === 'bar' && (!this.meta.barOptions
|
||||
|| !this.meta.barOptions.stacked)) {
|
||||
@ -376,7 +330,7 @@ export default class AxisChart extends BaseChart {
|
||||
animate: (svgUnits) => {
|
||||
// have been updated in axis render;
|
||||
let newX = this.state.xAxisPositions;
|
||||
let newY = this.state.datasets[index].positions;
|
||||
let newY = this.data.datasets[index].positions;
|
||||
|
||||
let lastUnit = svgUnits[svgUnits.length - 1];
|
||||
let parentNode = lastUnit.parentNode;
|
||||
@ -396,7 +350,7 @@ export default class AxisChart extends BaseChart {
|
||||
newX[i],
|
||||
newY[i],
|
||||
index,
|
||||
this.state.noOfDatasets
|
||||
this.data.datasets.length
|
||||
));
|
||||
});
|
||||
}
|
||||
@ -408,7 +362,7 @@ export default class AxisChart extends BaseChart {
|
||||
layerClass: 'path dataset-path',
|
||||
setData: () => {},
|
||||
makeElements: () => {
|
||||
let d = this.state.datasets[index];
|
||||
let d = this.data.datasets[index];
|
||||
let color = this.colors[index];
|
||||
|
||||
return getPaths(
|
||||
@ -421,7 +375,7 @@ export default class AxisChart extends BaseChart {
|
||||
},
|
||||
animate: (paths) => {
|
||||
let newX = this.state.xAxisPositions;
|
||||
let newY = this.state.datasets[index].positions;
|
||||
let newY = this.data.datasets[index].positions;
|
||||
|
||||
let oldX = this.oldState.xAxisPositions;
|
||||
let oldY = this.oldState.datasets[index].positions;
|
||||
@ -468,7 +422,7 @@ export default class AxisChart extends BaseChart {
|
||||
let s = this.state;
|
||||
if(!s.yExtremes) return;
|
||||
|
||||
let titles = s.xAxisLabels;
|
||||
let titles = s.xAxis.labels;
|
||||
if(this.formatTooltipX && this.formatTooltipX(titles[0])) {
|
||||
titles = titles.map(d=>this.formatTooltipX(d));
|
||||
}
|
||||
@ -482,7 +436,7 @@ export default class AxisChart extends BaseChart {
|
||||
let x = xVal + this.translateXLeft;
|
||||
let y = s.yExtremes[i] + this.translateY;
|
||||
|
||||
let values = s.datasets.map((set, j) => {
|
||||
let values = this.data.datasets.map((set, j) => {
|
||||
return {
|
||||
title: set.title,
|
||||
value: formatY ? this.formatTooltipY(set.values[i]) : set.values[i],
|
||||
@ -507,14 +461,14 @@ export default class AxisChart extends BaseChart {
|
||||
let data_key = key.slice(0, key.length-1);
|
||||
data_point[data_key] = y[key][index];
|
||||
});
|
||||
data_point.label = this.xAxisLabels[index];
|
||||
data_point.label = this.xAxis.labels[index];
|
||||
return data_point;
|
||||
}
|
||||
|
||||
setCurrentDataPoint(index) {
|
||||
index = parseInt(index);
|
||||
if(index < 0) index = 0;
|
||||
if(index >= this.xAxisLabels.length) index = this.xAxisLabels.length - 1;
|
||||
if(index >= this.xAxis.labels.length) index = this.xAxis.labels.length - 1;
|
||||
if(index === this.current_index) return;
|
||||
this.current_index = index;
|
||||
$.fire(this.parent, "data-select", this.getDataPoint());
|
||||
|
||||
@ -34,27 +34,29 @@ export default class BaseChart {
|
||||
this.currentIndex = 0;
|
||||
}
|
||||
|
||||
this.data = this.prepareData(data);;
|
||||
this.colors = [];
|
||||
this.config = {};
|
||||
this.state = {};
|
||||
this.options = {};
|
||||
|
||||
this.configure(arguments[0]);
|
||||
}
|
||||
|
||||
configure(args) {
|
||||
// Make a this.config, that has stuff like showTooltip,
|
||||
// showLegend, which then all functions will check
|
||||
|
||||
this.setColors();
|
||||
|
||||
// constants
|
||||
this.config = {
|
||||
showTooltip: 1, // calculate
|
||||
showLegend: 1,
|
||||
isNavigable: 0,
|
||||
// animate: 1
|
||||
animate: 0
|
||||
animate: 1
|
||||
};
|
||||
|
||||
this.state = {
|
||||
colors: this.colors
|
||||
};
|
||||
this.setMargins();
|
||||
|
||||
// Bind window events
|
||||
window.addEventListener('resize', () => this.draw());
|
||||
window.addEventListener('orientationchange', () => this.draw());
|
||||
}
|
||||
|
||||
setColors() {
|
||||
@ -81,10 +83,7 @@ export default class BaseChart {
|
||||
this.height = height - 40; // change
|
||||
this.translateY = 20;
|
||||
|
||||
this.setHorizontalMargin();
|
||||
}
|
||||
|
||||
setHorizontalMargin() {
|
||||
// Horizontal margins
|
||||
this.translateXLeft = 60;
|
||||
this.translateXRight = 40;
|
||||
}
|
||||
@ -96,18 +95,6 @@ export default class BaseChart {
|
||||
console.error("No parent element to render on was provided.");
|
||||
return false;
|
||||
}
|
||||
if(!this.parseData()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
parseData() {
|
||||
let data = this.rawChartArgs.data;
|
||||
let valid = this.checkData(data);
|
||||
if(!valid) return false;
|
||||
|
||||
this.data = data;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -118,29 +105,15 @@ export default class BaseChart {
|
||||
}
|
||||
|
||||
_setup() {
|
||||
this.bindWindowEvents();
|
||||
this.setupConstants();
|
||||
|
||||
this.setMargins();
|
||||
this.makeContainer();
|
||||
this.makeTooltip(); // without binding
|
||||
|
||||
this.calcWidth();
|
||||
this.makeChartArea();
|
||||
this.initComponents();
|
||||
|
||||
this.setupComponents();
|
||||
this.draw(true);
|
||||
}
|
||||
|
||||
bindWindowEvents() {
|
||||
window.addEventListener('resize orientationchange', () => this.draw());
|
||||
}
|
||||
|
||||
setupConstants() {}
|
||||
initComponents() {}
|
||||
|
||||
setupComponents() {
|
||||
// Components config
|
||||
this.components = [];
|
||||
}
|
||||
|
||||
@ -172,13 +145,22 @@ export default class BaseChart {
|
||||
bindTooltip() {}
|
||||
|
||||
draw(init=false) {
|
||||
this.calcWidth();
|
||||
this.makeChartArea();
|
||||
|
||||
this.initComponents(); // Only depend on the drawArea made in makeChartArea
|
||||
|
||||
this.setupComponents();
|
||||
|
||||
this.components.forEach(c => c.make()); // or c.build()
|
||||
this.renderLegend();
|
||||
|
||||
this.setupNavigation(init);
|
||||
|
||||
// TODO: remove timeout and decrease post animate time in chart component
|
||||
setTimeout(() => {this.update();}, 1000);
|
||||
if(init) {
|
||||
setTimeout(() => {this.update();}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
calcWidth() {
|
||||
@ -195,15 +177,13 @@ export default class BaseChart {
|
||||
}
|
||||
|
||||
update(data=this.data) {
|
||||
this.prepareData(data);
|
||||
this.data = this.prepareData(data);
|
||||
this.calc(); // builds state
|
||||
this.render();
|
||||
}
|
||||
|
||||
prepareData() {}
|
||||
|
||||
renderConstants() {}
|
||||
|
||||
calc() {} // builds state
|
||||
|
||||
render(animate=true) {
|
||||
@ -221,6 +201,9 @@ export default class BaseChart {
|
||||
}
|
||||
|
||||
makeChartArea() {
|
||||
if(this.svg) {
|
||||
this.chartWrapper.removeChild(this.svg);
|
||||
}
|
||||
this.svg = makeSVGContainer(
|
||||
this.chartWrapper,
|
||||
'chart',
|
||||
@ -283,37 +266,25 @@ export default class BaseChart {
|
||||
onDownArrow() {}
|
||||
onEnterKey() {}
|
||||
|
||||
// updateData() {
|
||||
// update();
|
||||
// }
|
||||
|
||||
getDataPoint() {}
|
||||
setCurrentDataPoint() {}
|
||||
|
||||
|
||||
// ????????????
|
||||
// Update the data here, then do relevant updates
|
||||
// and drawing in child classes by overriding
|
||||
// The Child chart will only know what a particular update means
|
||||
// and what components are affected,
|
||||
// BaseChart shouldn't be doing the animating
|
||||
|
||||
getDataPoint(index = 0) {}
|
||||
setCurrentDataPoint(point) {}
|
||||
|
||||
updateDataset(dataset, index) {}
|
||||
|
||||
updateDatasets(datasets) {
|
||||
//
|
||||
}
|
||||
|
||||
addDataset(dataset, index) {}
|
||||
|
||||
removeDataset(index = 0) {}
|
||||
|
||||
addDataPoint(dataPoint, index = 0) {}
|
||||
|
||||
removeDataPoint(index = 0) {}
|
||||
updateDatasets(datasets) {}
|
||||
|
||||
updateDataPoint(dataPoint, index = 0) {}
|
||||
|
||||
|
||||
addDataPoint(dataPoint, index = 0) {}
|
||||
removeDataPoint(index = 0) {}
|
||||
|
||||
getDifferentChart(type) {
|
||||
return getDifferentChart(type, this.type, this.rawChartArgs);
|
||||
|
||||
@ -54,7 +54,8 @@ export default class Heatmap extends BaseChart {
|
||||
return valid;
|
||||
}
|
||||
|
||||
setupConstants() {
|
||||
configure() {
|
||||
super.configure();
|
||||
this.today = new Date();
|
||||
|
||||
if(!this.start) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import AxisChart from './AxisChart';
|
||||
import { Y_AXIS_MARGIN } from '../utils/margins';
|
||||
import { Y_AXIS_MARGIN } from '../utils/constants';
|
||||
// import { ChartComponent } from '../objects/ChartComponents';
|
||||
import { floatTwo } from '../utils/helpers';
|
||||
|
||||
@ -14,7 +14,8 @@ export default class MultiAxisChart extends AxisChart {
|
||||
this.type = 'multiaxis';
|
||||
}
|
||||
|
||||
setHorizontalMargin() {
|
||||
setMargins() {
|
||||
super.setMargins();
|
||||
let noOfLeftAxes = this.data.datasets.filter(d => d.axisPosition === 'left').length;
|
||||
this.translateXLeft = (noOfLeftAxes) * Y_AXIS_MARGIN || Y_AXIS_MARGIN;
|
||||
this.translateXRight = (this.data.datasets.length - noOfLeftAxes) * Y_AXIS_MARGIN || Y_AXIS_MARGIN;
|
||||
@ -72,6 +73,7 @@ export default class MultiAxisChart extends AxisChart {
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: function doesn't exist, handle with components
|
||||
renderConstants() {
|
||||
this.state.datasets.map(d => {
|
||||
let guidePos = d.yAxis.position === 'left'
|
||||
|
||||
49
src/js/charts/axis-chart-utils.js
Normal file
49
src/js/charts/axis-chart-utils.js
Normal file
@ -0,0 +1,49 @@
|
||||
import { floatTwo, fillArray } from '../utils/helpers';
|
||||
import { DEFAULT_AXIS_CHART_TYPE } from '../utils/constants';
|
||||
|
||||
export function dataPrep(data, type) {
|
||||
data.labels = data.labels || [];
|
||||
|
||||
let datasetLength = data.labels.length;
|
||||
|
||||
// Datasets
|
||||
let datasets = data.datasets;
|
||||
let zeroArray = new Array(datasetLength).fill(0);
|
||||
if(!datasets) {
|
||||
// default
|
||||
datasets = [{
|
||||
values: zeroArray
|
||||
}];
|
||||
}
|
||||
|
||||
datasets.map((d, i)=> {
|
||||
// Set values
|
||||
if(!d.values) {
|
||||
d.values = zeroArray;
|
||||
} else {
|
||||
// Check for non values
|
||||
let vals = d.values;
|
||||
vals = vals.map(val => (!isNaN(val) ? val : 0));
|
||||
|
||||
// Trim or extend
|
||||
if(vals.length > datasetLength) {
|
||||
vals = vals.slice(0, datasetLength);
|
||||
} else {
|
||||
vals = fillArray(vals, datasetLength - vals.length, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Set index
|
||||
d.index = i;
|
||||
|
||||
// Set type
|
||||
if(!d.chartType ) {
|
||||
d.chartType = type || DEFAULT_AXIS_CHART_TYPE;
|
||||
}
|
||||
});
|
||||
|
||||
// Markers
|
||||
// Regions
|
||||
|
||||
return data;
|
||||
}
|
||||
@ -2,8 +2,6 @@ import { getBarHeightAndYAttr } from '../utils/draw-utils';
|
||||
import { createSVG, makePath, makeGradient, wrapInSVGGroup, FONT_SIZE } from '../utils/draw';
|
||||
import { STD_EASING, UNIT_ANIM_DUR, MARKER_LINE_ANIM_DUR, PATH_ANIM_DUR } from '../utils/animate';
|
||||
|
||||
const MIN_BAR_PERCENT_HEIGHT = 0.01;
|
||||
|
||||
class AxisChartController {
|
||||
constructor(meta) {
|
||||
// TODO: make configurable passing args
|
||||
|
||||
@ -1 +1,4 @@
|
||||
export const MIN_BAR_PERCENT_HEIGHT = 0.01;
|
||||
export const Y_AXIS_MARGIN = 60;
|
||||
|
||||
export const MIN_BAR_PERCENT_HEIGHT = 0.01;
|
||||
export const DEFAULT_AXIS_CHART_TYPE = 'line';
|
||||
@ -62,6 +62,8 @@ export function getStringWidth(string, charWidth) {
|
||||
return (string+"").length * charWidth;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function observe(obj, componentNames) {
|
||||
let components = this.components.get(name);
|
||||
|
||||
|
||||
@ -1 +0,0 @@
|
||||
export const Y_AXIS_MARGIN = 60;
|
||||
Loading…
x
Reference in New Issue
Block a user