c3
Version:
D3-based reusable chart library
150 lines (143 loc) • 4.3 kB
text/typescript
import CLASS from './class'
import { ChartInternal } from './core'
import { isUndefined } from './util'
ChartInternal.prototype.getShapeIndices = function(typeFilter) {
var $$ = this,
config = $$.config,
indices = {},
i = 0,
j,
k
$$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$)).forEach(
function(d) {
for (j = 0; j < config.data_groups.length; j++) {
if (config.data_groups[j].indexOf(d.id) < 0) {
continue
}
for (k = 0; k < config.data_groups[j].length; k++) {
if (config.data_groups[j][k] in indices) {
indices[d.id] = indices[config.data_groups[j][k]]
break
}
}
}
if (isUndefined(indices[d.id])) {
indices[d.id] = i++
}
}
)
;(indices as any).__max__ = i - 1
return indices
}
ChartInternal.prototype.getShapeX = function(
offset,
targetsNum,
indices,
isSub
) {
var $$ = this,
scale = isSub ? $$.subX : $$.x
return function(d) {
var index = d.id in indices ? indices[d.id] : 0
return d.x || d.x === 0 ? scale(d.x) - offset * (targetsNum / 2 - index) : 0
}
}
ChartInternal.prototype.getShapeY = function(isSub) {
const $$ = this
return function(d) {
const scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id)
return scale(
$$.isTargetNormalized(d.id) ? $$.getRatio('index', d, true) : d.value
)
}
}
ChartInternal.prototype.getShapeOffset = function(typeFilter, indices, isSub) {
var $$ = this,
targets = $$.orderTargets(
$$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$))
),
targetIds = targets.map(function(t) {
return t.id
})
return function(d, i) {
var scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id),
y0 = scale(0),
offset = y0
targets.forEach(function(t) {
const rowValues = $$.isStepType(d)
? $$.convertValuesToStep(t.values)
: t.values
const isTargetNormalized = $$.isTargetNormalized(d.id)
const values = rowValues.map(v =>
isTargetNormalized ? $$.getRatio('index', v, true) : v.value
)
if (t.id === d.id || indices[t.id] !== indices[d.id]) {
return
}
if (targetIds.indexOf(t.id) < targetIds.indexOf(d.id)) {
// check if the x values line up
if (isUndefined(rowValues[i]) || +rowValues[i].x !== +d.x) {
// "+" for timeseries
// if not, try to find the value that does line up
i = -1
rowValues.forEach(function(v, j) {
const x1 = v.x.constructor === Date ? +v.x : v.x
const x2 = d.x.constructor === Date ? +d.x : d.x
if (x1 === x2) {
i = j
}
})
}
if (i in rowValues && rowValues[i].value * d.value >= 0) {
offset += scale(values[i]) - y0
}
}
})
return offset
}
}
ChartInternal.prototype.isWithinShape = function(that, d) {
var $$ = this,
shape = $$.d3.select(that),
isWithin
if (!$$.isTargetToShow(d.id)) {
isWithin = false
} else if (that.nodeName === 'circle') {
isWithin = $$.isStepType(d)
? $$.isWithinStep(that, $$.getYScale(d.id)(d.value))
: $$.isWithinCircle(that, $$.pointSelectR(d) * 1.5)
} else if (that.nodeName === 'path') {
isWithin = shape.classed(CLASS.bar)
? $$.isWithinBar($$.d3.mouse(that), that)
: true
}
return isWithin
}
ChartInternal.prototype.getInterpolate = function(d) {
var $$ = this,
d3 = $$.d3,
types = {
linear: d3.curveLinear,
'linear-closed': d3.curveLinearClosed,
basis: d3.curveBasis,
'basis-open': d3.curveBasisOpen,
'basis-closed': d3.curveBasisClosed,
bundle: d3.curveBundle,
cardinal: d3.curveCardinal,
'cardinal-open': d3.curveCardinalOpen,
'cardinal-closed': d3.curveCardinalClosed,
monotone: d3.curveMonotoneX,
step: d3.curveStep,
'step-before': d3.curveStepBefore,
'step-after': d3.curveStepAfter
},
type
if ($$.isSplineType(d)) {
type = types[$$.config.spline_interpolation_type] || types.cardinal
} else if ($$.isStepType(d)) {
type = types[$$.config.line_step_type]
} else {
type = types.linear
}
return type
}