[animate] cycle update, x axis

This commit is contained in:
Prateeksha Singh 2018-02-25 13:09:54 +05:30
parent b11a78aa31
commit 8d3bd38d6d
12 changed files with 358 additions and 228 deletions

View File

@ -301,7 +301,9 @@ function translate(unit, oldCoord, newCoord, duration) {
]; ];
} }
function translateVertLine(xLine, newX, oldX) {
return translate(xLine, [oldX, 0], [newX, 0], MARKER_LINE_ANIM_DUR);
}
function translateHoriLine(yLine, newY, oldY) { function translateHoriLine(yLine, newY, oldY) {
return translate(yLine, [0, oldY], [0, newY], MARKER_LINE_ANIM_DUR); return translate(yLine, [0, oldY], [0, newY], MARKER_LINE_ANIM_DUR);
@ -551,6 +553,40 @@ function yLine(y, label, width, options={}) {
}); });
} }
function xLine$1(x, label, height, options={}) {
if(!options.pos) options.pos = 'bottom';
if(!options.offset) options.offset = 0;
if(!options.mode) options.mode = 'span';
if(!options.stroke) options.stroke = BASE_LINE_COLOR;
if(!options.className) options.className = '';
// Draw X axis line in span/tick mode with optional label
// y2(span)
// |
// |
// x line |
// |
// |
// ---------------------+-- y2(tick)
// |
// y1
let y1 = height + AXIS_TICK_LENGTH;
let y2 = options.mode === 'span' ? -1 * AXIS_TICK_LENGTH : height;
if(options.mode === 'tick' && options.pos === 'top') {
// top axis ticks
y1 = -1 * AXIS_TICK_LENGTH;
y2 = 0;
}
return makeVertLine(x, label, y1, y2, {
stroke: options.stroke,
className: options.className,
lineType: options.lineType
});
}
class AxisChartRenderer { class AxisChartRenderer {
constructor(state) { constructor(state) {
this.refreshState(state); this.refreshState(state);
@ -569,43 +605,6 @@ class AxisChartRenderer {
this.zeroLine = zeroLine; this.zeroLine = zeroLine;
} }
xLine(x, label, options={}) {
if(!options.pos) options.pos = 'bottom';
if(!options.offset) options.offset = 0;
if(!options.mode) options.mode = 'span';
if(!options.stroke) options.stroke = BASE_LINE_COLOR;
if(!options.className) options.className = '';
// Draw X axis line in span/tick mode with optional label
// y2(span)
// |
// |
// x line |
// |
// |
// ---------------------+-- y2(tick)
// |
// y1
let y1 = this.totalHeight + AXIS_TICK_LENGTH;
let y2 = options.mode === 'span' ? -1 * AXIS_TICK_LENGTH : this.totalHeight;
if(options.mode === 'tick' && options.pos === 'top') {
// top axis ticks
y1 = -1 * AXIS_TICK_LENGTH;
y2 = 0;
}
return makeVertLine(x, label, y1, y2, {
stroke: options.stroke,
className: options.className,
lineType: options.lineType
});
}
xMarker() {} xMarker() {}
yMarker(y, label, options={}) { yMarker(y, label, options={}) {
let labelSvg = createSVG('text', { let labelSvg = createSVG('text', {
@ -1074,8 +1073,9 @@ class BaseChart {
this.calcWidth(); this.calcWidth();
this.makeChartArea(); this.makeChartArea();
this.setupComponents(); this.initComponents();
this.setupComponents();
this.draw(true); this.draw(true);
} }
@ -1160,7 +1160,6 @@ class BaseChart {
render(animate=true) { render(animate=true) {
this.refreshComponents(); this.refreshComponents();
this.elementsToAnimate = [].concat.apply([], this.components.map(c => c.update(animate))); this.elementsToAnimate = [].concat.apply([], this.components.map(c => c.update(animate)));
console.log(this.elementsToAnimate);
if(this.elementsToAnimate) { if(this.elementsToAnimate) {
runSMILAnimation(this.chartWrapper, this.svg, this.elementsToAnimate); runSMILAnimation(this.chartWrapper, this.svg, this.elementsToAnimate);
} }
@ -1282,6 +1281,7 @@ class ChartComponent$1 {
preMake, preMake,
makeElements, makeElements,
postMake, postMake,
getData,
animateElements animateElements
}) { }) {
this.parent = parent; this.parent = parent;
@ -1292,6 +1292,7 @@ class ChartComponent$1 {
this.preMake = preMake; this.preMake = preMake;
this.makeElements = makeElements; this.makeElements = makeElements;
this.postMake = postMake; this.postMake = postMake;
this.getData = getData;
this.animateElements = animateElements; this.animateElements = animateElements;
@ -1336,12 +1337,9 @@ class ChartComponent$1 {
} }
} }
function getYAxisComponent(parent, constants, initData) { let componentConfigs = {
return new ChartComponent$1({ yAxis: {
parent: parent,
layerClass: 'y axis', layerClass: 'y axis',
constants: constants,
data: initData,
makeElements: function(data) { makeElements: function(data) {
return data.positions.map((position, i) => return data.positions.map((position, i) =>
yLine(position, data.labels[i], this.constants.width, yLine(position, data.labels[i], this.constants.width,
@ -1352,7 +1350,6 @@ function getYAxisComponent(parent, constants, initData) {
animateElements: function(newData) { animateElements: function(newData) {
let newPos = newData.positions; let newPos = newData.positions;
let newLabels = newData.labels; let newLabels = newData.labels;
let oldPos = this.oldData.positions; let oldPos = this.oldData.positions;
let oldLabels = this.oldData.labels; let oldLabels = this.oldData.labels;
@ -1370,7 +1367,49 @@ function getYAxisComponent(parent, constants, initData) {
); );
}); });
} }
}) },
xAxis: {
layerClass: 'x axis',
makeElements: function(data) {
return data.positions.map((position, i) =>
xLine$1(position, data.labels[i], this.constants.height,
{mode: this.constants.mode, pos: this.constants.pos})
);
},
animateElements: function(newData) {
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 translateVertLine(
line, newPos[i], oldPos[i]
);
});
}
}
};
function getComponent(name, parent, constants, initData, getData) {
let config = componentConfigs[name];
Object.assign(config, {
parent: parent,
constants: constants,
data: initData,
getData: getData
});
return new ChartComponent$1(config);
} }
const MIN_BAR_PERCENT_HEIGHT$1 = 0.01; const MIN_BAR_PERCENT_HEIGHT$1 = 0.01;
@ -2060,47 +2099,75 @@ class AxisChart extends BaseChart {
setupValues() {} setupValues() {}
setupComponents() { initComponents() {
// TODO: rebind new units // TODO: rebind new units
// if(this.isNavigable) { // if(this.isNavigable) {
// this.bind_units(units_array); // this.bind_units(units_array);
// } // }
this.yAxis = getYAxisComponent(
this.drawArea, this.componentConfigs = [
{ [
mode: this.yAxisMode, 'yAxis',
width: this.width, this.drawArea,
// pos: 'right' {
}, mode: this.yAxisMode,
{ width: this.width,
positions: getRealIntervals(this.height, 4, 0, 0), // pos: 'right'
labels: getRealIntervals(this.height, 4, 0, 0).map(d => d + ""), },
} {
); positions: getRealIntervals(this.height, 4, 0, 0),
this.components = [ labels: getRealIntervals(this.height, 4, 0, 0).map(d => d + ""),
this.yAxis },
// this.getXAxisComponents(), function() {
// ...this.getYRegions(), let s = this.state;
// ...this.getXRegions(), return {
// ...this.getYMarkerLines(), positions: s.yAxis.positions,
// // ...this.getXMarkerLines(), labels: s.yAxis.labels,
// ...this.getChartComponents(), }
// ...this.getChartLabels(), }.bind(this)
],
[
'xAxis',
this.drawArea,
{
mode: this.xAxisMode,
height: this.height,
// pos: 'right'
},
{
positions: getRealIntervals(this.width, 4, 0, 1),
labels: getRealIntervals(this.width, 4, 0, 1).map(d => d + ""),
},
function() {
let s = this.state;
return {
positions: s.xAxisPositions,
labels: s.xAxisLabels,
}
}.bind(this)
]
]; ];
// this.components = [
// yAxis
// // this.getXAxisComponents(),
// // ...this.getYRegions(),
// // ...this.getXRegions(),
// // ...this.getYMarkerLines(),
// // // ...this.getXMarkerLines(),
// // ...this.getChartComponents(),
// // ...this.getChartLabels(),
// ];
}
setupComponents() {
this.components = this.componentConfigs.map(args => getComponent(...args));
} }
refreshComponents() { refreshComponents() {
this.refreshYAxis(); this.components.forEach(comp => comp.refresh(comp.getData()));
}
refreshYAxis() {
let s = this.state;
this.yAxis.refresh({
positions: s.yAxis.positions,
labels: s.yAxis.labels,
});
} }
getXAxisComponents() { getXAxisComponents() {
@ -2786,40 +2853,40 @@ class PercentageChart extends BaseChart {
calc() {} calc() {}
// bindTooltip() { bindTooltip() {
// this.slices.map((slice, i) => { this.slices.map((slice, i) => {
// slice.addEventListener('mouseenter', () => { slice.addEventListener('mouseenter', () => {
// let g_off = getOffset(this.chartWrapper), p_off = getOffset(slice); let g_off = getOffset(this.chartWrapper), p_off = getOffset(slice);
// let x = p_off.left - g_off.left + slice.offsetWidth/2; let x = p_off.left - g_off.left + slice.offsetWidth/2;
// let y = p_off.top - g_off.top - 6; let y = p_off.top - g_off.top - 6;
// let title = (this.formatted_labels && this.formatted_labels.length>0 let title = (this.formatted_labels && this.formatted_labels.length>0
// ? this.formatted_labels[i] : this.labels[i]) + ': '; ? this.formatted_labels[i] : this.labels[i]) + ': ';
// let percent = (this.slice_totals[i]*100/this.grand_total).toFixed(1); let percent = (this.slice_totals[i]*100/this.grand_total).toFixed(1);
// this.tip.set_values(x, y, title, percent + "%"); this.tip.set_values(x, y, title, percent + "%");
// this.tip.show_tip(); this.tip.show_tip();
// }); });
// }); });
// } }
// renderLegend() { renderLegend() {
// let x_values = this.formatted_labels && this.formatted_labels.length > 0 let x_values = this.formatted_labels && this.formatted_labels.length > 0
// ? this.formatted_labels : this.labels; ? this.formatted_labels : this.labels;
// this.legend_totals.map((d, i) => { this.legend_totals.map((d, i) => {
// if(d) { if(d) {
// let stats = $.create('div', { let stats = $$1.create('div', {
// className: 'stats', className: 'stats',
// inside: this.statsWrapper inside: this.statsWrapper
// }); });
// stats.innerHTML = `<span class="indicator"> stats.innerHTML = `<span class="indicator">
// <i style="background: ${this.colors[i]}"></i> <i style="background: ${this.colors[i]}"></i>
// <span class="text-muted">${x_values[i]}:</span> <span class="text-muted">${x_values[i]}:</span>
// ${d} ${d}
// </span>`; </span>`;
// } }
// }); });
// } }
} }
const ANGLE_RATIO = Math.PI / 180; const ANGLE_RATIO = Math.PI / 180;

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

@ -1,6 +1,6 @@
import BaseChart from './BaseChart'; import BaseChart from './BaseChart';
import { Y_AXIS_MARGIN } from '../utils/margins'; import { Y_AXIS_MARGIN } from '../utils/margins';
import { getYAxisComponent } from '../objects/ChartComponents'; import { getComponent } from '../objects/ChartComponents';
import { BarChartController, LineChartController, getPaths } from '../objects/AxisChartControllers'; import { BarChartController, LineChartController, getPaths } from '../objects/AxisChartControllers';
import { AxisChartRenderer } from '../utils/draw'; import { AxisChartRenderer } from '../utils/draw';
import { getOffset, fire } from '../utils/dom'; import { getOffset, fire } from '../utils/dom';
@ -252,47 +252,75 @@ export default class AxisChart extends BaseChart {
setupValues() {} setupValues() {}
setupComponents() { initComponents() {
// TODO: rebind new units // TODO: rebind new units
// if(this.isNavigable) { // if(this.isNavigable) {
// this.bind_units(units_array); // this.bind_units(units_array);
// } // }
this.yAxis = getYAxisComponent(
this.drawArea, this.componentConfigs = [
{ [
mode: this.yAxisMode, 'yAxis',
width: this.width, this.drawArea,
// pos: 'right' {
}, mode: this.yAxisMode,
{ width: this.width,
positions: getRealIntervals(this.height, 4, 0, 0), // pos: 'right'
labels: getRealIntervals(this.height, 4, 0, 0).map(d => d + ""), },
} {
) positions: getRealIntervals(this.height, 4, 0, 0),
this.components = [ labels: getRealIntervals(this.height, 4, 0, 0).map(d => d + ""),
this.yAxis },
// this.getXAxisComponents(), function() {
// ...this.getYRegions(), let s = this.state;
// ...this.getXRegions(), return {
// ...this.getYMarkerLines(), positions: s.yAxis.positions,
// // ...this.getXMarkerLines(), labels: s.yAxis.labels,
// ...this.getChartComponents(), }
// ...this.getChartLabels(), }.bind(this)
],
[
'xAxis',
this.drawArea,
{
mode: this.xAxisMode,
height: this.height,
// pos: 'right'
},
{
positions: getRealIntervals(this.width, 4, 0, 1),
labels: getRealIntervals(this.width, 4, 0, 1).map(d => d + ""),
},
function() {
let s = this.state;
return {
positions: s.xAxisPositions,
labels: s.xAxisLabels,
}
}.bind(this)
]
]; ];
// this.components = [
// yAxis
// // this.getXAxisComponents(),
// // ...this.getYRegions(),
// // ...this.getXRegions(),
// // ...this.getYMarkerLines(),
// // // ...this.getXMarkerLines(),
// // ...this.getChartComponents(),
// // ...this.getChartLabels(),
// ];
}
setupComponents() {
this.components = this.componentConfigs.map(args => getComponent(...args));
} }
refreshComponents() { refreshComponents() {
this.refreshYAxis(); this.components.forEach(comp => comp.refresh(comp.getData()));
}
refreshYAxis() {
let s = this.state;
this.yAxis.refresh({
positions: s.yAxis.positions,
labels: s.yAxis.labels,
});
} }
getXAxisComponents() { getXAxisComponents() {

View File

@ -135,8 +135,9 @@ export default class BaseChart {
this.calcWidth(); this.calcWidth();
this.makeChartArea(); this.makeChartArea();
this.setupComponents(); this.initComponents();
this.setupComponents();
this.draw(true); this.draw(true);
} }
@ -221,7 +222,6 @@ export default class BaseChart {
render(animate=true) { render(animate=true) {
this.refreshComponents(); this.refreshComponents();
this.elementsToAnimate = [].concat.apply([], this.components.map(c => c.update(animate))); this.elementsToAnimate = [].concat.apply([], this.components.map(c => c.update(animate)));
console.log(this.elementsToAnimate);
if(this.elementsToAnimate) { if(this.elementsToAnimate) {
runSMILAnimation(this.chartWrapper, this.svg, this.elementsToAnimate); runSMILAnimation(this.chartWrapper, this.svg, this.elementsToAnimate);
} }

View File

@ -91,38 +91,38 @@ export default class PercentageChart extends BaseChart {
calc() {} calc() {}
// bindTooltip() { bindTooltip() {
// this.slices.map((slice, i) => { this.slices.map((slice, i) => {
// slice.addEventListener('mouseenter', () => { slice.addEventListener('mouseenter', () => {
// let g_off = getOffset(this.chartWrapper), p_off = getOffset(slice); let g_off = getOffset(this.chartWrapper), p_off = getOffset(slice);
// let x = p_off.left - g_off.left + slice.offsetWidth/2; let x = p_off.left - g_off.left + slice.offsetWidth/2;
// let y = p_off.top - g_off.top - 6; let y = p_off.top - g_off.top - 6;
// let title = (this.formatted_labels && this.formatted_labels.length>0 let title = (this.formatted_labels && this.formatted_labels.length>0
// ? this.formatted_labels[i] : this.labels[i]) + ': '; ? this.formatted_labels[i] : this.labels[i]) + ': ';
// let percent = (this.slice_totals[i]*100/this.grand_total).toFixed(1); let percent = (this.slice_totals[i]*100/this.grand_total).toFixed(1);
// this.tip.set_values(x, y, title, percent + "%"); this.tip.set_values(x, y, title, percent + "%");
// this.tip.show_tip(); this.tip.show_tip();
// }); });
// }); });
// } }
// renderLegend() { renderLegend() {
// let x_values = this.formatted_labels && this.formatted_labels.length > 0 let x_values = this.formatted_labels && this.formatted_labels.length > 0
// ? this.formatted_labels : this.labels; ? this.formatted_labels : this.labels;
// this.legend_totals.map((d, i) => { this.legend_totals.map((d, i) => {
// if(d) { if(d) {
// let stats = $.create('div', { let stats = $.create('div', {
// className: 'stats', className: 'stats',
// inside: this.statsWrapper inside: this.statsWrapper
// }); });
// stats.innerHTML = `<span class="indicator"> stats.innerHTML = `<span class="indicator">
// <i style="background: ${this.colors[i]}"></i> <i style="background: ${this.colors[i]}"></i>
// <span class="text-muted">${x_values[i]}:</span> <span class="text-muted">${x_values[i]}:</span>
// ${d} ${d}
// </span>`; </span>`;
// } }
// }); });
// } }
} }

View File

@ -1,7 +1,7 @@
import { makeSVGGroup } from '../utils/draw'; import { makeSVGGroup } from '../utils/draw';
import { yLine } from '../utils/draw'; import { xLine, yLine } from '../utils/draw';
import { equilizeNoOfElements } from '../utils/draw-utils'; import { equilizeNoOfElements } from '../utils/draw-utils';
import { Animator, translateHoriLine } from '../utils/animate'; import { Animator, translateHoriLine, translateVertLine } from '../utils/animate';
class ChartComponent { class ChartComponent {
constructor({ constructor({
@ -15,6 +15,7 @@ class ChartComponent {
preMake, preMake,
makeElements, makeElements,
postMake, postMake,
getData,
animateElements animateElements
}) { }) {
this.parent = parent; this.parent = parent;
@ -25,6 +26,7 @@ class ChartComponent {
this.preMake = preMake; this.preMake = preMake;
this.makeElements = makeElements; this.makeElements = makeElements;
this.postMake = postMake; this.postMake = postMake;
this.getData = getData;
this.animateElements = animateElements; this.animateElements = animateElements;
@ -69,12 +71,9 @@ class ChartComponent {
} }
} }
export function getYAxisComponent(parent, constants, initData) { let componentConfigs = {
return new ChartComponent({ yAxis: {
parent: parent,
layerClass: 'y axis', layerClass: 'y axis',
constants: constants,
data: initData,
makeElements: function(data) { makeElements: function(data) {
return data.positions.map((position, i) => return data.positions.map((position, i) =>
yLine(position, data.labels[i], this.constants.width, yLine(position, data.labels[i], this.constants.width,
@ -85,12 +84,9 @@ export function getYAxisComponent(parent, constants, initData) {
animateElements: function(newData) { animateElements: function(newData) {
let newPos = newData.positions; let newPos = newData.positions;
let newLabels = newData.labels; let newLabels = newData.labels;
let oldPos = this.oldData.positions; let oldPos = this.oldData.positions;
let oldLabels = this.oldData.labels; let oldLabels = this.oldData.labels;
let extra = newPos.length - oldPos.length;
[oldPos, newPos] = equilizeNoOfElements(oldPos, newPos); [oldPos, newPos] = equilizeNoOfElements(oldPos, newPos);
[oldLabels, newLabels] = equilizeNoOfElements(oldLabels, newLabels); [oldLabels, newLabels] = equilizeNoOfElements(oldLabels, newLabels);
@ -105,5 +101,47 @@ export function getYAxisComponent(parent, constants, initData) {
); );
}); });
} }
}) },
xAxis: {
layerClass: 'x axis',
makeElements: function(data) {
return data.positions.map((position, i) =>
xLine(position, data.labels[i], this.constants.height,
{mode: this.constants.mode, pos: this.constants.pos})
);
},
animateElements: function(newData) {
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 translateVertLine(
line, newPos[i], oldPos[i]
);
});
}
}
}
export function getComponent(name, parent, constants, initData, getData) {
let config = componentConfigs[name];
Object.assign(config, {
parent: parent,
constants: constants,
data: initData,
getData: getData
})
return new ChartComponent(config);
} }

View File

@ -266,6 +266,40 @@ export function yLine(y, label, width, options={}) {
}); });
} }
export function xLine(x, label, height, options={}) {
if(!options.pos) options.pos = 'bottom';
if(!options.offset) options.offset = 0;
if(!options.mode) options.mode = 'span';
if(!options.stroke) options.stroke = BASE_LINE_COLOR;
if(!options.className) options.className = '';
// Draw X axis line in span/tick mode with optional label
// y2(span)
// |
// |
// x line |
// |
// |
// ---------------------+-- y2(tick)
// |
// y1
let y1 = height + AXIS_TICK_LENGTH;
let y2 = options.mode === 'span' ? -1 * AXIS_TICK_LENGTH : height;
if(options.mode === 'tick' && options.pos === 'top') {
// top axis ticks
y1 = -1 * AXIS_TICK_LENGTH;
y2 = 0;
}
return makeVertLine(x, label, y1, y2, {
stroke: options.stroke,
className: options.className,
lineType: options.lineType
});
}
export class AxisChartRenderer { export class AxisChartRenderer {
constructor(state) { constructor(state) {
this.refreshState(state); this.refreshState(state);
@ -284,43 +318,6 @@ export class AxisChartRenderer {
this.zeroLine = zeroLine; this.zeroLine = zeroLine;
} }
xLine(x, label, options={}) {
if(!options.pos) options.pos = 'bottom';
if(!options.offset) options.offset = 0;
if(!options.mode) options.mode = 'span';
if(!options.stroke) options.stroke = BASE_LINE_COLOR;
if(!options.className) options.className = '';
// Draw X axis line in span/tick mode with optional label
// y2(span)
// |
// |
// x line |
// |
// |
// ---------------------+-- y2(tick)
// |
// y1
let y1 = this.totalHeight + AXIS_TICK_LENGTH;
let y2 = options.mode === 'span' ? -1 * AXIS_TICK_LENGTH : this.totalHeight;
if(options.mode === 'tick' && options.pos === 'top') {
// top axis ticks
y1 = -1 * AXIS_TICK_LENGTH;
y2 = 0;
}
return makeVertLine(x, label, y1, y2, {
stroke: options.stroke,
className: options.className,
lineType: options.lineType
});
}
xMarker() {} xMarker() {}
yMarker(y, label, options={}) { yMarker(y, label, options={}) {
let labelSvg = createSVG('text', { let labelSvg = createSVG('text', {