billboard.js
Version:
Re-usable easy interface JavaScript chart library, based on D3 v4+
177 lines (147 loc) • 4.68 kB
text/typescript
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
// @ts-nocheck
import CLASS from "./classes";
import {getCentroid, isString, parseDate} from "./util";
/**
* Stanford diagram plugin element class
* @class ColorScale
* @param {Stanford} owner Stanford instance
* @private
*/
export default class Elements {
private owner;
constructor(owner) {
this.owner = owner;
// MEMO: Avoid blocking eventRect
const elements = owner.$$.$el.main.select(".bb-chart")
.append("g")
.attr("class", CLASS.stanfordElements);
elements.append("g").attr("class", CLASS.stanfordLines);
elements.append("g").attr("class", CLASS.stanfordRegions);
}
updateStanfordLines(duration: number): void {
const {$$} = this.owner;
const {config, $el: {main}} = $$;
const isRotated = config.axis_rotated;
const xvCustom = this.xvCustom.bind($$);
const yvCustom = this.yvCustom.bind($$);
// Stanford-Lines
const stanfordLine = main.select(`.${CLASS.stanfordLines}`)
.style("shape-rendering", "geometricprecision")
.selectAll(`.${CLASS.stanfordLine}`)
.data(this.owner.config.lines);
// exit
stanfordLine.exit().transition()
.duration(duration)
.style("opacity", "0")
.remove();
// enter
const stanfordLineEnter = stanfordLine.enter().append("g");
stanfordLineEnter.append("line")
.style("opacity", "0");
stanfordLineEnter
.merge(stanfordLine)
.attr("class", d => CLASS.stanfordLine + (d.class ? ` ${d.class}` : ""))
.select("line")
.transition()
.duration(duration)
.attr("x1", d => {
const v = isRotated ? yvCustom(d, "y1") : xvCustom(d, "x1");
return v;
})
.attr("x2", d => (isRotated ? yvCustom(d, "y2") : xvCustom(d, "x2")))
.attr("y1", d => {
const v = isRotated ? xvCustom(d, "x1") : yvCustom(d, "y1");
return v;
})
.attr("y2", d => (isRotated ? xvCustom(d, "x2") : yvCustom(d, "y2")))
.transition()
.style("opacity", null);
}
updateStanfordRegions(duration: number): void {
const {$$} = this.owner;
const {config, $el: {main}} = $$;
const isRotated = config.axis_rotated;
const xvCustom = this.xvCustom.bind($$);
const yvCustom = this.yvCustom.bind($$);
const countPointsInRegion = this.owner.countEpochsInRegion.bind($$);
// Stanford-Regions
let stanfordRegion = main.select(`.${CLASS.stanfordRegions}`)
.selectAll(`.${CLASS.stanfordRegion}`)
.data(this.owner.config.regions);
// exit
stanfordRegion.exit().transition()
.duration(duration)
.style("opacity", "0")
.remove();
// enter
const stanfordRegionEnter = stanfordRegion.enter().append("g");
stanfordRegionEnter.append("polygon")
.style("opacity", "0");
stanfordRegionEnter.append("text")
.attr("transform", isRotated ? "rotate(-90)" : "")
.style("opacity", "0");
stanfordRegion = stanfordRegionEnter.merge(stanfordRegion);
// update
stanfordRegion
.attr("class", d => CLASS.stanfordRegion + (d.class ? ` ${d.class}` : ""))
.select("polygon")
.transition()
.duration(duration)
.attr("points", d =>
d.points.map(value =>
[
isRotated ? yvCustom(value, "y") : xvCustom(value, "x"),
isRotated ? xvCustom(value, "x") : yvCustom(value, "y")
].join(",")
).join(" "))
.transition()
.style("opacity", d => String(d.opacity ? d.opacity : 0.2));
stanfordRegion.select("text")
.transition()
.duration(duration)
.attr("x",
d => (isRotated ?
yvCustom(getCentroid(d.points), "y") :
xvCustom(getCentroid(d.points), "x")))
.attr("y",
d => (isRotated ?
xvCustom(getCentroid(d.points), "x") :
yvCustom(getCentroid(d.points), "y")))
.text(d => {
if (d.text) {
const {value, percentage} = countPointsInRegion(d.points);
return d.text(value, percentage);
}
return "";
})
.attr("text-anchor", "middle")
.attr("dominant-baseline", "middle")
.transition()
.style("opacity", null);
}
updateStanfordElements(duration = 0): void {
this.updateStanfordLines(duration);
this.updateStanfordRegions(duration);
}
xvCustom(d, xyValue): number {
const $$ = this;
const {axis, config} = $$;
let value = xyValue ? d[xyValue] : $$.getBaseValue(d);
if (axis.isTimeSeries()) {
value = parseDate.call($$, value);
} else if (axis.isCategorized() && isString(value)) {
value = config.axis_x_categories.indexOf(d.value);
}
return $$.scale.x(value);
}
yvCustom(d, xyValue): number {
const $$ = this;
const yScale = d.axis && d.axis === "y2" ? $$.scale.y2 : $$.scale.y;
const value = xyValue ? d[xyValue] : $$.getBaseValue(d);
return yScale(value);
}
}