Draw units independent of chart

This commit is contained in:
Prateeksha Singh 2018-01-02 12:34:45 +05:30
parent b3ca8f0819
commit f60fd25c00
12 changed files with 363 additions and 439 deletions

View File

@ -1029,13 +1029,13 @@ class ChartComponent {
make,
animate
}) {
this.layerClass = layerClass; // 'y axis'
this.layerClass = layerClass;
this.layerTransform = layerTransform;
this.make = make;
this.animate = animate;
this.layer = undefined;
this.store = []; //[[]] depends on indexed
this.store = [];
}
refresh(args) {}
@ -1058,8 +1058,6 @@ class ChartComponent {
}
}
// Indexed according to dataset
const REPLACE_ALL_NEW_DUR = 250;
@ -1491,19 +1489,14 @@ class AxisChart extends BaseChart {
// Y
s.datasetsLabels = this.data.datasets.map(d => d.name);
// s.yUnitValues = [[]]; indexed component
// s.yUnitValues = [[[12, 34, 68], [10, 5, 46]], [[20, 20, 20]]]; // array of indexed components
s.yUnitValues = s.datasets.map(d => d.values); // indexed component
this.setYAxis();
this.calcYUnits();
this.calcYMaximums();
// should be state
this.configUnits();
// temp
s.unitTypes = s.datasets.map(d => d.unitArgs ? d.unitArgs : this.state.unitArgs);
}
setYAxis() {
@ -1533,13 +1526,16 @@ class AxisChart extends BaseChart {
calcYUnits() {
let s = this.state;
s.yUnitPositions = s.yUnitValues.map(values =>
values.map(val => floatTwo(s.zeroLine - val * s.scaleMultiplier))
);
s.datasets.map(d => {
d.positions = d.values.map(val => floatTwo(s.yAxis.zeroLine - val * s.yAxis.scaleMultiplier));
});
}
calcYMaximums() {
let s = this.state;
s.yUnitMinimums = new Array(s.datasetLength).fill(9999);
s.datasets.map((d, i) => {
s.yUnitPositions[i].map((pos, j) => {
d.positions.map((pos, j) => {
if(pos < s.yUnitMinimums[j]) {
s.yUnitMinimums[j] = pos;
}
@ -1560,7 +1556,7 @@ class AxisChart extends BaseChart {
getAllYValues() {
// TODO: yMarkers, regions, sums, every Y value ever
return [].concat(...this.state.yUnitValues);
return [].concat(...this.state.datasets.map(d => d.values));
}
calcIntermedState() {
@ -1570,20 +1566,44 @@ class AxisChart extends BaseChart {
setupValues() {}
setupComponents() {
// temp : will be an indexedchartcomponent
// this.yAxisAux = new ChartComponent({
// layerClass: 'y axis aux',
// make: (renderer, positions, values) => {
// positions = [0, 70, 140, 270];
// values = [300, 200, 100, 0];
// return positions.map((position, i) => renderer.yLine(position, values[i], 'right'));
// },
// animate: () => {}
// });
this.setupYAxesComponents();
// TODO: rebind new units
// if(this.isNavigable) {
// this.bind_units(units_array);
// }
this.xAxis = new ChartComponent({
this.yMarkerLines = {};
this.xMarkerLines = {};
// Marker Regions
this.components = [
// temp
// this.yAxesAux,
...this.getYAxesComponents(),
this.getXAxisComponents(),
// this.yMarkerLines,
// this.xMarkerLines,
...this.getPathComponents(),
...this.getDataUnitsComponents(this.config),
];
}
getYAxesComponents() {
return [new ChartComponent({
layerClass: 'y axis',
make: () => {
let s = this.state;
return s.yAxis.positions.map((position, i) =>
this.renderer.yLine(position, s.yAxis.labels[i], {pos:'right'})
);
},
animate: () => {}
})];
}
getXAxisComponents() {
return new ChartComponent({
layerClass: 'x axis',
make: () => {
let s = this.state;
@ -1599,71 +1619,35 @@ class AxisChart extends BaseChart {
// });
// }
});
// this.dataUnits = new IndexedChartComponent({
// layerClass: 'dataset-units',
// make: (renderer, xPosSet, yPosSet, color, unitType,
// yValueSet, datasetIndex, noOfDatasets) => {;
// let unitSet = yPosSet.map((y, i) => {
// return renderer[unitType.type](
// xPosSet[i],
// y,
// unitType.args,
// color,
// i,
// datasetIndex,
// noOfDatasets
// );
// });
// if(this.type === 'line') {
// let pointsList = yPosSet.map((y, i) => (xPosSet[i] + ',' + y));
// let pointsStr = pointsList.join("L");
// unitSet.unshift(makePath("M"+pointsStr, 'line-graph-path', color));
// }
// return unitSet;
// },
// argsKeys: ['xUnitPositions', 'yUnitPositions',
// 'colors', 'unitTypes', 'yUnitValues'],
// animate: () => {}
// });
// TODO: rebind new units
// if(this.isNavigable) {
// this.bind_units(units_array);
// }
this.yMarkerLines = {};
this.xMarkerLines = {};
// Marker Regions
this.components = [
// temp
// this.yAxesAux,
...this.yAxesComponents,
this.xAxis,
// this.yMarkerLines,
// this.xMarkerLines,
// this.dataUnits,
];
}
setupYAxesComponents() {
this.yAxesComponents = [ new ChartComponent({
layerClass: 'y axis',
make: () => {
let s = this.state;
return s.yAxis.positions.map((position, i) =>
this.renderer.yLine(position, s.yAxis.labels[i], {pos:'right'})
);
},
animate: () => {}
})];
getDataUnitsComponents() {
return this.state.datasets.map((d, index) => {
return new ChartComponent({
layerClass: 'dataset-units dataset-' + index,
make: () => {
let d = this.state.datasets[index];
let unitType = this.unitArgs;
return d.positions.map((y, j) => {
return this.renderer[unitType.type](
this.state.xAxisPositions[j],
y,
unitType.args,
this.colors[index],
j,
index,
this.state.datasetLength
);
});
},
animate: () => {}
});
});
}
getPathComponents() {
return [];
}
refreshRenderer() {
@ -1707,7 +1691,7 @@ class BarChart extends AxisChart {
// }
configUnits() {
this.state.unitArgs = {
this.unitArgs = {
type: 'bar',
args: {
spaceWidth: this.state.unitWidth/2,
@ -1785,10 +1769,7 @@ class LineChart extends AxisChart {
configure(args) {
super.configure(args);
this.config.xAxisMode = args.xAxisMode || 'span';
// this.config.yAxisMode = args.yAxisMode || 'span';
// temp
this.config.yAxisMode = args.yAxisMode || 'tick';
this.config.yAxisMode = args.yAxisMode || 'span';
this.config.dotRadius = args.dotRadius || 4;
@ -1798,7 +1779,7 @@ class LineChart extends AxisChart {
}
configUnits() {
this.state.unitArgs = {
this.unitArgs = {
type: 'dot',
args: { radius: this.config.dotRadius }
};
@ -1810,78 +1791,49 @@ class LineChart extends AxisChart {
this.state.xOffset = 0;
}
// setupComponents() {
// super.setupComponents();
// this.paths = new IndexedChartComponent({
// layerClass: 'path',
// make: (renderer, xPosSet, yPosSet, color, unitType,
// yValueSet, datasetIndex, noOfDatasets) => {
// let pointsList = yPosSet.map((y, i) => (xPosSet[i] + ',' + y));
// let pointsStr = pointsList.join("L");
// return [makePath("M"+pointsStr, 'line-graph-path', color)];
// },
// argsKeys: ['xUnitPositions', 'yUnitPositions',
// 'colors', 'unitTypes', 'yUnitValues'],
// animate: () => {}
// });
// this.components.push(this.paths);
// }
make_path(d, x_positions, y_positions, color) {
let pointsList = y_positions.map((y, i) => (x_positions[i] + ',' + y));
let pointsStr = pointsList.join("L");
this.paths_groups[d.index].textContent = '';
d.path = makePath("M"+pointsStr, 'line-graph-path', color);
this.paths_groups[d.index].appendChild(d.path);
if(this.heatline) {
let gradient_id = makeGradient(this.svg_defs, color);
d.path.style.stroke = `url(#${gradient_id})`;
}
if(this.regionFill) {
this.fill_region_for_dataset(d, color, pointsStr);
getDataUnitsComponents(config) {
if(!config.showDots) {
return [];
} else {
return super.getDataUnitsComponents();
}
}
setupPreUnitLayers() {
// Path groups
this.paths_groups = [];
this.y.map((d, i) => {
this.paths_groups[i] = makeSVGGroup(
this.drawArea,
'path-group path-group-' + i
);
getPathComponents() {
return this.state.datasets.map((d, index) => {
return new ChartComponent({
layerClass: 'path dataset-path',
make: () => {
let d = this.state.datasets[index];
let color = this.colors[index];
let pointsList = d.positions.map((y, i) => (this.state.xAxisPositions[i] + ',' + y));
let pointsStr = pointsList.join("L");
let path = makePath("M"+pointsStr, 'line-graph-path', color);
// HeatLine
if(this.config.heatline) {
let gradient_id = makeGradient(this.svg_defs, color);
path.style.stroke = `url(#${gradient_id})`;
}
let components = [path];
// Region
if(this.config.regionFill) {
let gradient_id_region = makeGradient(this.svg_defs, color, true);
let zeroLine = this.state.yAxis.zeroLine;
let pathStr = "M" + `0,${zeroLine}L` + pointsStr + `L${this.width},${zeroLine}`;
components.push(makePath(pathStr, `region-fill`, 'none', `url(#${gradient_id_region})`));
}
return components;
},
animate: () => {}
});
});
}
makeDatasetUnits(x_values, y_values, color, dataset_index,
no_of_datasets, units_group, units_array, unit) {
if(this.showDots) {
super.makeDatasetUnits(x_values, y_values, color, dataset_index,
no_of_datasets, units_group, units_array, unit);
}
}
make_paths() {
this.y.map(d => {
this.make_path(d, this.xAxisPositions, d.yUnitPositions, d.color || this.colors[d.index]);
});
}
fill_region_for_dataset(d, color, pointsStr) {
let gradient_id = makeGradient(this.svg_defs, color, true);
let pathStr = "M" + `0,${this.zeroLine}L` + pointsStr + `L${this.width},${this.zeroLine}`;
d.regionPath = makePath(pathStr, `region-fill`, 'none', `url(#${gradient_id})`);
this.paths_groups[d.index].appendChild(d.regionPath);
}
}
class ScatterChart extends LineChart {
@ -1921,12 +1873,11 @@ class MultiAxisChart extends AxisChart {
setHorizontalMargin() {
let noOfLeftAxes = this.data.datasets.filter(d => d.axisPosition === 'left').length;
this.translateXLeft = (noOfLeftAxes) * Y_AXIS_MARGIN;
this.translateXLeft = (noOfLeftAxes) * Y_AXIS_MARGIN || Y_AXIS_MARGIN;
this.translateXRight = (this.data.datasets.length - noOfLeftAxes) * Y_AXIS_MARGIN || Y_AXIS_MARGIN;
}
prepareYAxis() {
this.state.yAxes = [];
let sets = this.state.datasets;
// let axesLeft = sets.filter(d => d.axisPosition === 'left');
// let axesRight = sets.filter(d => d.axisPosition === 'right');
@ -1936,12 +1887,10 @@ class MultiAxisChart extends AxisChart {
let leftCount = 0, rightCount = 0;
sets.forEach((d, i) => {
this.state.yAxes.push({
d.yAxis = {
position: d.axisPosition,
color: d.color,
dataValues: d.values,
index: d.axisPosition === 'left' ? leftCount++ : rightCount++
});
};
});
}
@ -1957,7 +1906,7 @@ class MultiAxisChart extends AxisChart {
// }
configUnits() {
this.state.unitArgs = {
this.unitArgs = {
type: 'bar',
args: {
spaceWidth: this.state.unitWidth/2,
@ -1966,41 +1915,75 @@ class MultiAxisChart extends AxisChart {
}
setYAxis() {
this.state.yAxes.map(yAxis => {
// console.log(yAxis);
this.calcYAxisParameters(yAxis, yAxis.dataValues, this.unitType === 'line');
// console.log(yAxis);
this.state.datasets.map(d => {
this.calcYAxisParameters(d.yAxis, d.values, this.unitType === 'line');
});
}
setupYAxesComponents() {
this.yAxesComponents = this.state.yAxes.map((e, i) => {
calcYUnits() {
this.state.datasets.map(d => {
d.positions = d.values.map(val => floatTwo(d.yAxis.zeroLine - val * d.yAxis.scaleMultiplier));
});
}
getYAxesComponents() {
return this.state.datasets.map((e, i) => {
return new ChartComponent({
layerClass: 'y axis y-axis-' + i,
make: () => {
let d = this.state.yAxes[i];
this.renderer.setZeroline(d.zeroline);
let axis = d.positions.map((position, j) =>
this.renderer.yLine(position, d.labels[j], {
pos: d.position,
mode: 'tick',
offset: d.index * Y_AXIS_MARGIN,
stroke: this.colors[i]
})
let yAxis = this.state.datasets[i].yAxis;
this.renderer.setZeroline(yAxis.zeroline);
let options = {
pos: yAxis.position,
mode: 'tick',
offset: yAxis.index * Y_AXIS_MARGIN,
stroke: this.colors[i]
};
let yAxisLines = yAxis.positions.map((position, j) =>
this.renderer.yLine(position, yAxis.labels[j], options)
);
let guidePos = d.position === 'left'
? -1 * d.index * Y_AXIS_MARGIN
: this.width + d.index * Y_AXIS_MARGIN;
let guidePos = yAxis.position === 'left'
? -1 * yAxis.index * Y_AXIS_MARGIN
: this.width + yAxis.index * Y_AXIS_MARGIN;
axis.push(this.renderer.xLine(guidePos, '', {
yAxisLines.push(this.renderer.xLine(guidePos, '', {
pos:'top',
mode: 'span',
stroke: this.colors[i],
className: 'y-axis-guide'
}));
return axis;
return yAxisLines;
},
animate: () => {}
});
});
}
getDataUnitsComponents() {
return this.state.datasets.map((d, index) => {
return new ChartComponent({
layerClass: 'dataset-units dataset-' + index,
make: () => {
let d = this.state.datasets[index];
let unitType = this.unitArgs;
// the only difference, should be tied to datasets or default
this.renderer.setZeroline(d.yAxis.zeroLine);
return d.positions.map((y, j) => {
return this.renderer[unitType.type](
this.state.xAxisPositions[j],
y,
unitType.args,
this.colors[index],
j,
index,
this.state.datasetLength
);
});
},
animate: () => {}
});

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
.chart-container{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}.chart-container .multiaxis-chart .line-horizontal,.chart-container .multiaxis-chart .y-axis-guide{stroke-width:2px}.chart-container .graph-focus-margin{margin:0 5%}.chart-container>.title{margin-top:25px;margin-left:25px;text-align:left;font-weight:400;font-size:12px;color:#6c7680}.chart-container .graphics{margin-top:10px;padding-top:10px;padding-bottom:10px;position:relative}.chart-container .graph-stats-group{-ms-flex-pack:distribute;-webkit-box-flex:1;-ms-flex:1;flex:1}.chart-container .graph-stats-container,.chart-container .graph-stats-group{display:-webkit-box;display:-ms-flexbox;display:flex;justify-content:space-around}.chart-container .graph-stats-container{-ms-flex-pack:distribute;padding-top:10px}.chart-container .graph-stats-container .stats{padding-bottom:15px}.chart-container .graph-stats-container .stats-title{color:#8d99a6}.chart-container .graph-stats-container .stats-value{font-size:20px;font-weight:300}.chart-container .graph-stats-container .stats-description{font-size:12px;color:#8d99a6}.chart-container .graph-stats-container .graph-data .stats-value{color:#98d85b}.chart-container .axis,.chart-container .chart-label{fill:#555b51}.chart-container .axis line,.chart-container .chart-label line{stroke:#dadada}.chart-container .percentage-graph .progress{margin-bottom:0}.chart-container .dataset-units circle{stroke:#fff;stroke-width:2}.chart-container .dataset-units path,.chart-container .path-group path{fill:none;stroke-opacity:1;stroke-width:2px}.chart-container line.dashed{stroke-dasharray:5,3}.chart-container .axis-line .specific-value{text-anchor:start}.chart-container .axis-line .y-line{text-anchor:end}.chart-container .axis-line .x-line{text-anchor:middle}.chart-container .progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.chart-container .progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#36414c;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;transition:width .6s ease}.chart-container .graph-svg-tip{position:absolute;z-index:1;padding:10px;font-size:12px;color:#959da5;text-align:center;background:rgba(0,0,0,.8);border-radius:3px}.chart-container .graph-svg-tip ol,.chart-container .graph-svg-tip ul{padding-left:0;display:-webkit-box;display:-ms-flexbox;display:flex}.chart-container .graph-svg-tip ul.data-point-list li{min-width:90px;-webkit-box-flex:1;-ms-flex:1;flex:1;font-weight:600}.chart-container .graph-svg-tip strong{color:#dfe2e5;font-weight:600}.chart-container .graph-svg-tip .svg-pointer{position:absolute;height:5px;margin:0 0 0 -5px;content:" ";border:5px solid transparent;border-top-color:rgba(0,0,0,.8)}.chart-container .graph-svg-tip.comparison{padding:0;text-align:left;pointer-events:none}.chart-container .graph-svg-tip.comparison .title{display:block;padding:10px;margin:0;font-weight:600;line-height:1;pointer-events:none}.chart-container .graph-svg-tip.comparison ul{margin:0;white-space:nowrap;list-style:none}.chart-container .graph-svg-tip.comparison li{display:inline-block;padding:5px 10px}.chart-container .indicator,.chart-container .indicator-right{background:none;font-size:12px;vertical-align:middle;font-weight:700;color:#6c7680}.chart-container .indicator i{content:"";display:inline-block;height:8px;width:8px;border-radius:8px}.chart-container .indicator:before,.chart-container .indicator i{margin:0 4px 0 0}.chart-container .indicator-right:after{margin:0 0 0 4px}
.chart-container{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}.chart-container .graph-focus-margin{margin:0 5%}.chart-container>.title{margin-top:25px;margin-left:25px;text-align:left;font-weight:400;font-size:12px;color:#6c7680}.chart-container .graphics{margin-top:10px;padding-top:10px;padding-bottom:10px;position:relative}.chart-container .graph-stats-group{-ms-flex-pack:distribute;-webkit-box-flex:1;-ms-flex:1;flex:1}.chart-container .graph-stats-container,.chart-container .graph-stats-group{display:-webkit-box;display:-ms-flexbox;display:flex;justify-content:space-around}.chart-container .graph-stats-container{-ms-flex-pack:distribute;padding-top:10px}.chart-container .graph-stats-container .stats{padding-bottom:15px}.chart-container .graph-stats-container .stats-title{color:#8d99a6}.chart-container .graph-stats-container .stats-value{font-size:20px;font-weight:300}.chart-container .graph-stats-container .stats-description{font-size:12px;color:#8d99a6}.chart-container .graph-stats-container .graph-data .stats-value{color:#98d85b}.chart-container .axis,.chart-container .chart-label{fill:#555b51}.chart-container .axis line,.chart-container .chart-label line{stroke:#dadada}.chart-container .percentage-graph .progress{margin-bottom:0}.chart-container .dataset-units circle{stroke:#fff;stroke-width:2}.chart-container .dataset-units path{fill:none;stroke-opacity:1;stroke-width:2px}.chart-container .dataset-path,.chart-container .multiaxis-chart .line-horizontal,.chart-container .multiaxis-chart .y-axis-guide{stroke-width:2px}.chart-container .path-group path{fill:none;stroke-opacity:1;stroke-width:2px}.chart-container line.dashed{stroke-dasharray:5,3}.chart-container .axis-line .specific-value{text-anchor:start}.chart-container .axis-line .y-line{text-anchor:end}.chart-container .axis-line .x-line{text-anchor:middle}.chart-container .progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.chart-container .progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#36414c;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;transition:width .6s ease}.chart-container .graph-svg-tip{position:absolute;z-index:1;padding:10px;font-size:12px;color:#959da5;text-align:center;background:rgba(0,0,0,.8);border-radius:3px}.chart-container .graph-svg-tip ol,.chart-container .graph-svg-tip ul{padding-left:0;display:-webkit-box;display:-ms-flexbox;display:flex}.chart-container .graph-svg-tip ul.data-point-list li{min-width:90px;-webkit-box-flex:1;-ms-flex:1;flex:1;font-weight:600}.chart-container .graph-svg-tip strong{color:#dfe2e5;font-weight:600}.chart-container .graph-svg-tip .svg-pointer{position:absolute;height:5px;margin:0 0 0 -5px;content:" ";border:5px solid transparent;border-top-color:rgba(0,0,0,.8)}.chart-container .graph-svg-tip.comparison{padding:0;text-align:left;pointer-events:none}.chart-container .graph-svg-tip.comparison .title{display:block;padding:10px;margin:0;font-weight:600;line-height:1;pointer-events:none}.chart-container .graph-svg-tip.comparison ul{margin:0;white-space:nowrap;list-style:none}.chart-container .graph-svg-tip.comparison li{display:inline-block;padding:5px 10px}.chart-container .indicator,.chart-container .indicator-right{background:none;font-size:12px;vertical-align:middle;font-weight:700;color:#6c7680}.chart-container .indicator i{content:"";display:inline-block;height:8px;width:8px;border-radius:8px}.chart-container .indicator:before,.chart-container .indicator i{margin:0 4px 0 0}.chart-container .indicator-right:after{margin:0 0 0 4px}

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

@ -92,19 +92,14 @@ export default class AxisChart extends BaseChart {
// Y
s.datasetsLabels = this.data.datasets.map(d => d.name);
// s.yUnitValues = [[]]; indexed component
// s.yUnitValues = [[[12, 34, 68], [10, 5, 46]], [[20, 20, 20]]]; // array of indexed components
s.yUnitValues = s.datasets.map(d => d.values); // indexed component
this.setYAxis();
this.calcYUnits();
this.calcYMaximums();
// should be state
this.configUnits();
// temp
s.unitTypes = s.datasets.map(d => d.unitArgs ? d.unitArgs : this.state.unitArgs);
}
setYAxis() {
@ -134,13 +129,16 @@ export default class AxisChart extends BaseChart {
calcYUnits() {
let s = this.state;
s.yUnitPositions = s.yUnitValues.map(values =>
values.map(val => floatTwo(s.zeroLine - val * s.scaleMultiplier))
);
s.datasets.map(d => {
d.positions = d.values.map(val => floatTwo(s.yAxis.zeroLine - val * s.yAxis.scaleMultiplier));
});
}
calcYMaximums() {
let s = this.state;
s.yUnitMinimums = new Array(s.datasetLength).fill(9999);
s.datasets.map((d, i) => {
s.yUnitPositions[i].map((pos, j) => {
d.positions.map((pos, j) => {
if(pos < s.yUnitMinimums[j]) {
s.yUnitMinimums[j] = pos;
}
@ -161,7 +159,7 @@ export default class AxisChart extends BaseChart {
getAllYValues() {
// TODO: yMarkers, regions, sums, every Y value ever
return [].concat(...this.state.yUnitValues);
return [].concat(...this.state.datasets.map(d => d.values));
}
calcIntermedState() {
@ -171,20 +169,44 @@ export default class AxisChart extends BaseChart {
setupValues() {}
setupComponents() {
// temp : will be an indexedchartcomponent
// this.yAxisAux = new ChartComponent({
// layerClass: 'y axis aux',
// make: (renderer, positions, values) => {
// positions = [0, 70, 140, 270];
// values = [300, 200, 100, 0];
// return positions.map((position, i) => renderer.yLine(position, values[i], 'right'));
// },
// animate: () => {}
// });
this.setupYAxesComponents();
// TODO: rebind new units
// if(this.isNavigable) {
// this.bind_units(units_array);
// }
this.xAxis = new ChartComponent({
this.yMarkerLines = {};
this.xMarkerLines = {};
// Marker Regions
this.components = [
// temp
// this.yAxesAux,
...this.getYAxesComponents(),
this.getXAxisComponents(),
// this.yMarkerLines,
// this.xMarkerLines,
...this.getPathComponents(),
...this.getDataUnitsComponents(this.config),
];
}
getYAxesComponents() {
return [new ChartComponent({
layerClass: 'y axis',
make: () => {
let s = this.state;
return s.yAxis.positions.map((position, i) =>
this.renderer.yLine(position, s.yAxis.labels[i], {pos:'right'})
);
},
animate: () => {}
})];
}
getXAxisComponents() {
return new ChartComponent({
layerClass: 'x axis',
make: () => {
let s = this.state;
@ -200,71 +222,35 @@ export default class AxisChart extends BaseChart {
// });
// }
});
// this.dataUnits = new IndexedChartComponent({
// layerClass: 'dataset-units',
// make: (renderer, xPosSet, yPosSet, color, unitType,
// yValueSet, datasetIndex, noOfDatasets) => {;
// let unitSet = yPosSet.map((y, i) => {
// return renderer[unitType.type](
// xPosSet[i],
// y,
// unitType.args,
// color,
// i,
// datasetIndex,
// noOfDatasets
// );
// });
// if(this.type === 'line') {
// let pointsList = yPosSet.map((y, i) => (xPosSet[i] + ',' + y));
// let pointsStr = pointsList.join("L");
// unitSet.unshift(makePath("M"+pointsStr, 'line-graph-path', color));
// }
// return unitSet;
// },
// argsKeys: ['xUnitPositions', 'yUnitPositions',
// 'colors', 'unitTypes', 'yUnitValues'],
// animate: () => {}
// });
// TODO: rebind new units
// if(this.isNavigable) {
// this.bind_units(units_array);
// }
this.yMarkerLines = {};
this.xMarkerLines = {};
// Marker Regions
this.components = [
// temp
// this.yAxesAux,
...this.yAxesComponents,
this.xAxis,
// this.yMarkerLines,
// this.xMarkerLines,
// this.dataUnits,
];
}
setupYAxesComponents() {
this.yAxesComponents = [ new ChartComponent({
layerClass: 'y axis',
make: () => {
let s = this.state;
return s.yAxis.positions.map((position, i) =>
this.renderer.yLine(position, s.yAxis.labels[i], {pos:'right'})
);
},
animate: () => {}
})];
getDataUnitsComponents() {
return this.state.datasets.map((d, index) => {
return new ChartComponent({
layerClass: 'dataset-units dataset-' + index,
make: () => {
let d = this.state.datasets[index];
let unitType = this.unitArgs;
return d.positions.map((y, j) => {
return this.renderer[unitType.type](
this.state.xAxisPositions[j],
y,
unitType.args,
this.colors[index],
j,
index,
this.state.datasetLength
);
});
},
animate: () => {}
});
});
}
getPathComponents() {
return [];
}
refreshRenderer() {

View File

@ -19,7 +19,7 @@ export default class BarChart extends AxisChart {
// }
configUnits() {
this.state.unitArgs = {
this.unitArgs = {
type: 'bar',
args: {
spaceWidth: this.state.unitWidth/2,

View File

@ -1,4 +1,5 @@
import AxisChart from './AxisChart';
import { ChartComponent } from '../objects/ChartComponent';
import { makeSVGGroup, makePath, makeGradient } from '../utils/draw';
export default class LineChart extends AxisChart {
@ -16,10 +17,7 @@ export default class LineChart extends AxisChart {
configure(args) {
super.configure(args);
this.config.xAxisMode = args.xAxisMode || 'span';
// this.config.yAxisMode = args.yAxisMode || 'span';
// temp
this.config.yAxisMode = args.yAxisMode || 'tick';
this.config.yAxisMode = args.yAxisMode || 'span';
this.config.dotRadius = args.dotRadius || 4;
@ -29,7 +27,7 @@ export default class LineChart extends AxisChart {
}
configUnits() {
this.state.unitArgs = {
this.unitArgs = {
type: 'dot',
args: { radius: this.config.dotRadius }
};
@ -41,76 +39,47 @@ export default class LineChart extends AxisChart {
this.state.xOffset = 0;
}
// setupComponents() {
// super.setupComponents();
// this.paths = new IndexedChartComponent({
// layerClass: 'path',
// make: (renderer, xPosSet, yPosSet, color, unitType,
// yValueSet, datasetIndex, noOfDatasets) => {
// let pointsList = yPosSet.map((y, i) => (xPosSet[i] + ',' + y));
// let pointsStr = pointsList.join("L");
// return [makePath("M"+pointsStr, 'line-graph-path', color)];
// },
// argsKeys: ['xUnitPositions', 'yUnitPositions',
// 'colors', 'unitTypes', 'yUnitValues'],
// animate: () => {}
// });
// this.components.push(this.paths);
// }
make_path(d, x_positions, y_positions, color) {
let pointsList = y_positions.map((y, i) => (x_positions[i] + ',' + y));
let pointsStr = pointsList.join("L");
this.paths_groups[d.index].textContent = '';
d.path = makePath("M"+pointsStr, 'line-graph-path', color);
this.paths_groups[d.index].appendChild(d.path);
if(this.heatline) {
let gradient_id = makeGradient(this.svg_defs, color);
d.path.style.stroke = `url(#${gradient_id})`;
}
if(this.regionFill) {
this.fill_region_for_dataset(d, color, pointsStr);
getDataUnitsComponents(config) {
if(!config.showDots) {
return [];
} else {
return super.getDataUnitsComponents();
}
}
setupPreUnitLayers() {
// Path groups
this.paths_groups = [];
this.y.map((d, i) => {
this.paths_groups[i] = makeSVGGroup(
this.drawArea,
'path-group path-group-' + i
);
getPathComponents() {
return this.state.datasets.map((d, index) => {
return new ChartComponent({
layerClass: 'path dataset-path',
make: () => {
let d = this.state.datasets[index];
let color = this.colors[index];
let pointsList = d.positions.map((y, i) => (this.state.xAxisPositions[i] + ',' + y));
let pointsStr = pointsList.join("L");
let path = makePath("M"+pointsStr, 'line-graph-path', color);
// HeatLine
if(this.config.heatline) {
let gradient_id = makeGradient(this.svg_defs, color);
path.style.stroke = `url(#${gradient_id})`;
}
let components = [path];
// Region
if(this.config.regionFill) {
let gradient_id_region = makeGradient(this.svg_defs, color, true);
let zeroLine = this.state.yAxis.zeroLine;
let pathStr = "M" + `0,${zeroLine}L` + pointsStr + `L${this.width},${zeroLine}`;
components.push(makePath(pathStr, `region-fill`, 'none', `url(#${gradient_id_region})`));
}
return components;
},
animate: () => {}
});
});
}
makeDatasetUnits(x_values, y_values, color, dataset_index,
no_of_datasets, units_group, units_array, unit) {
if(this.showDots) {
super.makeDatasetUnits(x_values, y_values, color, dataset_index,
no_of_datasets, units_group, units_array, unit);
}
}
make_paths() {
this.y.map(d => {
this.make_path(d, this.xAxisPositions, d.yUnitPositions, d.color || this.colors[d.index]);
});
}
fill_region_for_dataset(d, color, pointsStr) {
let gradient_id = makeGradient(this.svg_defs, color, true);
let pathStr = "M" + `0,${this.zeroLine}L` + pointsStr + `L${this.width},${this.zeroLine}`;
d.regionPath = makePath(pathStr, `region-fill`, 'none', `url(#${gradient_id})`);
this.paths_groups[d.index].appendChild(d.regionPath);
}
}

View File

@ -1,6 +1,7 @@
import AxisChart from './AxisChart';
import { Y_AXIS_MARGIN } from '../utils/margins';
import { ChartComponent } from '../objects/ChartComponent';
import { floatTwo } from '../utils/helpers';
export default class MultiAxisChart extends AxisChart {
constructor(args) {
@ -12,12 +13,11 @@ export default class MultiAxisChart extends AxisChart {
setHorizontalMargin() {
let noOfLeftAxes = this.data.datasets.filter(d => d.axisPosition === 'left').length;
this.translateXLeft = (noOfLeftAxes) * Y_AXIS_MARGIN;
this.translateXLeft = (noOfLeftAxes) * Y_AXIS_MARGIN || Y_AXIS_MARGIN;
this.translateXRight = (this.data.datasets.length - noOfLeftAxes) * Y_AXIS_MARGIN || Y_AXIS_MARGIN;
}
prepareYAxis() {
this.state.yAxes = [];
let sets = this.state.datasets;
// let axesLeft = sets.filter(d => d.axisPosition === 'left');
// let axesRight = sets.filter(d => d.axisPosition === 'right');
@ -27,12 +27,10 @@ export default class MultiAxisChart extends AxisChart {
let leftCount = 0, rightCount = 0;
sets.forEach((d, i) => {
this.state.yAxes.push({
d.yAxis = {
position: d.axisPosition,
color: d.color,
dataValues: d.values,
index: d.axisPosition === 'left' ? leftCount++ : rightCount++
});
};
});
}
@ -48,7 +46,7 @@ export default class MultiAxisChart extends AxisChart {
// }
configUnits() {
this.state.unitArgs = {
this.unitArgs = {
type: 'bar',
args: {
spaceWidth: this.state.unitWidth/2,
@ -57,41 +55,75 @@ export default class MultiAxisChart extends AxisChart {
}
setYAxis() {
this.state.yAxes.map(yAxis => {
// console.log(yAxis);
this.calcYAxisParameters(yAxis, yAxis.dataValues, this.unitType === 'line');
// console.log(yAxis);
this.state.datasets.map(d => {
this.calcYAxisParameters(d.yAxis, d.values, this.unitType === 'line');
});
}
setupYAxesComponents() {
this.yAxesComponents = this.state.yAxes.map((e, i) => {
calcYUnits() {
this.state.datasets.map(d => {
d.positions = d.values.map(val => floatTwo(d.yAxis.zeroLine - val * d.yAxis.scaleMultiplier));
});
}
getYAxesComponents() {
return this.state.datasets.map((e, i) => {
return new ChartComponent({
layerClass: 'y axis y-axis-' + i,
make: () => {
let d = this.state.yAxes[i];
this.renderer.setZeroline(d.zeroline);
let axis = d.positions.map((position, j) =>
this.renderer.yLine(position, d.labels[j], {
pos: d.position,
mode: 'tick',
offset: d.index * Y_AXIS_MARGIN,
stroke: this.colors[i]
})
let yAxis = this.state.datasets[i].yAxis;
this.renderer.setZeroline(yAxis.zeroline);
let options = {
pos: yAxis.position,
mode: 'tick',
offset: yAxis.index * Y_AXIS_MARGIN,
stroke: this.colors[i]
};
let yAxisLines = yAxis.positions.map((position, j) =>
this.renderer.yLine(position, yAxis.labels[j], options)
);
let guidePos = d.position === 'left'
? -1 * d.index * Y_AXIS_MARGIN
: this.width + d.index * Y_AXIS_MARGIN;
let guidePos = yAxis.position === 'left'
? -1 * yAxis.index * Y_AXIS_MARGIN
: this.width + yAxis.index * Y_AXIS_MARGIN;
axis.push(this.renderer.xLine(guidePos, '', {
yAxisLines.push(this.renderer.xLine(guidePos, '', {
pos:'top',
mode: 'span',
stroke: this.colors[i],
className: 'y-axis-guide'
}));
return axis;
return yAxisLines;
},
animate: () => {}
});
});
}
getDataUnitsComponents() {
return this.state.datasets.map((d, index) => {
return new ChartComponent({
layerClass: 'dataset-units dataset-' + index,
make: () => {
let d = this.state.datasets[index];
let unitType = this.unitArgs;
// the only difference, should be tied to datasets or default
this.renderer.setZeroline(d.yAxis.zeroLine);
return d.positions.map((y, j) => {
return this.renderer[unitType.type](
this.state.xAxisPositions[j],
y,
unitType.args,
this.colors[index],
j,
index,
this.state.datasetLength
);
});
},
animate: () => {}
});

View File

@ -7,13 +7,13 @@ export class ChartComponent {
make,
animate
}) {
this.layerClass = layerClass; // 'y axis'
this.layerClass = layerClass;
this.layerTransform = layerTransform;
this.make = make;
this.animate = animate;
this.layer = undefined;
this.store = []; //[[]] depends on indexed
this.store = [];
}
refresh(args) {}
@ -35,51 +35,3 @@ export class ChartComponent {
this.layer = makeSVGGroup(this.parent, this.layerClass, this.layerTransform);
}
}
// Indexed according to dataset
export class IndexedChartComponent extends ChartComponent {
constructor(args) {
super(args);
this.stores = [];
}
refresh(args) {
super.refresh(args);
this.totalIndices = this.chartState[this.argsKeys[0]].length;
}
makeLayer() {
super.makeLayer();
this.layers = [];
for(var i = 0; i < this.totalIndices; i++) {
this.layers[i] = makeSVGGroup(this.layer, this.layerClass + '-' + i);
}
}
addLayer() {}
render() {
let datasetArrays = this.argsKeys.map(key => this.chartState[key]);
// datasetArrays will have something like an array of X positions sets
// datasetArrays = [
// xUnitPositions, yUnitPositions, colors, unitTypes, yUnitValues
// ]
// where xUnitPositions = [[0,0,0], [1,1,1]]
// i.e.: [ [[0,0,0], [1,1,1]], ... ]
for(var i = 0; i < this.totalIndices; i++) {
let args = datasetArrays.map(datasetArray => datasetArray[i]);
args.push(i);
args.push(this.totalIndices);
this.stores.push(this.make(...args));
let layer = this.layers[i];
layer.textContent = '';
this.stores[i].forEach(element => {
layer.appendChild(element);
});
}
}
}

View File

@ -4,12 +4,6 @@
"Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell",
"Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
.multiaxis-chart {
.line-horizontal, .y-axis-guide {
stroke-width: 2px;
}
}
.graph-focus-margin {
margin: 0px 5%;
}
@ -81,6 +75,14 @@
stroke-width: 2px;
}
}
.multiaxis-chart {
.line-horizontal, .y-axis-guide {
stroke-width: 2px;
}
}
.dataset-path {
stroke-width: 2px;
}
.path-group {
path {
fill: none;