[fix] stacked bar animation

This commit is contained in:
Prateeksha Singh 2018-03-04 17:40:34 +05:30
parent de19ce8e31
commit 3a9755cfc9
12 changed files with 81 additions and 61 deletions

View File

@ -336,8 +336,9 @@ function animateRegion(rectGroup, newY1, newY2, oldY2) {
return [rectAnim, groupAnim]; return [rectAnim, groupAnim];
} }
function animateBar(bar, x, yTop, width, index=0, meta={}) { function animateBar(bar, x, yTop, width, offset=0, index=0, meta={}) {
let [height, y] = getBarHeightAndYAttr(yTop, meta.zeroLine); let [height, y] = getBarHeightAndYAttr(yTop, meta.zeroLine);
y -= offset;
if(bar.nodeName !== 'rect') { if(bar.nodeName !== 'rect') {
let rect = bar.childNodes[0]; let rect = bar.childNodes[0];
let rectAnim = [ let rectAnim = [
@ -398,7 +399,7 @@ const LEFT_MARGIN_BASE_CHART = 60;
const RIGHT_MARGIN_BASE_CHART = 40; const RIGHT_MARGIN_BASE_CHART = 40;
const Y_AXIS_MARGIN = 60; const Y_AXIS_MARGIN = 60;
const INIT_CHART_UPDATE_TIMEOUT = 400; const INIT_CHART_UPDATE_TIMEOUT = 1000;
const CHART_POST_ANIMATE_TIMEOUT = 400; const CHART_POST_ANIMATE_TIMEOUT = 400;
const DEFAULT_AXIS_CHART_TYPE = 'line'; const DEFAULT_AXIS_CHART_TYPE = 'line';
@ -1133,9 +1134,9 @@ class BaseChart {
this.rawChartArgs = options; this.rawChartArgs = options;
this.parent = typeof parent === 'string' ? document.querySelector(parent) : parent; this.parent = typeof parent === 'string' ? document.querySelector(parent) : parent;
if (!(this.parent instanceof HTMLElement)) { if (!(this.parent instanceof HTMLElement)) {
throw new Error('No `parent` element to render on was provided.'); throw new Error('No `parent` element to render on was provided.');
} }
this.title = options.title || ''; this.title = options.title || '';
this.subtitle = options.subtitle || ''; this.subtitle = options.subtitle || '';
@ -2510,9 +2511,9 @@ let componentConfigs = {
y, y,
data.barWidth, data.barWidth,
c.color, c.color,
(c.valuesOverPoints ? (c.stacked ? data.cumulativeYs[j] : data.values[j]) : ''), data.labels[j],
j, j,
y - (c.stacked ? data.cumulativeYPos[j] : y), data.offsets[j],
{ {
zeroLine: data.zeroLine, zeroLine: data.zeroLine,
barsWidth: data.barsWidth, barsWidth: data.barsWidth,
@ -2526,29 +2527,24 @@ let componentConfigs = {
let newXPos = newData.xPositions; let newXPos = newData.xPositions;
let newYPos = newData.yPositions; let newYPos = newData.yPositions;
let newCYPos = newData.cumulativeYPos; let newOffsets = newData.offsets;
let newValues = newData.values; let newLabels = newData.labels;
let newCYs = newData.cumulativeYs;
let oldXPos = this.oldData.xPositions; let oldXPos = this.oldData.xPositions;
let oldYPos = this.oldData.yPositions; let oldYPos = this.oldData.yPositions;
let oldCYPos = this.oldData.cumulativeYPos; let oldOffsets = this.oldData.offsets;
let oldValues = this.oldData.values; let oldLabels = this.oldData.labels;
let oldCYs = this.oldData.cumulativeYs;
[oldXPos, newXPos] = equilizeNoOfElements(oldXPos, newXPos); [oldXPos, newXPos] = equilizeNoOfElements(oldXPos, newXPos);
[oldYPos, newYPos] = equilizeNoOfElements(oldYPos, newYPos); [oldYPos, newYPos] = equilizeNoOfElements(oldYPos, newYPos);
[oldCYPos, newCYPos] = equilizeNoOfElements(oldCYPos, newCYPos); [oldOffsets, newOffsets] = equilizeNoOfElements(oldOffsets, newOffsets);
[oldValues, newValues] = equilizeNoOfElements(oldValues, newValues); [oldLabels, newLabels] = equilizeNoOfElements(oldLabels, newLabels);
[oldCYs, newCYs] = equilizeNoOfElements(oldCYs, newCYs);
this.render({ this.render({
xPositions: oldXPos, xPositions: oldXPos,
yPositions: oldYPos, yPositions: oldYPos,
cumulativeYPos: oldCYPos, offsets: oldOffsets,
labels: newLabels,
values: newValues,
cumulativeYs: newCYs,
zeroLine: this.oldData.zeroLine, zeroLine: this.oldData.zeroLine,
barsWidth: this.oldData.barsWidth, barsWidth: this.oldData.barsWidth,
@ -2559,7 +2555,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, c.index, bar, newXPos[i], newYPos[i], newData.barWidth, newOffsets[i], c.index,
{zeroLine: newData.zeroLine} {zeroLine: newData.zeroLine}
)); ));
}); });
@ -2866,23 +2862,37 @@ class AxisChart extends BaseChart {
function() { function() {
let s = this.state; let s = this.state;
let d = s.datasets[index]; let d = s.datasets[index];
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/(this.barOptions.stacked ? 1 : barDatasets.length); let barWidth = barsWidth/(stacked ? 1 : barDatasets.length);
let xPositions = s.xAxis.positions.map(x => x - barsWidth/2); let xPositions = s.xAxis.positions.map(x => x - barsWidth/2);
if(!this.barOptions.stacked) { if(!stacked) {
xPositions = xPositions.map(p => p + barWidth * index); xPositions = xPositions.map(p => p + barWidth * index);
} }
let labels = new Array(s.datasetLength).fill('');
if(this.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,
yPositions: d.yPositions, yPositions: d.yPositions,
cumulativeYPos: d.cumulativeYPos, offsets: offsets,
// values: d.values,
values: d.values, labels: labels,
cumulativeYs: d.cumulativeYs,
zeroLine: s.yAxis.zeroLine, zeroLine: s.yAxis.zeroLine,
barsWidth: barsWidth, barsWidth: barsWidth,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -219,23 +219,37 @@ export default class AxisChart extends BaseChart {
function() { function() {
let s = this.state; let s = this.state;
let d = s.datasets[index]; let d = s.datasets[index];
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/(this.barOptions.stacked ? 1 : barDatasets.length); let barWidth = barsWidth/(stacked ? 1 : barDatasets.length);
let xPositions = s.xAxis.positions.map(x => x - barsWidth/2); let xPositions = s.xAxis.positions.map(x => x - barsWidth/2);
if(!this.barOptions.stacked) { if(!stacked) {
xPositions = xPositions.map(p => p + barWidth * index); xPositions = xPositions.map(p => p + barWidth * index);
} }
let labels = new Array(s.datasetLength).fill('');
if(this.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,
yPositions: d.yPositions, yPositions: d.yPositions,
cumulativeYPos: d.cumulativeYPos, offsets: offsets,
// values: d.values,
values: d.values, labels: labels,
cumulativeYs: d.cumulativeYs,
zeroLine: s.yAxis.zeroLine, zeroLine: s.yAxis.zeroLine,
barsWidth: barsWidth, barsWidth: barsWidth,

View File

@ -13,9 +13,9 @@ export default class BaseChart {
this.rawChartArgs = options; this.rawChartArgs = options;
this.parent = typeof parent === 'string' ? document.querySelector(parent) : parent; this.parent = typeof parent === 'string' ? document.querySelector(parent) : parent;
if (!(this.parent instanceof HTMLElement)) { if (!(this.parent instanceof HTMLElement)) {
throw new Error('No `parent` element to render on was provided.'); throw new Error('No `parent` element to render on was provided.');
} }
this.title = options.title || ''; this.title = options.title || '';
this.subtitle = options.subtitle || ''; this.subtitle = options.subtitle || '';
@ -249,7 +249,7 @@ export default class BaseChart {
'38': this.onUpArrow.bind(this), '38': this.onUpArrow.bind(this),
'39': this.onRightArrow.bind(this), '39': this.onRightArrow.bind(this),
'40': this.onDownArrow.bind(this), '40': this.onDownArrow.bind(this),
} };
document.addEventListener('keydown', (e) => { document.addEventListener('keydown', (e) => {
if(isElementInViewport(this.chartWrapper)) { if(isElementInViewport(this.chartWrapper)) {

View File

@ -207,9 +207,9 @@ let componentConfigs = {
y, y,
data.barWidth, data.barWidth,
c.color, c.color,
(c.valuesOverPoints ? (c.stacked ? data.cumulativeYs[j] : data.values[j]) : ''), data.labels[j],
j, j,
y - (c.stacked ? data.cumulativeYPos[j] : y), data.offsets[j],
{ {
zeroLine: data.zeroLine, zeroLine: data.zeroLine,
barsWidth: data.barsWidth, barsWidth: data.barsWidth,
@ -223,29 +223,24 @@ let componentConfigs = {
let newXPos = newData.xPositions; let newXPos = newData.xPositions;
let newYPos = newData.yPositions; let newYPos = newData.yPositions;
let newCYPos = newData.cumulativeYPos; let newOffsets = newData.offsets;
let newValues = newData.values; let newLabels = newData.labels;
let newCYs = newData.cumulativeYs;
let oldXPos = this.oldData.xPositions; let oldXPos = this.oldData.xPositions;
let oldYPos = this.oldData.yPositions; let oldYPos = this.oldData.yPositions;
let oldCYPos = this.oldData.cumulativeYPos; let oldOffsets = this.oldData.offsets;
let oldValues = this.oldData.values; let oldLabels = this.oldData.labels;
let oldCYs = this.oldData.cumulativeYs;
[oldXPos, newXPos] = equilizeNoOfElements(oldXPos, newXPos); [oldXPos, newXPos] = equilizeNoOfElements(oldXPos, newXPos);
[oldYPos, newYPos] = equilizeNoOfElements(oldYPos, newYPos); [oldYPos, newYPos] = equilizeNoOfElements(oldYPos, newYPos);
[oldCYPos, newCYPos] = equilizeNoOfElements(oldCYPos, newCYPos); [oldOffsets, newOffsets] = equilizeNoOfElements(oldOffsets, newOffsets);
[oldValues, newValues] = equilizeNoOfElements(oldValues, newValues); [oldLabels, newLabels] = equilizeNoOfElements(oldLabels, newLabels);
[oldCYs, newCYs] = equilizeNoOfElements(oldCYs, newCYs);
this.render({ this.render({
xPositions: oldXPos, xPositions: oldXPos,
yPositions: oldYPos, yPositions: oldYPos,
cumulativeYPos: oldCYPos, offsets: oldOffsets,
labels: newLabels,
values: newValues,
cumulativeYs: newCYs,
zeroLine: this.oldData.zeroLine, zeroLine: this.oldData.zeroLine,
barsWidth: this.oldData.barsWidth, barsWidth: this.oldData.barsWidth,
@ -256,7 +251,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, c.index, bar, newXPos[i], newYPos[i], newData.barWidth, newOffsets[i], c.index,
{zeroLine: newData.zeroLine} {zeroLine: newData.zeroLine}
)); ));
}); });

View File

@ -42,8 +42,9 @@ export function animateRegion(rectGroup, newY1, newY2, oldY2) {
return [rectAnim, groupAnim]; return [rectAnim, groupAnim];
} }
export function animateBar(bar, x, yTop, width, index=0, meta={}) { export function animateBar(bar, x, yTop, width, offset=0, index=0, meta={}) {
let [height, y] = getBarHeightAndYAttr(yTop, meta.zeroLine); let [height, y] = getBarHeightAndYAttr(yTop, meta.zeroLine);
y -= offset;
if(bar.nodeName !== 'rect') { if(bar.nodeName !== 'rect') {
let rect = bar.childNodes[0]; let rect = bar.childNodes[0];
let rectAnim = [ let rectAnim = [

View File

@ -4,7 +4,7 @@ export const LEFT_MARGIN_BASE_CHART = 60;
export const RIGHT_MARGIN_BASE_CHART = 40; export const RIGHT_MARGIN_BASE_CHART = 40;
export const Y_AXIS_MARGIN = 60; export const Y_AXIS_MARGIN = 60;
export const INIT_CHART_UPDATE_TIMEOUT = 400; export const INIT_CHART_UPDATE_TIMEOUT = 1000;
export const CHART_POST_ANIMATE_TIMEOUT = 400; export const CHART_POST_ANIMATE_TIMEOUT = 400;
export const DEFAULT_AXIS_CHART_TYPE = 'line'; export const DEFAULT_AXIS_CHART_TYPE = 'line';