|
|
@@ -232,9 +232,14 @@ function getStringWidth(string, charWidth) { |
|
|
|
return (string+"").length * charWidth; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// observe(s.yAxis, ['yAxis', 'barGraph']) |
|
|
|
|
|
|
|
function equilizeNoOfElements(array1, array2, |
|
|
|
extra_count=array2.length - array1.length) { |
|
|
|
|
|
|
|
// Doesn't work if either has zero elements. |
|
|
|
if(extra_count > 0) { |
|
|
|
array1 = fillArray(array1, extra_count); |
|
|
|
} else { |
|
|
@@ -305,6 +310,22 @@ function animateRegion(rectGroup, newY1, newY2, oldY2) { |
|
|
|
return [rectAnim, groupAnim]; |
|
|
|
} |
|
|
|
|
|
|
|
/* |
|
|
|
|
|
|
|
<filter id="glow" x="-10%" y="-10%" width="120%" height="120%"> |
|
|
|
<feGaussianBlur stdDeviation="0.5 0.5" result="glow"></feGaussianBlur> |
|
|
|
<feMerge> |
|
|
|
<feMergeNode in="glow"></feMergeNode> |
|
|
|
<feMergeNode in="glow"></feMergeNode> |
|
|
|
<feMergeNode in="glow"></feMergeNode> |
|
|
|
</feMerge> |
|
|
|
</filter> |
|
|
|
|
|
|
|
filter: url(#glow); |
|
|
|
fill: #fff; |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
const AXIS_TICK_LENGTH = 6; |
|
|
|
const LABEL_MARGIN = 4; |
|
|
|
const FONT_SIZE = 10; |
|
|
@@ -578,7 +599,6 @@ function xLine(x, label, height, options={}) { |
|
|
|
} |
|
|
|
|
|
|
|
function yMarker(y, label, width, options={}) { |
|
|
|
// console.log(y - FONT_SIZE - 2, ); |
|
|
|
let labelSvg = createSVG('text', { |
|
|
|
className: 'chart-label', |
|
|
|
x: width - getStringWidth(label, 5) - LABEL_MARGIN, |
|
|
@@ -994,6 +1014,7 @@ class BaseChart { |
|
|
|
|
|
|
|
this.setupComponents(); |
|
|
|
|
|
|
|
this.components.forEach(c => c.setup(this.drawArea)); // or c.build() |
|
|
|
this.components.forEach(c => c.make()); // or c.build() |
|
|
|
this.renderLegend(); |
|
|
|
|
|
|
@@ -1170,6 +1191,9 @@ function dataPrep(data, type) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Set labels |
|
|
|
// |
|
|
|
|
|
|
|
// Set index |
|
|
|
d.index = i; |
|
|
|
|
|
|
@@ -1180,7 +1204,9 @@ function dataPrep(data, type) { |
|
|
|
}); |
|
|
|
|
|
|
|
// Markers |
|
|
|
|
|
|
|
// Regions |
|
|
|
// Set start and end |
|
|
|
|
|
|
|
return data; |
|
|
|
} |
|
|
@@ -1189,17 +1215,13 @@ class ChartComponent$1 { |
|
|
|
constructor({ |
|
|
|
layerClass = '', |
|
|
|
layerTransform = '', |
|
|
|
parent, |
|
|
|
constants, |
|
|
|
data, |
|
|
|
|
|
|
|
// called on update |
|
|
|
getData, |
|
|
|
makeElements, |
|
|
|
postMake, |
|
|
|
getData, |
|
|
|
animateElements |
|
|
|
}) { |
|
|
|
this.parent = parent; |
|
|
|
this.layerTransform = layerTransform; |
|
|
|
this.constants = constants; |
|
|
|
|
|
|
@@ -1211,20 +1233,20 @@ class ChartComponent$1 { |
|
|
|
|
|
|
|
this.store = []; |
|
|
|
|
|
|
|
layerClass = typeof(layerClass) === 'function' |
|
|
|
this.layerClass = typeof(layerClass) === 'function' |
|
|
|
? layerClass() : layerClass; |
|
|
|
|
|
|
|
this.layer = makeSVGGroup(this.parent, layerClass, this.layerTransform); |
|
|
|
|
|
|
|
this.data = data; |
|
|
|
|
|
|
|
this.make(); |
|
|
|
this.refresh(); |
|
|
|
} |
|
|
|
|
|
|
|
refresh(data) { |
|
|
|
this.data = data || this.getData(); |
|
|
|
} |
|
|
|
|
|
|
|
setup(parent) { |
|
|
|
this.layer = makeSVGGroup(parent, this.layerClass, this.layerTransform); |
|
|
|
} |
|
|
|
|
|
|
|
make() { |
|
|
|
this.preMake && this.preMake(); |
|
|
|
this.render(this.data); |
|
|
@@ -1473,12 +1495,10 @@ let componentConfigs = { |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
function getComponent(name, parent, constants, initData, getData) { |
|
|
|
function getComponent(name, constants, getData) { |
|
|
|
let config = componentConfigs[name]; |
|
|
|
Object.assign(config, { |
|
|
|
parent: parent, |
|
|
|
constants: constants, |
|
|
|
data: initData, |
|
|
|
getData: getData |
|
|
|
}); |
|
|
|
return new ChartComponent$1(config); |
|
|
@@ -1818,24 +1838,43 @@ class AxisChart extends BaseChart { |
|
|
|
configure(args) { |
|
|
|
super.configure(); |
|
|
|
|
|
|
|
// TODO: set in options and use |
|
|
|
|
|
|
|
this.config.xAxisMode = args.xAxisMode; |
|
|
|
this.config.yAxisMode = args.yAxisMode; |
|
|
|
} |
|
|
|
|
|
|
|
setTrivialState() { |
|
|
|
// Define data and stuff |
|
|
|
let xLabels = this.data.labels; |
|
|
|
let yTempPos = getRealIntervals(this.height, 4, 0, 0); |
|
|
|
|
|
|
|
this.state = { |
|
|
|
xAxis: { |
|
|
|
positions: [], |
|
|
|
labels: xLabels, |
|
|
|
labels: [], |
|
|
|
}, |
|
|
|
yAxis: { |
|
|
|
positions: [], |
|
|
|
labels: [], |
|
|
|
positions: yTempPos, |
|
|
|
labels: yTempPos.map(d => ""), |
|
|
|
}, |
|
|
|
datasetLength: xLabels.length |
|
|
|
yRegions: [ |
|
|
|
{ |
|
|
|
start: this.height, |
|
|
|
end: this.height, |
|
|
|
label: '' |
|
|
|
} |
|
|
|
], |
|
|
|
yMarkers: [ |
|
|
|
{ |
|
|
|
position: this.height, |
|
|
|
label: '' |
|
|
|
} |
|
|
|
] |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
this.calcWidth(); |
|
|
|
this.calcXPositions(); |
|
|
|
this.setObservers(); |
|
|
|
} |
|
|
|
|
|
|
@@ -1855,11 +1894,8 @@ class AxisChart extends BaseChart { |
|
|
|
} |
|
|
|
|
|
|
|
calc() { |
|
|
|
let s = this.state; |
|
|
|
|
|
|
|
this.calcXPositions(); |
|
|
|
|
|
|
|
s.datasetsLabels = this.data.datasets.map(d => d.name); |
|
|
|
this.setYAxis(); |
|
|
|
this.calcYUnits(); |
|
|
|
this.calcYMaximums(); |
|
|
@@ -1874,12 +1910,16 @@ class AxisChart extends BaseChart { |
|
|
|
|
|
|
|
calcXPositions() { |
|
|
|
let s = this.state; |
|
|
|
this.setUnitWidthAndXOffset(); |
|
|
|
s.xAxisPositions = s.xAxis.labels.map((d, i) => |
|
|
|
s.xAxis.labels = this.data.labels; |
|
|
|
s.datasetLength = this.data.labels.length; |
|
|
|
|
|
|
|
s.unitWidth = this.width/(s.datasetLength); |
|
|
|
// Default, as per bar, and mixed. Only line will be a special case |
|
|
|
s.xOffset = s.unitWidth/2; |
|
|
|
|
|
|
|
s.xAxis.positions = s.xAxis.labels.map((d, i) => |
|
|
|
floatTwo(s.xOffset + i * s.unitWidth) |
|
|
|
); |
|
|
|
|
|
|
|
s.xUnitPositions = new Array(this.data.datasets.length).fill(s.xAxisPositions); |
|
|
|
} |
|
|
|
|
|
|
|
calcYAxisParameters(yAxis, dataValues, withMinimum = 'false') { |
|
|
@@ -1931,14 +1971,14 @@ class AxisChart extends BaseChart { |
|
|
|
calcYRegions() { |
|
|
|
let s = this.state; |
|
|
|
if(this.data.yMarkers) { |
|
|
|
this.data.yMarkers = this.data.yMarkers.map(d => { |
|
|
|
this.state.yMarkers = this.data.yMarkers.map(d => { |
|
|
|
d.position = floatTwo(s.yAxis.zeroLine - d.value * s.yAxis.scaleMultiplier); |
|
|
|
d.label += ': ' + d.value; |
|
|
|
return d; |
|
|
|
}); |
|
|
|
} |
|
|
|
if(this.data.yRegions) { |
|
|
|
this.data.yRegions = this.data.yRegions.map(d => { |
|
|
|
this.state.yRegions = this.data.yRegions.map(d => { |
|
|
|
if(d.end < d.start) { |
|
|
|
[d.start, d.end] = [d.end, start]; |
|
|
|
} |
|
|
@@ -1949,12 +1989,6 @@ class AxisChart extends BaseChart { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Default, as per bar, and mixed. Only line will be a special case |
|
|
|
setUnitWidthAndXOffset() { |
|
|
|
this.state.unitWidth = this.width/(this.state.datasetLength); |
|
|
|
this.state.xOffset = this.state.unitWidth/2; |
|
|
|
} |
|
|
|
|
|
|
|
getAllYValues() { |
|
|
|
// TODO: yMarkers, regions, sums, every Y value ever |
|
|
|
|
|
|
@@ -1976,83 +2010,36 @@ class AxisChart extends BaseChart { |
|
|
|
this.componentConfigs = [ |
|
|
|
[ |
|
|
|
'yAxis', |
|
|
|
this.drawArea, |
|
|
|
{ |
|
|
|
mode: this.yAxisMode, |
|
|
|
width: this.width, |
|
|
|
// pos: 'right' |
|
|
|
}, |
|
|
|
{ |
|
|
|
positions: getRealIntervals(this.height, 4, 0, 0), |
|
|
|
labels: getRealIntervals(this.height, 4, 0, 0).map(d => d + ""), |
|
|
|
}, |
|
|
|
function() { |
|
|
|
let s = this.state; |
|
|
|
return { |
|
|
|
positions: s.yAxis.positions, |
|
|
|
labels: s.yAxis.labels, |
|
|
|
} |
|
|
|
}.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.xAxis.labels, |
|
|
|
} |
|
|
|
}.bind(this) |
|
|
|
} |
|
|
|
], |
|
|
|
|
|
|
|
[ |
|
|
|
'yRegions', |
|
|
|
this.drawArea, |
|
|
|
{ |
|
|
|
// mode: this.yAxisMode, |
|
|
|
width: this.width, |
|
|
|
pos: 'right' |
|
|
|
}, |
|
|
|
[ |
|
|
|
{ |
|
|
|
start: this.height, |
|
|
|
end: this.height, |
|
|
|
label: '' |
|
|
|
} |
|
|
|
], |
|
|
|
function() { |
|
|
|
return this.data.yRegions || []; |
|
|
|
}.bind(this) |
|
|
|
} |
|
|
|
], |
|
|
|
|
|
|
|
[ |
|
|
|
'yMarkers', |
|
|
|
this.drawArea, |
|
|
|
{ |
|
|
|
// mode: this.yAxisMode, |
|
|
|
width: this.width, |
|
|
|
pos: 'right' |
|
|
|
}, |
|
|
|
[ |
|
|
|
{ |
|
|
|
position: this.height, |
|
|
|
label: '' |
|
|
|
} |
|
|
|
], |
|
|
|
function() { |
|
|
|
return this.data.yMarkers || []; |
|
|
|
}.bind(this) |
|
|
|
} |
|
|
|
] |
|
|
|
]; |
|
|
|
} |
|
|
@@ -2060,7 +2047,10 @@ class AxisChart extends BaseChart { |
|
|
|
let optionals = ['yMarkers', 'yRegions']; |
|
|
|
this.components = this.componentConfigs |
|
|
|
.filter(args => !optionals.includes(args[0]) || this.data[args[0]]) |
|
|
|
.map(args => getComponent(...args)); |
|
|
|
.map(args => { |
|
|
|
args.push(function() { return this.state[args[0]]; }.bind(this)); |
|
|
|
return getComponent(...args); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
getChartComponents() { |
|
|
@@ -2088,7 +2078,7 @@ class AxisChart extends BaseChart { |
|
|
|
|
|
|
|
return d.positions.map((y, j) => { |
|
|
|
return unitRenderer.draw( |
|
|
|
this.state.xAxisPositions[j], |
|
|
|
this.state.xAxis.positions[j], |
|
|
|
y, |
|
|
|
this.colors[index], |
|
|
|
(this.valuesOverPoints ? (this.barOptions && |
|
|
@@ -2113,7 +2103,7 @@ class AxisChart extends BaseChart { |
|
|
|
}, |
|
|
|
animate: (svgUnits) => { |
|
|
|
// have been updated in axis render; |
|
|
|
let newX = this.state.xAxisPositions; |
|
|
|
let newX = this.state.xAxis.positions; |
|
|
|
let newY = this.data.datasets[index].positions; |
|
|
|
|
|
|
|
let lastUnit = svgUnits[svgUnits.length - 1]; |
|
|
@@ -2151,17 +2141,17 @@ class AxisChart extends BaseChart { |
|
|
|
|
|
|
|
return getPaths( |
|
|
|
d.positions, |
|
|
|
this.state.xAxisPositions, |
|
|
|
this.state.xAxis.positions, |
|
|
|
color, |
|
|
|
this.config.heatline, |
|
|
|
this.config.regionFill |
|
|
|
); |
|
|
|
}, |
|
|
|
animate: (paths) => { |
|
|
|
let newX = this.state.xAxisPositions; |
|
|
|
let newX = this.state.xAxis.positions; |
|
|
|
let newY = this.data.datasets[index].positions; |
|
|
|
|
|
|
|
let oldX = this.oldState.xAxisPositions; |
|
|
|
let oldX = this.oldState.xAxis.positions; |
|
|
|
let oldY = this.oldState.datasets[index].positions; |
|
|
|
|
|
|
|
|
|
|
@@ -2214,8 +2204,8 @@ class AxisChart extends BaseChart { |
|
|
|
let formatY = this.formatTooltipY && this.formatTooltipY(this.y[0].values[0]); |
|
|
|
|
|
|
|
for(var i=s.datasetLength - 1; i >= 0 ; i--) { |
|
|
|
let xVal = s.xAxisPositions[i]; |
|
|
|
// let delta = i === 0 ? s.unitWidth : xVal - s.xAxisPositions[i-1]; |
|
|
|
let xVal = s.xAxis.positions[i]; |
|
|
|
// let delta = i === 0 ? s.unitWidth : xVal - s.xAxis.positions[i-1]; |
|
|
|
if(relX > xVal - s.unitWidth/2) { |
|
|
|
let x = xVal + this.translateXLeft; |
|
|
|
let y = s.yExtremes[i] + this.translateY; |
|
|
@@ -2291,6 +2281,7 @@ class AxisChart extends BaseChart { |
|
|
|
|
|
|
|
// keep a binding at the end of chart |
|
|
|
|
|
|
|
// import { ChartComponent } from '../objects/ChartComponents'; |
|
|
|
class LineChart extends AxisChart { |
|
|
|
constructor(args) { |
|
|
|
super(args); |
|
|
@@ -2357,6 +2348,7 @@ class ScatterChart extends LineChart { |
|
|
|
make_path() {} |
|
|
|
} |
|
|
|
|
|
|
|
// import { ChartComponent } from '../objects/ChartComponents'; |
|
|
|
class MultiAxisChart extends AxisChart { |
|
|
|
constructor(args) { |
|
|
|
super(args); |
|
|
@@ -3134,6 +3126,19 @@ class Heatmap extends BaseChart { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// if ("development" !== 'production') { |
|
|
|
// // Enable LiveReload |
|
|
|
// document.write( |
|
|
|
// '<script src="http://' + (location.host || 'localhost').split(':')[0] + |
|
|
|
// ':35729/livereload.js?snipver=1"></' + 'script>' |
|
|
|
// ); |
|
|
|
// } |
|
|
|
|
|
|
|
// If type is bar |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const chartTypes = { |
|
|
|
mixed: AxisChart, |
|
|
|
multiaxis: MultiAxisChart, |
|
|
|