c3
Version:
D3-based reusable chart library
183 lines (146 loc) • 3.98 kB
text/typescript
import { ChartInternal } from './core'
import { isFunction, sanitise } from './util'
ChartInternal.prototype.isStanfordGraphType = function() {
var $$ = this
return $$.config.data_type === 'stanford'
}
ChartInternal.prototype.initStanfordData = function() {
var $$ = this,
d3 = $$.d3,
config = $$.config,
target = $$.data.targets[0],
epochs,
maxEpochs,
minEpochs
// Make larger values appear on top
target.values.sort(compareEpochs)
// Get array of epochs
epochs = target.values.map(a => a.epochs)
minEpochs = !isNaN(config.stanford_scaleMin)
? config.stanford_scaleMin
: d3.min(epochs)
maxEpochs = !isNaN(config.stanford_scaleMax)
? config.stanford_scaleMax
: d3.max(epochs)
if (minEpochs > maxEpochs) {
throw Error('Number of minEpochs has to be smaller than maxEpochs')
}
target.colors = isFunction(config.stanford_colors)
? config.stanford_colors
: d3.interpolateHslLong(d3.hsl(250, 1, 0.5), d3.hsl(0, 1, 0.5))
target.colorscale = d3
.scaleSequentialLog(target.colors)
.domain([minEpochs, maxEpochs])
target.minEpochs = minEpochs
target.maxEpochs = maxEpochs
}
ChartInternal.prototype.getStanfordPointColor = function(d) {
var $$ = this,
target = $$.data.targets[0]
return target.colorscale(d.epochs)
}
// http://jsfiddle.net/Xotic750/KtzLq/
ChartInternal.prototype.getCentroid = function(points) {
var area = getRegionArea(points)
var x = 0,
y = 0,
i,
j,
f,
point1,
point2
for (i = 0, j = points.length - 1; i < points.length; j = i, i += 1) {
point1 = points[i]
point2 = points[j]
f = point1.x * point2.y - point2.x * point1.y
x += (point1.x + point2.x) * f
y += (point1.y + point2.y) * f
}
f = area * 6
return {
x: x / f,
y: y / f
}
}
ChartInternal.prototype.getStanfordTooltipTitle = function(d) {
var $$ = this,
labelX = $$.axis.getLabelText('x'),
labelY = $$.axis.getLabelText('y')
return `
<tr><th>${labelX ? sanitise(labelX) : 'x'}</th><th class='value'>${
d.x
}</th></tr>
<tr><th>${labelY ? sanitise(labelY) : 'y'}</th><th class='value'>${
d.value
}</th></tr>
`
}
ChartInternal.prototype.countEpochsInRegion = function(region) {
var $$ = this,
target = $$.data.targets[0],
total,
count
total = target.values.reduce(
(accumulator, currentValue) => accumulator + Number(currentValue.epochs),
0
)
count = target.values.reduce((accumulator, currentValue) => {
if (pointInRegion(currentValue, region)) {
return accumulator + Number(currentValue.epochs)
}
return accumulator
}, 0)
return {
value: count,
percentage: count !== 0 ? ((count / total) * 100).toFixed(1) : 0
}
}
export var getRegionArea = function(points) {
// thanks to: https://stackoverflow.com/questions/16282330/find-centerpoint-of-polygon-in-javascript
var area = 0,
i,
j,
point1,
point2
for (i = 0, j = points.length - 1; i < points.length; j = i, i += 1) {
point1 = points[i]
point2 = points[j]
area += point1.x * point2.y
area -= point1.y * point2.x
}
area /= 2
return area
}
export var pointInRegion = function(point, region) {
// thanks to: http://bl.ocks.org/bycoffe/5575904
// ray-casting algorithm based on
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
let xi,
yi,
yj,
xj,
intersect,
x = point.x,
y = point.value,
inside = false
for (let i = 0, j = region.length - 1; i < region.length; j = i++) {
xi = region[i].x
yi = region[i].y
xj = region[j].x
yj = region[j].y
intersect = yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi
if (intersect) {
inside = !inside
}
}
return inside
}
export var compareEpochs = function(a, b) {
if (a.epochs < b.epochs) {
return -1
}
if (a.epochs > b.epochs) {
return 1
}
return 0
}