@@ -2501,6 +2501,18 @@ function scale(val, yAxis) { | |||||
return floatTwo(yAxis.zeroLine - val * yAxis.scaleMultiplier); | return floatTwo(yAxis.zeroLine - val * yAxis.scaleMultiplier); | ||||
} | } | ||||
function getClosestInArray(goal, arr, index = false) { | |||||
let closest = arr.reduce(function(prev, curr) { | |||||
return (Math.abs(curr - goal) < Math.abs(prev - goal) ? curr : prev); | |||||
}); | |||||
return index ? arr.indexOf(closest) : closest; | |||||
} | |||||
function calcDistribution(values, distributionSize) { | function calcDistribution(values, distributionSize) { | ||||
// Assume non-negative values, | // Assume non-negative values, | ||||
// implying distribution minimum at zero | // implying distribution minimum at zero | ||||
@@ -2905,6 +2917,7 @@ class AxisChart extends BaseChart { | |||||
this.calcXPositions(); | this.calcXPositions(); | ||||
if(onlyWidthChange) return; | if(onlyWidthChange) return; | ||||
this.calcYAxisParameters(this.getAllYValues(), this.type === 'line'); | this.calcYAxisParameters(this.getAllYValues(), this.type === 'line'); | ||||
this.makeDataByIndex(); | |||||
} | } | ||||
calcXPositions() { | calcXPositions() { | ||||
@@ -3208,10 +3221,34 @@ class AxisChart extends BaseChart { | |||||
}); | }); | ||||
} | } | ||||
makeDataByIndex() { | |||||
this.dataByIndex = {}; | |||||
} | |||||
mapTooltipXPosition(relX) { | mapTooltipXPosition(relX) { | ||||
// console.log(relX); | |||||
let s = this.state; | let s = this.state; | ||||
if(!s.yExtremes) return; | if(!s.yExtremes) return; | ||||
let index = getClosestInArray(relX, s.xAxis.positions, true); | |||||
this.tip.setValues( | |||||
s.xAxis.positions[index], | |||||
s.yExtremes[index], | |||||
{name: s.xAxis.labels[index], value: ''}, | |||||
this.data.datasets.map((set, i) => { | |||||
return { | |||||
title: set.name, | |||||
value: set.values[index], | |||||
color: this.colors[i], | |||||
}; | |||||
}), | |||||
index | |||||
); | |||||
this.tip.showTip(); | |||||
} | |||||
getTooltipValues() { | |||||
let formatY = this.config.formatTooltipY; | let formatY = this.config.formatTooltipY; | ||||
let formatX = this.config.formatTooltipX; | let formatX = this.config.formatTooltipX; | ||||
@@ -3222,26 +3259,7 @@ class AxisChart extends BaseChart { | |||||
formatY = formatY && formatY(s.yAxis.labels[0]) ? formatY : 0; | formatY = formatY && formatY(s.yAxis.labels[0]) ? formatY : 0; | ||||
for(var i=s.datasetLength - 1; i >= 0 ; i--) { | |||||
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.leftMargin; | |||||
let y = s.yExtremes[i] + this.topMargin; | |||||
let values = this.data.datasets.map((set, j) => { | |||||
return { | |||||
title: set.name, | |||||
value: formatY ? formatY(set.values[i]) : set.values[i], | |||||
color: this.colors[j], | |||||
}; | |||||
}); | |||||
this.tip.setValues(x, y, {name: titles[i], value: ''}, values, i); | |||||
this.tip.showTip(); | |||||
break; | |||||
} | |||||
} | |||||
yVal = formatY ? formatY(set.values[i]) : set.values[i]; | |||||
} | } | ||||
renderLegend() { | renderLegend() { | ||||
@@ -3265,6 +3283,9 @@ class AxisChart extends BaseChart { | |||||
} | } | ||||
} | } | ||||
// Overlay | |||||
makeOverlay() { | makeOverlay() { | ||||
if(this.init) { | if(this.init) { | ||||
this.init = 0; | this.init = 0; | ||||
@@ -3365,6 +3386,8 @@ class AxisChart extends BaseChart { | |||||
fire(this.parent, "data-select", this.getDataPoint()); | fire(this.parent, "data-select", this.getDataPoint()); | ||||
} | } | ||||
// API | // API | ||||
addDataPoint(label, datasetValues, index=this.state.datasetLength) { | addDataPoint(label, datasetValues, index=this.state.datasetLength) { | ||||
super.addDataPoint(label, datasetValues, index); | super.addDataPoint(label, datasetValues, index); | ||||
@@ -270,6 +270,8 @@ var heatmapData = { | |||||
end: end | end: end | ||||
}; | }; | ||||
// ================================================================================ | |||||
var c1 = document.querySelector("#chart-composite-1"); | var c1 = document.querySelector("#chart-composite-1"); | ||||
var c2 = document.querySelector("#chart-composite-2"); | var c2 = document.querySelector("#chart-composite-2"); | ||||
@@ -3,7 +3,7 @@ import { dataPrep, zeroDataPrep, getShortenedLabels } from '../utils/axis-chart- | |||||
import { Y_AXIS_LEFT_MARGIN, Y_AXIS_RIGHT_MARGIN, AXIS_LEGEND_BAR_SIZE } from '../utils/constants'; | import { Y_AXIS_LEFT_MARGIN, Y_AXIS_RIGHT_MARGIN, AXIS_LEGEND_BAR_SIZE } from '../utils/constants'; | ||||
import { getComponent } from '../objects/ChartComponents'; | import { getComponent } from '../objects/ChartComponents'; | ||||
import { getOffset, fire } from '../utils/dom'; | import { getOffset, fire } from '../utils/dom'; | ||||
import { calcChartIntervals, getIntervalSize, getValueRange, getZeroIndex, scale } from '../utils/intervals'; | |||||
import { calcChartIntervals, getIntervalSize, getValueRange, getZeroIndex, scale, getClosestInArray } from '../utils/intervals'; | |||||
import { floatTwo } from '../utils/helpers'; | import { floatTwo } from '../utils/helpers'; | ||||
import { makeOverlay, updateOverlay, legendBar } from '../utils/draw'; | import { makeOverlay, updateOverlay, legendBar } from '../utils/draw'; | ||||
import { MIN_BAR_PERCENT_HEIGHT, BAR_CHART_SPACE_RATIO, LINE_CHART_DOT_SIZE } from '../utils/constants'; | import { MIN_BAR_PERCENT_HEIGHT, BAR_CHART_SPACE_RATIO, LINE_CHART_DOT_SIZE } from '../utils/constants'; | ||||
@@ -55,6 +55,7 @@ export default class AxisChart extends BaseChart { | |||||
this.calcXPositions(); | this.calcXPositions(); | ||||
if(onlyWidthChange) return; | if(onlyWidthChange) return; | ||||
this.calcYAxisParameters(this.getAllYValues(), this.type === 'line'); | this.calcYAxisParameters(this.getAllYValues(), this.type === 'line'); | ||||
this.makeDataByIndex(); | |||||
} | } | ||||
calcXPositions() { | calcXPositions() { | ||||
@@ -358,10 +359,34 @@ export default class AxisChart extends BaseChart { | |||||
}); | }); | ||||
} | } | ||||
makeDataByIndex() { | |||||
this.dataByIndex = {}; | |||||
} | |||||
mapTooltipXPosition(relX) { | mapTooltipXPosition(relX) { | ||||
let s = this.state; | |||||
// console.log(relX); | |||||
let s = this.state, d = this.data; | |||||
if(!s.yExtremes) return; | if(!s.yExtremes) return; | ||||
let index = getClosestInArray(relX, s.xAxis.positions, true); | |||||
this.tip.setValues( | |||||
s.xAxis.positions[index], | |||||
s.yExtremes[index], | |||||
{name: s.xAxis.labels[index], value: ''}, | |||||
this.data.datasets.map((set, i) => { | |||||
return { | |||||
title: set.name, | |||||
value: set.values[index], | |||||
color: this.colors[i], | |||||
}; | |||||
}), | |||||
index | |||||
); | |||||
this.tip.showTip(); | |||||
} | |||||
getTooltipValues() { | |||||
let formatY = this.config.formatTooltipY; | let formatY = this.config.formatTooltipY; | ||||
let formatX = this.config.formatTooltipX; | let formatX = this.config.formatTooltipX; | ||||
@@ -372,26 +397,7 @@ export default class AxisChart extends BaseChart { | |||||
formatY = formatY && formatY(s.yAxis.labels[0]) ? formatY : 0; | formatY = formatY && formatY(s.yAxis.labels[0]) ? formatY : 0; | ||||
for(var i=s.datasetLength - 1; i >= 0 ; i--) { | |||||
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.leftMargin; | |||||
let y = s.yExtremes[i] + this.topMargin; | |||||
let values = this.data.datasets.map((set, j) => { | |||||
return { | |||||
title: set.name, | |||||
value: formatY ? formatY(set.values[i]) : set.values[i], | |||||
color: this.colors[j], | |||||
}; | |||||
}); | |||||
this.tip.setValues(x, y, {name: titles[i], value: ''}, values, i); | |||||
this.tip.showTip(); | |||||
break; | |||||
} | |||||
} | |||||
yVal = formatY ? formatY(set.values[i]) : set.values[i] | |||||
} | } | ||||
renderLegend() { | renderLegend() { | ||||
@@ -415,6 +421,9 @@ export default class AxisChart extends BaseChart { | |||||
} | } | ||||
} | } | ||||
// Overlay | |||||
makeOverlay() { | makeOverlay() { | ||||
if(this.init) { | if(this.init) { | ||||
this.init = 0; | this.init = 0; | ||||
@@ -515,6 +524,8 @@ export default class AxisChart extends BaseChart { | |||||
fire(this.parent, "data-select", this.getDataPoint()); | fire(this.parent, "data-select", this.getDataPoint()); | ||||
} | } | ||||
// API | // API | ||||
addDataPoint(label, datasetValues, index=this.state.datasetLength) { | addDataPoint(label, datasetValues, index=this.state.datasetLength) { | ||||
super.addDataPoint(label, datasetValues, index); | super.addDataPoint(label, datasetValues, index); | ||||
@@ -200,6 +200,23 @@ export function scale(val, yAxis) { | |||||
return floatTwo(yAxis.zeroLine - val * yAxis.scaleMultiplier); | return floatTwo(yAxis.zeroLine - val * yAxis.scaleMultiplier); | ||||
} | } | ||||
export function isInRange(val, min, max) { | |||||
return val > min && val < max; | |||||
} | |||||
export function isInRange2D(coord, minCoord, maxCoord) { | |||||
return isInRange(coord[0], minCoord[0], maxCoord[0]) | |||||
&& isInRange(coord[1], minCoord[1], maxCoord[1]); | |||||
} | |||||
export function getClosestInArray(goal, arr, index = false) { | |||||
let closest = arr.reduce(function(prev, curr) { | |||||
return (Math.abs(curr - goal) < Math.abs(prev - goal) ? curr : prev); | |||||
}); | |||||
return index ? arr.indexOf(closest) : closest; | |||||
} | |||||
export function calcDistribution(values, distributionSize) { | export function calcDistribution(values, distributionSize) { | ||||
// Assume non-negative values, | // Assume non-negative values, | ||||
// implying distribution minimum at zero | // implying distribution minimum at zero | ||||