Feat: Adding multi y-Axis support and configurable labes
This commit is contained in:
parent
10de973608
commit
539bc50883
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
@ -30,20 +30,37 @@ export default class AxisChart extends BaseChart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
configure(options) {
|
configure(options) {
|
||||||
super.configure(options);
|
super.configure(options);
|
||||||
|
const { axisOptions = {} } = options;
|
||||||
|
const { xAxis, yAxis } = axisOptions || {};
|
||||||
|
|
||||||
options.axisOptions = options.axisOptions || {};
|
options.tooltipOptions = options.tooltipOptions || {};
|
||||||
options.tooltipOptions = options.tooltipOptions || {};
|
|
||||||
|
|
||||||
this.config.xAxisMode = options.axisOptions.xAxisMode || 'span';
|
this.config.xAxisMode = xAxis ? xAxis.xAxisMode : axisOptions.xAxisMode || 'span';
|
||||||
this.config.yAxisMode = options.axisOptions.yAxisMode || 'span';
|
|
||||||
this.config.xIsSeries = options.axisOptions.xIsSeries || 0;
|
|
||||||
this.config.shortenYAxisNumbers = options.axisOptions.shortenYAxisNumbers || 0;
|
|
||||||
|
|
||||||
this.config.formatTooltipX = options.tooltipOptions.formatTooltipX;
|
// this will pass an array
|
||||||
this.config.formatTooltipY = options.tooltipOptions.formatTooltipY;
|
// lets determine if we need two yAxis based on if there is length
|
||||||
|
// to the yAxis array
|
||||||
|
if (yAxis && yAxis.length) {
|
||||||
|
this.config.yAxisConfig = yAxis.map((item) => {
|
||||||
|
return {
|
||||||
|
yAxisMode: item.yAxisMode,
|
||||||
|
id: item.id,
|
||||||
|
position: item.position,
|
||||||
|
title: item.title
|
||||||
|
};
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.config.yAxisMode = axisOptions.yAxisMode || 'span';
|
||||||
|
}
|
||||||
|
|
||||||
this.config.valuesOverPoints = options.valuesOverPoints;
|
this.config.xIsSeries = axisOptions.xIsSeries || 0;
|
||||||
|
this.config.shortenYAxisNumbers = axisOptions.shortenYAxisNumbers || 0;
|
||||||
|
|
||||||
|
this.config.formatTooltipX = options.tooltipOptions.formatTooltipX;
|
||||||
|
this.config.formatTooltipY = options.tooltipOptions.formatTooltipY;
|
||||||
|
|
||||||
|
this.config.valuesOverPoints = options.valuesOverPoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareData(data=this.data) {
|
prepareData(data=this.data) {
|
||||||
@ -83,45 +100,106 @@ export default class AxisChart extends BaseChart {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
calcYAxisParameters(dataValues, withMinimum = 'false') {
|
|
||||||
const yPts = calcChartIntervals(dataValues, withMinimum);
|
|
||||||
const scaleMultiplier = this.height / getValueRange(yPts);
|
|
||||||
const intervalHeight = getIntervalSize(yPts) * scaleMultiplier;
|
|
||||||
const zeroLine = this.height - (getZeroIndex(yPts) * intervalHeight);
|
|
||||||
|
|
||||||
this.state.yAxis = {
|
calcYAxisParameters(dataValues, withMinimum = 'false') {
|
||||||
labels: yPts,
|
let yPts, scaleMultiplier, intervalHeight, zeroLine, positions;
|
||||||
positions: yPts.map(d => zeroLine - d * scaleMultiplier),
|
|
||||||
scaleMultiplier: scaleMultiplier,
|
|
||||||
zeroLine: zeroLine,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Dependent if above changes
|
// if we have an object we have multiple yAxisParameters.
|
||||||
this.calcDatasetPoints();
|
if (dataValues instanceof Array) {
|
||||||
this.calcYExtremes();
|
yPts = calcChartIntervals(dataValues, withMinimum);
|
||||||
this.calcYRegions();
|
scaleMultiplier = this.height / getValueRange(yPts);
|
||||||
}
|
intervalHeight = getIntervalSize(yPts) * scaleMultiplier;
|
||||||
|
zeroLine = this.height - getZeroIndex(yPts) * intervalHeight;
|
||||||
|
this.state.yAxis = {
|
||||||
|
labels: yPts,
|
||||||
|
positions: yPts.map((d) => zeroLine - d * scaleMultiplier),
|
||||||
|
scaleMultiplier: scaleMultiplier,
|
||||||
|
zeroLine: zeroLine
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
this.state.yAxis = [];
|
||||||
|
for (let key in dataValues) {
|
||||||
|
const dataValue = dataValues[key];
|
||||||
|
yPts = calcChartIntervals(dataValue, withMinimum);
|
||||||
|
scaleMultiplier = this.height / getValueRange(yPts);
|
||||||
|
intervalHeight = getIntervalSize(yPts) * scaleMultiplier;
|
||||||
|
zeroLine = this.height - getZeroIndex(yPts) * intervalHeight;
|
||||||
|
positions = yPts.map((d) => zeroLine - d * scaleMultiplier);
|
||||||
|
|
||||||
calcDatasetPoints() {
|
const yAxisConfigObject =
|
||||||
let s = this.state;
|
this.config.yAxisConfig.find((item) => key === item.id) || [];
|
||||||
let scaleAll = values => values.map(val => scale(val, s.yAxis));
|
const yAxisAlignment = yAxisConfigObject
|
||||||
|
? yAxisConfigObject.position
|
||||||
|
: 'right';
|
||||||
|
|
||||||
s.datasets = this.data.datasets.map((d, i) => {
|
if (this.state.yAxis.length) {
|
||||||
let values = d.values;
|
const yPtsArray = [];
|
||||||
let cumulativeYs = d.cumulativeYs || [];
|
const firstArr = this.state.yAxis[0];
|
||||||
return {
|
// we need to loop through original positions.
|
||||||
name: d.name && d.name.replace(/<|>|&/g, (char) => char == '&' ? '&' : char == '<' ? '<' : '>'),
|
firstArr.positions.forEach((pos) => {
|
||||||
index: i,
|
yPtsArray.push(Math.ceil(pos / scaleMultiplier));
|
||||||
chartType: d.chartType,
|
});
|
||||||
|
yPts = yPtsArray.reverse();
|
||||||
|
zeroLine = this.height - getZeroIndex(yPts) * intervalHeight;
|
||||||
|
positions = firstArr.positions;
|
||||||
|
}
|
||||||
|
|
||||||
values: values,
|
this.state.yAxis.push({
|
||||||
yPositions: scaleAll(values),
|
axisID: key || 'left-axis',
|
||||||
|
labels: yPts,
|
||||||
|
title: yAxisConfigObject.title,
|
||||||
|
pos: yAxisAlignment,
|
||||||
|
scaleMultiplier,
|
||||||
|
zeroLine,
|
||||||
|
positions
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cumulativeYs: cumulativeYs,
|
// Dependent if above changes
|
||||||
cumulativeYPos: scaleAll(cumulativeYs),
|
this.calcDatasetPoints();
|
||||||
};
|
this.calcYExtremes();
|
||||||
});
|
this.calcYRegions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
calcDatasetPoints() {
|
||||||
|
let s = this.state;
|
||||||
|
let scaleAll = (values, id) => {
|
||||||
|
return values.map((val) => {
|
||||||
|
let { yAxis } = s;
|
||||||
|
|
||||||
|
if (yAxis instanceof Array) {
|
||||||
|
yAxis = yAxis.length > 1 ? yAxis.find((axis) => id === axis.axisID) : s.yAxis[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return scale(val, yAxis);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
s.barChartIndex = 1;
|
||||||
|
s.datasets = this.data.datasets.map((d, i) => {
|
||||||
|
let values = d.values;
|
||||||
|
let cumulativeYs = d.cumulativeYs || [];
|
||||||
|
|
||||||
|
return {
|
||||||
|
name:
|
||||||
|
d.name &&
|
||||||
|
d.name.replace(/<|>|&/g, (char) =>
|
||||||
|
char == '&' ? '&' : char == '<' ? '<' : '>'
|
||||||
|
),
|
||||||
|
index: i,
|
||||||
|
barIndex: d.chartType === 'bar' ? s.barChartIndex++ : s.barChartIndex,
|
||||||
|
chartType: d.chartType,
|
||||||
|
|
||||||
|
values: values,
|
||||||
|
yPositions: scaleAll(values, d.axisID),
|
||||||
|
id: d.axisID,
|
||||||
|
|
||||||
|
cumulativeYs: cumulativeYs,
|
||||||
|
cumulativeYPos: scaleAll(cumulativeYs, d.axisID)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
calcYExtremes() {
|
calcYExtremes() {
|
||||||
let s = this.state;
|
let s = this.state;
|
||||||
@ -161,46 +239,73 @@ export default class AxisChart extends BaseChart {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getAllYValues() {
|
getAllYValues() {
|
||||||
let key = 'values';
|
let key = 'values';
|
||||||
|
let multiAxis = this.config.yAxisConfig ? true : false;
|
||||||
|
let allValueLists = multiAxis ? {} : [];
|
||||||
|
|
||||||
if(this.barOptions.stacked) {
|
let groupBy = (arr, property) => {
|
||||||
key = 'cumulativeYs';
|
return arr.reduce((acc, cur) => {
|
||||||
let cumulative = new Array(this.state.datasetLength).fill(0);
|
acc[cur[property]] = [...(acc[cur[property]] || []), cur];
|
||||||
this.data.datasets.map((d, i) => {
|
return acc;
|
||||||
let values = this.data.datasets[i].values;
|
}, {});
|
||||||
d[key] = cumulative = cumulative.map((c, i) => c + values[i]);
|
};
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let allValueLists = this.data.datasets.map(d => d[key]);
|
let generateCumulative = (arr) => {
|
||||||
if(this.data.yMarkers) {
|
let cumulative = new Array(this.state.datasetLength).fill(0);
|
||||||
allValueLists.push(this.data.yMarkers.map(d => d.value));
|
arr.forEach((d, i) => {
|
||||||
}
|
let values = arr[i].values;
|
||||||
if(this.data.yRegions) {
|
d[key] = cumulative = cumulative.map((c, i) => {
|
||||||
this.data.yRegions.map(d => {
|
return c + values[i];
|
||||||
allValueLists.push([d.end, d.start]);
|
});
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
return [].concat(...allValueLists);
|
if (this.barOptions.stacked) {
|
||||||
}
|
key = 'cumulativeYs';
|
||||||
|
// we need to filter out the different yAxis ID's here.
|
||||||
|
if (multiAxis) {
|
||||||
|
const groupedDataSets = groupBy(this.data.datasets, 'axisID');
|
||||||
|
// const dataSetsByAxis = this.data.dd
|
||||||
|
for (var axisID in groupedDataSets) {
|
||||||
|
generateCumulative(groupedDataSets[axisID]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
generateCumulative(this.data.datasets);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is the trouble maker, we don't want to merge all
|
||||||
|
// datasets since we are trying to run two yAxis.
|
||||||
|
if (multiAxis) {
|
||||||
|
this.data.datasets.forEach((d) => {
|
||||||
|
// if the array exists already just push more data into it.
|
||||||
|
// otherwise create a new array into the object.
|
||||||
|
allValueLists[d.axisID || key]
|
||||||
|
? allValueLists[d.axisID || key].push(...d[key])
|
||||||
|
: (allValueLists[d.axisID || key] = [...d[key]]);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
allValueLists = this.data.datasets.map((d) => {
|
||||||
|
return d[key];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.data.yMarkers && !multiAxis) {
|
||||||
|
allValueLists.push(this.data.yMarkers.map((d) => d.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.data.yRegions && !multiAxis) {
|
||||||
|
this.data.yRegions.map((d) => {
|
||||||
|
allValueLists.push([d.end, d.start]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return multiAxis ? allValueLists : [].concat(...allValueLists);
|
||||||
|
}
|
||||||
|
|
||||||
setupComponents() {
|
setupComponents() {
|
||||||
let componentConfigs = [
|
let componentConfigs = [
|
||||||
[
|
|
||||||
'yAxis',
|
|
||||||
{
|
|
||||||
mode: this.config.yAxisMode,
|
|
||||||
width: this.width,
|
|
||||||
shortenNumbers: this.config.shortenYAxisNumbers
|
|
||||||
// pos: 'right'
|
|
||||||
},
|
|
||||||
function() {
|
|
||||||
return this.state.yAxis;
|
|
||||||
}.bind(this)
|
|
||||||
],
|
|
||||||
|
|
||||||
[
|
[
|
||||||
'xAxis',
|
'xAxis',
|
||||||
{
|
{
|
||||||
@ -229,11 +334,43 @@ export default class AxisChart extends BaseChart {
|
|||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// if we have multiple yAxisConfigs we need to update the yAxisDefault
|
||||||
|
// components to multiple yAxis components.
|
||||||
|
if (this.config.yAxisConfig && this.config.yAxisConfig.length) {
|
||||||
|
this.config.yAxisConfig.forEach((yAxis) => {
|
||||||
|
componentConfigs.push([
|
||||||
|
'yAxis',
|
||||||
|
{
|
||||||
|
mode: this.config.yAxisMode,
|
||||||
|
width: this.width,
|
||||||
|
shortenNumbers: this.config.shortenYAxisNumbers,
|
||||||
|
pos: yAxis.position || 'left'
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
return this.state.yAxis;
|
||||||
|
}.bind(this)
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
componentConfigs.push([
|
||||||
|
'yAxis',
|
||||||
|
{
|
||||||
|
mode: this.config.yAxisMode,
|
||||||
|
width: this.width,
|
||||||
|
shortenNumbers: this.config.shortenYAxisNumbers
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
return this.state.yAxis;
|
||||||
|
}.bind(this)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
let barDatasets = this.state.datasets.filter(d => d.chartType === 'bar');
|
let barDatasets = this.state.datasets.filter(d => d.chartType === 'bar');
|
||||||
let lineDatasets = this.state.datasets.filter(d => d.chartType === 'line');
|
let lineDatasets = this.state.datasets.filter(d => d.chartType === 'line');
|
||||||
|
|
||||||
let barsConfigs = barDatasets.map(d => {
|
let barsConfigs = barDatasets.map(d => {
|
||||||
let index = d.index;
|
let index = d.index;
|
||||||
|
let barIndex = d.barIndex || index;
|
||||||
return [
|
return [
|
||||||
'barGraph' + '-' + d.index,
|
'barGraph' + '-' + d.index,
|
||||||
{
|
{
|
||||||
@ -246,32 +383,44 @@ export default class AxisChart extends BaseChart {
|
|||||||
minHeight: this.height * MIN_BAR_PERCENT_HEIGHT,
|
minHeight: this.height * MIN_BAR_PERCENT_HEIGHT,
|
||||||
},
|
},
|
||||||
function() {
|
function() {
|
||||||
let s = this.state;
|
let s = this.state;
|
||||||
let d = s.datasets[index];
|
let { yAxis } = s;
|
||||||
let stacked = this.barOptions.stacked;
|
let d = s.datasets[index];
|
||||||
|
let { id = 'left-axis' } = d;
|
||||||
|
let stacked = this.barOptions.stacked;
|
||||||
|
|
||||||
let spaceRatio = this.barOptions.spaceRatio || BAR_CHART_SPACE_RATIO;
|
let spaceRatio = this.barOptions.spaceRatio || BAR_CHART_SPACE_RATIO;
|
||||||
let barsWidth = s.unitWidth * (1 - spaceRatio);
|
let barsWidth = s.unitWidth * (1 - spaceRatio);
|
||||||
let barWidth = barsWidth/(stacked ? 1 : barDatasets.length);
|
let barWidth = barsWidth / (stacked ? 1 : barDatasets.length);
|
||||||
|
|
||||||
let xPositions = s.xAxis.positions.map(x => x - barsWidth/2);
|
// if there are multiple yAxis we need to return the yAxis with the
|
||||||
if(!stacked) {
|
// proper ID.
|
||||||
xPositions = xPositions.map(p => p + barWidth * index);
|
if (yAxis instanceof Array) {
|
||||||
|
// if the person only configured one yAxis in the array return the first.
|
||||||
|
yAxis = yAxis.length > 1 ? yAxis.find((axis) => id === axis.axisID) : s.yAxis[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
let labels = new Array(s.datasetLength).fill('');
|
|
||||||
if(this.config.valuesOverPoints) {
|
|
||||||
if(stacked && d.index === s.datasets.length - 1) {
|
|
||||||
labels = d.cumulativeYs;
|
|
||||||
} else {
|
|
||||||
labels = d.values;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let offsets = new Array(s.datasetLength).fill(0);
|
let xPositions = s.xAxis.positions.map((x) => x - barsWidth / 2);
|
||||||
if(stacked) {
|
|
||||||
offsets = d.yPositions.map((y, j) => y - d.cumulativeYPos[j]);
|
if (!stacked) {
|
||||||
}
|
xPositions = xPositions.map((p) => {
|
||||||
|
return p + barWidth * barIndex - barWidth;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let labels = new Array(s.datasetLength).fill('');
|
||||||
|
if (this.config.valuesOverPoints) {
|
||||||
|
if (stacked && d.index === s.datasets.length - 1) {
|
||||||
|
labels = d.cumulativeYs;
|
||||||
|
} else {
|
||||||
|
labels = d.values;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let offsets = new Array(s.datasetLength).fill(0);
|
||||||
|
if (stacked) {
|
||||||
|
offsets = d.yPositions.map((y, j) => y - d.cumulativeYPos[j]);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
xPositions: xPositions,
|
xPositions: xPositions,
|
||||||
@ -280,7 +429,7 @@ export default class AxisChart extends BaseChart {
|
|||||||
// values: d.values,
|
// values: d.values,
|
||||||
labels: labels,
|
labels: labels,
|
||||||
|
|
||||||
zeroLine: s.yAxis.zeroLine,
|
zeroLine: yAxis.zeroLine,
|
||||||
barsWidth: barsWidth,
|
barsWidth: barsWidth,
|
||||||
barWidth: barWidth,
|
barWidth: barWidth,
|
||||||
};
|
};
|
||||||
@ -288,41 +437,49 @@ export default class AxisChart extends BaseChart {
|
|||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
let lineConfigs = lineDatasets.map(d => {
|
let lineConfigs = lineDatasets.map((d) => {
|
||||||
let index = d.index;
|
let index = d.index;
|
||||||
return [
|
return [
|
||||||
'lineGraph' + '-' + d.index,
|
'lineGraph' + '-' + d.index,
|
||||||
{
|
{
|
||||||
index: index,
|
index: index,
|
||||||
color: this.colors[index],
|
color: this.colors[index],
|
||||||
svgDefs: this.svgDefs,
|
svgDefs: this.svgDefs,
|
||||||
heatline: this.lineOptions.heatline,
|
heatline: this.lineOptions.heatline,
|
||||||
regionFill: this.lineOptions.regionFill,
|
regionFill: this.lineOptions.regionFill,
|
||||||
spline: this.lineOptions.spline,
|
spline: this.lineOptions.spline,
|
||||||
hideDots: this.lineOptions.hideDots,
|
hideDots: this.lineOptions.hideDots,
|
||||||
hideLine: this.lineOptions.hideLine,
|
hideLine: this.lineOptions.hideLine,
|
||||||
|
|
||||||
// same for all datasets
|
// same for all datasets
|
||||||
valuesOverPoints: this.config.valuesOverPoints,
|
valuesOverPoints: this.config.valuesOverPoints
|
||||||
},
|
},
|
||||||
function() {
|
function () {
|
||||||
let s = this.state;
|
let s = this.state;
|
||||||
let d = s.datasets[index];
|
let d = s.datasets[index];
|
||||||
let minLine = s.yAxis.positions[0] < s.yAxis.zeroLine
|
|
||||||
? s.yAxis.positions[0] : s.yAxis.zeroLine;
|
|
||||||
|
|
||||||
return {
|
// if we have more than one yindex lets map the values
|
||||||
xPositions: s.xAxis.positions,
|
const yAxis = s.yAxis.length
|
||||||
yPositions: d.yPositions,
|
? s.yAxis.find((axis) => d.id === axis.axisID) || s.yAxis[0]
|
||||||
|
: s.yAxis;
|
||||||
|
|
||||||
values: d.values,
|
let minLine =
|
||||||
|
yAxis.positions[0] < yAxis.zeroLine
|
||||||
|
? yAxis.positions[0]
|
||||||
|
: yAxis.zeroLine;
|
||||||
|
|
||||||
zeroLine: minLine,
|
return {
|
||||||
radius: this.lineOptions.dotSize || LINE_CHART_DOT_SIZE,
|
xPositions: s.xAxis.positions,
|
||||||
};
|
yPositions: d.yPositions,
|
||||||
}.bind(this)
|
|
||||||
];
|
values: d.values,
|
||||||
});
|
|
||||||
|
zeroLine: minLine,
|
||||||
|
radius: this.lineOptions.dotSize || LINE_CHART_DOT_SIZE
|
||||||
|
};
|
||||||
|
}.bind(this)
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
let markerConfigs = [
|
let markerConfigs = [
|
||||||
[
|
[
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { makeSVGGroup } from '../utils/draw';
|
import { makeSVGGroup } from '../utils/draw';
|
||||||
import { makeText, makePath, xLine, yLine, yMarker, yRegion, datasetBar, datasetDot, percentageBar, getPaths, heatSquare } from '../utils/draw';
|
import { makeText, generateAxisLabel, makePath, xLine, yLine, yMarker, yRegion, datasetBar, datasetDot, percentageBar, getPaths, heatSquare } from '../utils/draw';
|
||||||
import { equilizeNoOfElements } from '../utils/draw-utils';
|
import { equilizeNoOfElements } from '../utils/draw-utils';
|
||||||
import { translateHoriLine, translateVertLine, animateRegion, animateBar,
|
import { translateHoriLine, translateVertLine, animateRegion, animateBar,
|
||||||
animateDot, animatePath, animatePathStr } from '../utils/animate';
|
animateDot, animatePath, animatePathStr } from '../utils/animate';
|
||||||
@ -50,9 +50,13 @@ class ChartComponent {
|
|||||||
this.store = this.makeElements(data);
|
this.store = this.makeElements(data);
|
||||||
|
|
||||||
this.layer.textContent = '';
|
this.layer.textContent = '';
|
||||||
this.store.forEach(element => {
|
this.store.forEach((element) => {
|
||||||
this.layer.appendChild(element);
|
element.length
|
||||||
});
|
? element.forEach((el) => {
|
||||||
|
this.layer.appendChild(el);
|
||||||
|
})
|
||||||
|
: this.layer.appendChild(element);
|
||||||
|
});
|
||||||
this.labels.forEach(element => {
|
this.labels.forEach(element => {
|
||||||
this.layer.appendChild(element);
|
this.layer.appendChild(element);
|
||||||
});
|
});
|
||||||
@ -114,36 +118,93 @@ let componentConfigs = {
|
|||||||
if(newData) return [];
|
if(newData) return [];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
yAxis: {
|
yAxis: {
|
||||||
layerClass: 'y axis',
|
layerClass: 'y axis',
|
||||||
makeElements(data) {
|
makeElements(data) {
|
||||||
return data.positions.map((position, i) =>
|
let elements = [];
|
||||||
yLine(position, data.labels[i], this.constants.width,
|
|
||||||
{mode: this.constants.mode, pos: this.constants.pos, shortenNumbers: this.constants.shortenNumbers})
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
animateElements(newData) {
|
if (data.length) {
|
||||||
let newPos = newData.positions;
|
data.forEach((item, i) => {
|
||||||
let newLabels = newData.labels;
|
item.positions.map((position, i) => {
|
||||||
let oldPos = this.oldData.positions;
|
elements.push(
|
||||||
let oldLabels = this.oldData.labels;
|
yLine(position, item.labels[i], this.constants.width, {
|
||||||
|
mode: this.constants.mode,
|
||||||
|
pos: item.pos || this.constants.pos,
|
||||||
|
shortenNumbers: this.constants.shortenNumbers
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
// we need to make yAxis titles if they are defined
|
||||||
|
if (item.title) {
|
||||||
|
elements.push(
|
||||||
|
generateAxisLabel({
|
||||||
|
title: item.title,
|
||||||
|
position: item.pos,
|
||||||
|
height: item.zeroLine,
|
||||||
|
width: this.constants.width
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
[oldPos, newPos] = equilizeNoOfElements(oldPos, newPos);
|
return elements;
|
||||||
[oldLabels, newLabels] = equilizeNoOfElements(oldLabels, newLabels);
|
}
|
||||||
|
|
||||||
this.render({
|
return data.positions.map((position, i) => {
|
||||||
positions: oldPos,
|
return yLine(position, data.labels[i], this.constants.width, {
|
||||||
labels: newLabels
|
mode: this.constants.mode,
|
||||||
});
|
pos: this.constants.pos,
|
||||||
|
shortenNumbers: this.constants.shortenNumbers
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
return this.store.map((line, i) => {
|
animateElements(newData) {
|
||||||
return translateHoriLine(
|
const animateMultipleElements = (oldData, newData) => {
|
||||||
line, newPos[i], oldPos[i]
|
let newPos = newData.positions;
|
||||||
);
|
let newLabels = newData.labels;
|
||||||
});
|
let oldPos = oldData.positions;
|
||||||
}
|
let oldLabels = oldData.labels;
|
||||||
},
|
|
||||||
|
[oldPos, newPos] = equilizeNoOfElements(oldPos, newPos);
|
||||||
|
[oldLabels, newLabels] = equilizeNoOfElements(oldLabels, newLabels);
|
||||||
|
|
||||||
|
this.render({
|
||||||
|
positions: oldPos,
|
||||||
|
labels: newLabels
|
||||||
|
});
|
||||||
|
|
||||||
|
return this.store.map((line, i) => {
|
||||||
|
return translateHoriLine(line, newPos[i], oldPos[i]);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// we will need to animate both axis if we have more than one.
|
||||||
|
// so check if the oldData is an array of values.
|
||||||
|
if (this.oldData instanceof Array) {
|
||||||
|
return this.oldData.forEach((old, i) => {
|
||||||
|
animateMultipleElements(old, newData[i]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let newPos = newData.positions;
|
||||||
|
let newLabels = newData.labels;
|
||||||
|
let oldPos = this.oldData.positions;
|
||||||
|
let oldLabels = this.oldData.labels;
|
||||||
|
|
||||||
|
[oldPos, newPos] = equilizeNoOfElements(oldPos, newPos);
|
||||||
|
[oldLabels, newLabels] = equilizeNoOfElements(oldLabels, newLabels);
|
||||||
|
|
||||||
|
this.render({
|
||||||
|
positions: oldPos,
|
||||||
|
labels: newLabels
|
||||||
|
});
|
||||||
|
|
||||||
|
return this.store.map((line, i) => {
|
||||||
|
return translateHoriLine(line, newPos[i], oldPos[i]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
xAxis: {
|
xAxis: {
|
||||||
layerClass: 'x axis',
|
layerClass: 'x axis',
|
||||||
|
|||||||
@ -61,16 +61,18 @@ export function zeroDataPrep(realData) {
|
|||||||
let datasetLength = realData.labels.length;
|
let datasetLength = realData.labels.length;
|
||||||
let zeroArray = new Array(datasetLength).fill(0);
|
let zeroArray = new Array(datasetLength).fill(0);
|
||||||
|
|
||||||
let zeroData = {
|
let zeroData = {
|
||||||
labels: realData.labels.slice(0, -1),
|
labels: realData.labels.slice(0, -1),
|
||||||
datasets: realData.datasets.map(d => {
|
datasets: realData.datasets.map((d) => {
|
||||||
return {
|
const { axisID } = d;
|
||||||
name: '',
|
return {
|
||||||
values: zeroArray.slice(0, -1),
|
axisID,
|
||||||
chartType: d.chartType
|
name: '',
|
||||||
};
|
values: zeroArray.slice(0, -1),
|
||||||
}),
|
chartType: d.chartType
|
||||||
};
|
};
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
if(realData.yMarkers) {
|
if(realData.yMarkers) {
|
||||||
zeroData.yMarkers = [
|
zeroData.yMarkers = [
|
||||||
|
|||||||
1225
src/js/utils/draw.js
1225
src/js/utils/draw.js
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user