@visactor/vgrammar-core
Version:
VGrammar is a visual grammar library
418 lines (406 loc) • 20.2 kB
JavaScript
import { isValidNumber } from "@visactor/vutils";
import { Factory } from "../core/factory";
import { registerGlyphGraphic, registerRectGraphic, registerRuleGraphic } from "../graph/mark/graphic";
import { isHorizontal } from "@visactor/vgrammar-util";
import { registerGlyphMark } from "../view/glyph";
const scaleIn = computeCenter => (element, options, animationParameters) => {
var _a, _b, _c;
const direction = null !== (_c = null !== (_a = element.getGraphicAttribute("direction", !1)) && void 0 !== _a ? _a : null === (_b = element.mark.getGlyphConfig()) || void 0 === _b ? void 0 : _b.direction) && void 0 !== _c ? _c : "vertical", center = computeCenter(element, direction, options);
if (!isValidNumber(center)) return {};
const x = element.getGraphicAttribute("x", !1), y = element.getGraphicAttribute("y", !1), min = element.getGraphicAttribute("min", !1), max = element.getGraphicAttribute("max", !1), q1 = element.getGraphicAttribute("q1", !1), q3 = element.getGraphicAttribute("q3", !1), median = element.getGraphicAttribute("median", !1), animateAttributes = {
from: {
x: x,
y: y
},
to: {
x: x,
y: y
}
};
return isValidNumber(min) && (animateAttributes.from.min = center, animateAttributes.to.min = min),
isValidNumber(max) && (animateAttributes.from.max = center, animateAttributes.to.max = max),
isValidNumber(q1) && (animateAttributes.from.q1 = center, animateAttributes.to.q1 = q1),
isValidNumber(q3) && (animateAttributes.from.q3 = center, animateAttributes.to.q3 = q3),
isValidNumber(median) && (animateAttributes.from.median = center, animateAttributes.to.median = median),
animateAttributes;
}, scaleOut = computeCenter => (element, options, animationParameters) => {
var _a, _b, _c;
const direction = null !== (_c = null !== (_a = element.getGraphicAttribute("direction", !1)) && void 0 !== _a ? _a : null === (_b = element.mark.getGlyphConfig()) || void 0 === _b ? void 0 : _b.direction) && void 0 !== _c ? _c : "vertical", center = computeCenter(element, direction, options);
if (!isValidNumber(center)) return {};
const x = element.getGraphicAttribute("x", !0), y = element.getGraphicAttribute("y", !0), min = element.getGraphicAttribute("min", !0), max = element.getGraphicAttribute("max", !0), q1 = element.getGraphicAttribute("q1", !0), q3 = element.getGraphicAttribute("q3", !0), median = element.getGraphicAttribute("median", !0), animateAttributes = {
from: {
x: x,
y: y
},
to: {
x: x,
y: y
}
};
return isValidNumber(min) && (animateAttributes.to.min = center, animateAttributes.from.min = min),
isValidNumber(max) && (animateAttributes.to.max = center, animateAttributes.from.max = max),
isValidNumber(q1) && (animateAttributes.to.q1 = center, animateAttributes.from.q1 = q1),
isValidNumber(q3) && (animateAttributes.to.q3 = center, animateAttributes.from.q3 = q3),
isValidNumber(median) && (animateAttributes.to.median = center, animateAttributes.from.median = median),
animateAttributes;
}, computeBoxplotCenter = (glyphElement, direction, options) => {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
if (options && isValidNumber(options.center)) return options.center;
let median, max, min, q1, q3;
if (isHorizontal(direction)) {
median = null === (_b = null === (_a = glyphElement.getGraphicAttribute("points", !1, "median")) || void 0 === _a ? void 0 : _a[0]) || void 0 === _b ? void 0 : _b.x,
max = null === (_d = null === (_c = glyphElement.getGraphicAttribute("points", !1, "max")) || void 0 === _c ? void 0 : _c[0]) || void 0 === _d ? void 0 : _d.x,
min = null === (_f = null === (_e = glyphElement.getGraphicAttribute("points", !1, "min")) || void 0 === _e ? void 0 : _e[0]) || void 0 === _f ? void 0 : _f.x;
const boxWidth = glyphElement.getGraphicAttribute("width", !1, "box"), boxX = glyphElement.getGraphicAttribute("x", !1, "box");
q1 = boxX, q3 = boxX + boxWidth;
} else {
median = null === (_h = null === (_g = glyphElement.getGraphicAttribute("points", !1, "median")) || void 0 === _g ? void 0 : _g[0]) || void 0 === _h ? void 0 : _h.y,
max = null === (_k = null === (_j = glyphElement.getGraphicAttribute("points", !1, "max")) || void 0 === _j ? void 0 : _j[0]) || void 0 === _k ? void 0 : _k.y,
min = null === (_m = null === (_l = glyphElement.getGraphicAttribute("points", !1, "min")) || void 0 === _l ? void 0 : _l[0]) || void 0 === _m ? void 0 : _m.y;
const boxHeight = glyphElement.getGraphicAttribute("height", !1, "box"), boxY = glyphElement.getGraphicAttribute("y", !1, "box");
q1 = boxY, q3 = boxY + boxHeight;
}
return isValidNumber(median) ? median : isValidNumber(q1) && isValidNumber(q3) ? (q1 + q3) / 2 : isValidNumber(max) && isValidNumber(min) ? (max + min) / 2 : isValidNumber(min) ? min : isValidNumber(max) ? max : NaN;
}, encodeBoxplotSize = (encodeValues, datum, element, config) => {
var _a, _b, _c, _d, _e, _f, _g, _h;
const attributes = {
shaft: {},
box: {},
max: {},
min: {},
median: {}
}, x = null !== (_a = encodeValues.x) && void 0 !== _a ? _a : element.getGraphicAttribute("x", !1), y = null !== (_b = encodeValues.y) && void 0 !== _b ? _b : element.getGraphicAttribute("y", !1), width = null !== (_c = encodeValues.width) && void 0 !== _c ? _c : element.getGraphicAttribute("width", !1), height = null !== (_d = encodeValues.height) && void 0 !== _d ? _d : element.getGraphicAttribute("height", !1), boxWidth = null !== (_e = encodeValues.boxWidth) && void 0 !== _e ? _e : element.getGraphicAttribute("boxWidth", !1), boxHeight = null !== (_f = encodeValues.boxHeight) && void 0 !== _f ? _f : element.getGraphicAttribute("boxHeight", !1), ruleWidth = null !== (_g = encodeValues.ruleWidth) && void 0 !== _g ? _g : element.getGraphicAttribute("ruleWidth", !1), ruleHeight = null !== (_h = encodeValues.ruleHeight) && void 0 !== _h ? _h : element.getGraphicAttribute("ruleHeight", !1);
return config && isHorizontal(config.direction) ? (isValidNumber(boxHeight) ? (Object.assign(attributes.box, {
y: y - boxHeight / 2,
y1: y + boxHeight / 2
}), Object.assign(attributes.median, {
y: y - boxHeight / 2,
y1: y + boxHeight / 2
})) : (Object.assign(attributes.box, {
y: y - height / 2,
y1: y + height / 2
}), Object.assign(attributes.median, {
y: y - height / 2,
y1: y + height / 2
})), isValidNumber(ruleHeight) ? (Object.assign(attributes.max, {
y: y - ruleHeight / 2,
y1: y + ruleHeight / 2
}), Object.assign(attributes.min, {
y: y - ruleHeight / 2,
y1: y + ruleHeight / 2
})) : (Object.assign(attributes.max, {
y: y - height / 2,
y1: y + height / 2
}), Object.assign(attributes.min, {
y: y - height / 2,
y1: y + height / 2
}))) : (isValidNumber(boxWidth) ? (Object.assign(attributes.box, {
x: x - boxWidth / 2,
x1: x + boxWidth / 2
}), Object.assign(attributes.median, {
x: x - boxWidth / 2,
x1: x + boxWidth / 2
})) : (Object.assign(attributes.box, {
x: x - width / 2,
x1: x + width / 2
}), Object.assign(attributes.median, {
x: x - width / 2,
x1: x + width / 2
})), isValidNumber(ruleWidth) ? (Object.assign(attributes.max, {
x: x - ruleWidth / 2,
x1: x + ruleWidth / 2
}), Object.assign(attributes.min, {
x: x - ruleWidth / 2,
x1: x + ruleWidth / 2
})) : (Object.assign(attributes.max, {
x: x - width / 2,
x1: x + width / 2
}), Object.assign(attributes.min, {
x: x - width / 2,
x1: x + width / 2
}))), attributes;
};
export const boxplotScaleIn = scaleIn(computeBoxplotCenter);
export const boxplotScaleOut = scaleOut(computeBoxplotCenter);
export function registerBoxplotGlyph() {
Factory.registerGlyph("boxplot", {
shaft: "rule",
box: "rect",
max: "rule",
min: "rule",
median: "rule"
}).registerProgressiveChannels([ "x", "y", "q1", "q3", "min", "max", "median", "angle", "width", "height", "boxWidth", "boxHeight", "ruleWidth", "ruleHeight" ]).registerFunctionEncoder(encodeBoxplotSize).registerChannelEncoder("x", ((channel, encodeValue, encodeValues, datum, element, config) => config && isHorizontal(config.direction) ? null : {
shaft: {
x: encodeValue,
x1: encodeValue
}
})).registerChannelEncoder("y", ((channel, encodeValue, encodeValues, datum, element, config) => config && isHorizontal(config.direction) ? {
shaft: {
y: encodeValue,
y1: encodeValue
}
} : null)).registerChannelEncoder("q1", ((channel, encodeValue, encodeValues, datum, element, config) => config && isHorizontal(config.direction) ? {
box: {
x: encodeValue
}
} : {
box: {
y: encodeValue
}
})).registerChannelEncoder("q3", ((channel, encodeValue, encodeValues, datum, element, config) => config && isHorizontal(config.direction) ? {
box: {
x1: encodeValue
}
} : {
box: {
y1: encodeValue
}
})).registerChannelEncoder("min", ((channel, encodeValue, encodeValues, datum, element, config) => config && isHorizontal(config.direction) ? {
shaft: {
x: encodeValue
},
min: {
x: encodeValue,
x1: encodeValue,
visible: !0
}
} : {
shaft: {
y: encodeValue
},
min: {
y: encodeValue,
y1: encodeValue,
visible: !0
}
})).registerChannelEncoder("max", ((channel, encodeValue, encodeValues, datum, element, config) => config && isHorizontal(config.direction) ? {
shaft: {
x1: encodeValue
},
max: {
x: encodeValue,
x1: encodeValue,
visible: !0
}
} : {
shaft: {
y1: encodeValue
},
max: {
y: encodeValue,
y1: encodeValue,
visible: !0
}
})).registerChannelEncoder("median", ((channel, encodeValue, encodeValues, datum, element, config) => config && isHorizontal(config.direction) ? {
median: {
x: encodeValue,
x1: encodeValue,
visible: !0
}
} : {
median: {
y: encodeValue,
y1: encodeValue,
visible: !0
}
})).registerChannelEncoder("angle", ((channel, encodeValue, encodeValues, datum, element, config) => {
var _a;
const defaultAnchor = config && isHorizontal(config.direction) ? [ (encodeValues.min + encodeValues.max) / 2, encodeValues.y ] : [ encodeValues.x, (encodeValues.min + encodeValues.max) / 2 ], anchor = null !== (_a = encodeValues.anchor) && void 0 !== _a ? _a : defaultAnchor;
return {
shaft: {
angle: encodeValue,
anchor: anchor
},
box: {
angle: encodeValue,
anchor: anchor
},
max: {
angle: encodeValue,
anchor: anchor
},
min: {
angle: encodeValue,
anchor: anchor
},
median: {
angle: encodeValue,
anchor: anchor
}
};
})).registerDefaultEncoder((() => ({
max: {
visible: !1
},
min: {
visible: !1
},
median: {
visible: !1
}
}))), Factory.registerAnimationType("boxplotScaleIn", boxplotScaleIn), Factory.registerAnimationType("boxplotScaleOut", boxplotScaleOut),
registerGlyphMark(), registerGlyphGraphic(), registerRectGraphic(), registerRuleGraphic();
}
const computeBarBoxplotCenter = (glyphElement, direction, options) => {
var _a, _b, _c, _d;
if (isValidNumber(null == options ? void 0 : options.center)) return options.center;
let median, max, min, q1, q3;
if (isHorizontal(direction)) {
median = null === (_b = null === (_a = glyphElement.getGraphicAttribute("points", !1, "median")) || void 0 === _a ? void 0 : _a[0]) || void 0 === _b ? void 0 : _b.x;
const minMaxBoxWidth = glyphElement.getGraphicAttribute("width", !1, "minMaxBox"), minMaxBoxBoxX = glyphElement.getGraphicAttribute("x", !1, "minMaxBox");
min = minMaxBoxBoxX, max = minMaxBoxBoxX + minMaxBoxWidth;
const q1q3BoxWidth = glyphElement.getGraphicAttribute("width", !1, "q1q3Box"), q1q3BoxX = glyphElement.getGraphicAttribute("x", !1, "q1q3Box");
q1 = q1q3BoxX, q3 = q1q3BoxX + q1q3BoxWidth;
} else {
median = null === (_d = null === (_c = glyphElement.getGraphicAttribute("points", !1, "median")) || void 0 === _c ? void 0 : _c[0]) || void 0 === _d ? void 0 : _d.y;
const minMaxBoxHeight = glyphElement.getGraphicAttribute("height", !1, "minMaxBox"), minMaxBoxBoxY = glyphElement.getGraphicAttribute("y", !1, "minMaxBox");
min = minMaxBoxBoxY, max = minMaxBoxBoxY + minMaxBoxHeight;
const q1q3BoxHeight = glyphElement.getGraphicAttribute("height", !1, "q1q3Box"), q1q3BoxY = glyphElement.getGraphicAttribute("y", !1, "q1q3Box");
q1 = q1q3BoxY, q3 = q1q3BoxY + q1q3BoxHeight;
}
return isValidNumber(median) ? median : isValidNumber(q1) && isValidNumber(q3) ? (q1 + q3) / 2 : isValidNumber(max) && isValidNumber(min) ? (max + min) / 2 : isValidNumber(min) ? min : isValidNumber(max) ? max : NaN;
}, encodeBarBoxplotSize = (encodeValues, datum, element, config) => {
var _a, _b, _c, _d, _e, _f, _g, _h;
const attributes = {
minMaxBox: {},
q1q3Box: {},
median: {}
}, x = null !== (_a = encodeValues.x) && void 0 !== _a ? _a : element.getGraphicAttribute("x", !1), y = null !== (_b = encodeValues.y) && void 0 !== _b ? _b : element.getGraphicAttribute("y", !1), width = null !== (_c = encodeValues.width) && void 0 !== _c ? _c : element.getGraphicAttribute("width", !1), minMaxWidth = null !== (_d = encodeValues.minMaxWidth) && void 0 !== _d ? _d : element.getGraphicAttribute("minMaxWidth", !1), q1q3Width = null !== (_e = encodeValues.q1q3Width) && void 0 !== _e ? _e : element.getGraphicAttribute("q1q3Width", !1), height = null !== (_f = encodeValues.height) && void 0 !== _f ? _f : element.getGraphicAttribute("height", !1), minMaxHeight = null !== (_g = encodeValues.minMaxHeight) && void 0 !== _g ? _g : element.getGraphicAttribute("minMaxHeight", !1), q1q3Height = null !== (_h = encodeValues.q1q3Height) && void 0 !== _h ? _h : element.getGraphicAttribute("q1q3Height", !1);
return config && isHorizontal(config.direction) ? (isValidNumber(minMaxHeight) ? Object.assign(attributes.minMaxBox, {
y: y - minMaxHeight / 2,
y1: y + minMaxHeight / 2
}) : Object.assign(attributes.minMaxBox, {
y: y - height / 2,
y1: y + height / 2
}), isValidNumber(q1q3Height) ? (Object.assign(attributes.q1q3Box, {
y: y - q1q3Height / 2,
y1: y + q1q3Height / 2
}), Object.assign(attributes.median, {
y: y - q1q3Height / 2,
y1: y + q1q3Height / 2
})) : (Object.assign(attributes.q1q3Box, {
y: y - height / 2,
y1: y + height / 2
}), Object.assign(attributes.median, {
y: y - height / 2,
y1: y + height / 2
}))) : (isValidNumber(minMaxWidth) ? Object.assign(attributes.minMaxBox, {
x: x - minMaxWidth / 2,
x1: x + minMaxWidth / 2
}) : Object.assign(attributes.minMaxBox, {
x: x - width / 2,
x1: x + width / 2
}), isValidNumber(q1q3Width) ? (Object.assign(attributes.q1q3Box, {
x: x - q1q3Width / 2,
x1: x + q1q3Width / 2
}), Object.assign(attributes.median, {
x: x - q1q3Width / 2,
x1: x + q1q3Width / 2
})) : (Object.assign(attributes.q1q3Box, {
x: x - width / 2,
x1: x + width / 2
}), Object.assign(attributes.median, {
x: x - width / 2,
x1: x + width / 2
}))), attributes;
};
export const barBoxplotScaleIn = scaleIn(computeBarBoxplotCenter);
export const barBoxplotScaleOut = scaleOut(computeBarBoxplotCenter);
export function registerBarBoxplotGlyph() {
Factory.registerGlyph("barBoxplot", {
minMaxBox: "rect",
q1q3Box: "rect",
median: "rule"
}).registerProgressiveChannels([ "x", "y", "q1", "q3", "min", "max", "median", "angle", "width", "height", "minMaxWidth", "q1q3Width", "minMaxHeight", "q1q3Height" ]).registerFunctionEncoder(encodeBarBoxplotSize).registerChannelEncoder("q1", ((channel, encodeValue, encodeValues, datum, element, config) => config && isHorizontal(config.direction) ? {
q1q3Box: {
x: encodeValue
}
} : {
q1q3Box: {
y: encodeValue
}
})).registerChannelEncoder("q3", ((channel, encodeValue, encodeValues, datum, element, config) => config && isHorizontal(config.direction) ? {
q1q3Box: {
x1: encodeValue
}
} : {
q1q3Box: {
y1: encodeValue
}
})).registerChannelEncoder("min", ((channel, encodeValue, encodeValues, datum, element, config) => config && isHorizontal(config.direction) ? {
minMaxBox: {
x: encodeValue
}
} : {
minMaxBox: {
y: encodeValue
}
})).registerChannelEncoder("max", ((channel, encodeValue, encodeValues, datum, element, config) => config && isHorizontal(config.direction) ? {
minMaxBox: {
x1: encodeValue
}
} : {
minMaxBox: {
y1: encodeValue
}
})).registerChannelEncoder("median", ((channel, encodeValue, encodeValues, datum, element, config) => config && isHorizontal(config.direction) ? {
median: {
x: encodeValue,
x1: encodeValue,
visible: !0
}
} : {
median: {
y: encodeValue,
y1: encodeValue,
visible: !0
}
})).registerChannelEncoder("angle", ((channel, encodeValue, encodeValues, datum, element, config) => {
var _a;
const anchor = null !== (_a = encodeValues.anchor) && void 0 !== _a ? _a : [ encodeValues.x, (encodeValues.min + encodeValues.max) / 2 ];
return {
minMaxBox: {
angle: encodeValue,
anchor: anchor
},
q1q3Box: {
angle: encodeValue,
anchor: anchor
},
median: {
angle: encodeValue,
anchor: anchor
}
};
})).registerChannelEncoder("lineWidth", ((channel, encodeValue, encodeValues, datum, element, config) => ({
minMaxBox: {
lineWidth: 0
},
q1q3Box: {
lineWidth: 0
}
}))).registerChannelEncoder("minMaxFillOpacity", ((channel, encodeValue, encodeValues, datum, element, config) => ({
minMaxBox: {
fillOpacity: encodeValue
}
}))).registerChannelEncoder("stroke", ((channel, encodeValue, encodeValues, datum, element, config) => ({
minMaxBox: {
stroke: !1
},
q1q3Box: {
stroke: !1
}
}))).registerDefaultEncoder((() => ({
minMaxBox: {
lineWidth: 0
},
q1q3Box: {
lineWidth: 0
},
median: {
visible: !1
}
}))), Factory.registerAnimationType("barBoxplotScaleIn", barBoxplotScaleIn), Factory.registerAnimationType("barBoxplotScaleOut", barBoxplotScaleOut),
registerGlyphMark(), registerGlyphGraphic(), registerRectGraphic(), registerRuleGraphic();
}
//# sourceMappingURL=boxplot.js.map