@visactor/vchart
Version:
charts lib based @visactor/VGrammar
244 lines (235 loc) • 8.79 kB
JavaScript
import { Factory } from "./../core/factory";
import { createLine, createRect } from "@visactor/vrender-core";
import { GlyphMark, registerGlyphMark } from "./glyph";
import { isValidNumber } from "@visactor/vutils";
import { registerLine, registerRect } from "@visactor/vrender-kits";
const BAR_BOX_PLOT_CHANNELS = [ "x", "y", "minMaxWidth", "minMaxHeight", "q1q3Width", "q1q3Height", "q1", "q3", "min", "max", "median", "angle" ], BOX_PLOT_CHANNELS = [ "x", "y", "boxWidth", "boxHeight", "ruleWidth", "ruleHeight", "q1", "q3", "min", "max", "median", "angle" ];
export class BoxPlotMark extends GlyphMark {
constructor() {
super(...arguments), this.type = BoxPlotMark.type;
}
_isHorizontal() {
return this._glyphConfig && "horizontal" === this._glyphConfig.direction;
}
setGlyphConfig(cfg) {
super.setGlyphConfig(cfg), "bar" === cfg.shaftShape ? (this._subMarks = {
minMaxBox: {
type: "rect",
defaultAttributes: {
lineWidth: 0
}
},
q1q3Box: {
type: "rect",
defaultAttributes: {
lineWidth: 0
}
},
median: {
type: "line",
defaultAttributes: {
x: 0,
y: 0
}
}
}, this._positionChannels = BAR_BOX_PLOT_CHANNELS, this._channelEncoder = {
minMaxFillOpacity: val => ({
minMaxBox: {
fillOpacity: val
}
}),
lineWidth: val => ({
minMaxBox: {
lineWidth: 0
},
q1q3Box: {
lineWidth: 0
}
}),
stroke: val => ({
minMaxBox: {
stroke: !1
},
q1q3Box: {
stroke: !1
}
})
}, this._positionEncoder = (glyphAttrs, datum, g) => {
var _a;
const {x: x = g.attribute.x, y: y = g.attribute.y, minMaxWidth: minMaxWidth = g.attribute.minMaxWidth, minMaxHeight: minMaxHeight = g.attribute.minMaxHeight, q1q3Width: q1q3Width = g.attribute.q1q3Width, q1q3Height: q1q3Height = g.attribute.q1q3Height, q1: q1 = g.attribute.q1, q3: q3 = g.attribute.q3, min: min = g.attribute.min, max: max = g.attribute.max, median: median = g.attribute.median, angle: angle} = glyphAttrs, isH = this._isHorizontal(), attributes = {};
if (isH ? (attributes.minMaxBox = {
x: min,
x1: max,
y: y - minMaxHeight / 2,
y1: y + minMaxHeight / 2
}, attributes.q1q3Box = {
x: q1,
x1: q3,
y: y - q1q3Height / 2,
y1: y + q1q3Height / 2
}, attributes.median = {
points: [ {
x: median,
y: y - q1q3Height / 2
}, {
x: median,
y: y + q1q3Height / 2
} ]
}) : (attributes.minMaxBox = {
y: min,
y1: max,
x: x - minMaxWidth / 2,
x1: x + minMaxWidth / 2
}, attributes.q1q3Box = {
y: q1,
y1: q3,
x: x - q1q3Width / 2,
x1: x + q1q3Width / 2
}, attributes.median = {
points: [ {
y: median,
x: x - q1q3Width / 2
}, {
y: median,
x: x + q1q3Width / 2
} ]
}), isValidNumber(angle)) {
const anchor = null !== (_a = glyphAttrs.anchor) && void 0 !== _a ? _a : isH ? [ (min + max) / 2, y ] : [ x, (min + max) / 2 ];
Object.keys(attributes).forEach((key => {
attributes[key].angle = angle, attributes[key].anchor = anchor;
}));
}
return attributes;
}) : (this._subMarks = {
shaft: {
type: "line",
defaultAttributes: {
x: 0,
y: 0
}
},
box: {
type: "rect"
},
max: {
type: "line",
defaultAttributes: {
x: 0,
y: 0
}
},
min: {
type: "line",
defaultAttributes: {
x: 0,
y: 0
}
},
median: {
type: "line",
defaultAttributes: {
x: 0,
y: 0
}
}
}, this._positionChannels = BOX_PLOT_CHANNELS, this._channelEncoder = null, this._positionEncoder = (glyphAttrs, datum, g) => {
var _a;
const {x: x = g.attribute.x, y: y = g.attribute.y, boxWidth: boxWidth = g.attribute.boxWidth, boxHeight: boxHeight = g.attribute.boxHeight, ruleWidth: ruleWidth = g.attribute.ruleWidth, ruleHeight: ruleHeight = g.attribute.ruleHeight, q1: q1 = g.attribute.q1, q3: q3 = g.attribute.q3, min: min = g.attribute.min, max: max = g.attribute.max, median: median = g.attribute.median, angle: angle} = glyphAttrs, isH = this._isHorizontal(), attributes = {};
if (isH ? (attributes.box = {
x: q1,
x1: q3,
y: y - boxHeight / 2,
y1: y + boxHeight / 2
}, attributes.median = {
points: [ {
x: median,
y: y - boxHeight / 2
}, {
x: median,
y: y + boxHeight / 2
} ]
}, attributes.shaft = {
points: [ {
x: min,
y: y
}, {
x: max,
y: y
} ]
}, attributes.max = {
points: [ {
x: max,
y: y - ruleHeight / 2
}, {
x: max,
y: y + ruleHeight / 2
} ]
}, attributes.min = {
points: [ {
x: min,
y: y - ruleHeight / 2
}, {
x: min,
y: y + ruleHeight / 2
} ]
}) : (attributes.box = {
x: x - boxWidth / 2,
x1: x + boxWidth / 2,
y: q1,
y1: q3
}, attributes.median = {
points: [ {
x: x - boxWidth / 2,
y: median
}, {
x: x + boxWidth / 2,
y: median
} ]
}, attributes.max = {
points: [ {
x: x - ruleWidth / 2,
y: max
}, {
x: x + ruleWidth / 2,
y: max
} ]
}, attributes.min = {
points: [ {
x: x - ruleWidth / 2,
y: min
}, {
x: x + ruleWidth / 2,
y: min
} ]
}, attributes.shaft = {
points: [ {
x: x,
y: min
}, {
x: x,
y: max
} ]
}), isValidNumber(angle)) {
const anchor = null !== (_a = glyphAttrs.anchor) && void 0 !== _a ? _a : isH ? [ (min + max) / 2, y ] : [ x, (min + max) / 2 ];
Object.keys(attributes).forEach((key => {
attributes[key].angle = angle, attributes[key].anchor = anchor;
}));
}
return attributes;
});
}
_getDefaultStyle() {
return Object.assign(Object.assign({}, super._getDefaultStyle()), {
lineWidth: 2,
boxWidth: 30,
shaftWidth: 20,
shaftShape: "line"
});
}
}
BoxPlotMark.type = "boxPlot";
export const registerBoxPlotMark = () => {
registerGlyphMark(), registerLine(), registerRect(), Factory.registerGraphicComponent("line", (attrs => createLine(attrs))),
Factory.registerGraphicComponent("rect", (attrs => createRect(attrs))), Factory.registerMark(BoxPlotMark.type, BoxPlotMark);
};
//# sourceMappingURL=box-plot.js.map