@visactor/vgrammar-core
Version:
VGrammar is a visual grammar library
137 lines (130 loc) • 8.89 kB
JavaScript
import { Factory } from "../core/factory";
import { isNil } from "@visactor/vutils";
import { registerGlyphGraphic, registerPathGraphic } from "../graph/mark/graphic";
import { registerGlyphMark } from "../view/glyph";
export const getHorizontalPath = (options, ratio) => {
var _a;
const curvature = null !== (_a = options.curvature) && void 0 !== _a ? _a : .5, thickness = "number" == typeof ratio ? options.thickness * ratio : options.thickness;
let x0 = options.x0, x1 = options.x1, y00 = options.y0, y10 = options.y1, cpx0 = x0 + curvature * (x1 - x0), cpx1 = x1 + curvature * (x0 - x1), formatter = v => v;
!1 !== options.round && (x0 = Math.round(x0), x1 = Math.round(x1), y00 = Math.round(y00),
y10 = Math.round(y10), cpx0 = Math.round(cpx0), cpx1 = Math.round(cpx1), formatter = Math.round);
"line" === options.pathType || options.pathType;
"center" === options.align ? (y00 = formatter(options.y0 - thickness / 2), y10 = formatter(options.y1 - thickness / 2)) : "end" === options.align ? (y00 = formatter(options.y0 + options.thickness / 2 - thickness),
y10 = formatter(options.y1 + options.thickness / 2 - thickness)) : (y00 = formatter(options.y0 - options.thickness / 2),
y10 = formatter(options.y1 - options.thickness / 2));
const y01 = formatter(y00 + thickness), y11 = formatter(y10 + thickness), hasLength = Math.abs(x1 - x0) > 1e-6, endArrowPath = options.endArrow && hasLength ? `L${x1},${formatter(y10 - thickness / 2)}L${formatter(x1 + thickness)},${formatter((y10 + y11) / 2)}L${x1},${formatter(y11 + thickness / 2)}` : "", startArrowPath = options.startArrow && hasLength ? `L${x0},${formatter(y01 + thickness / 2)}L${formatter(x0 - thickness)},${formatter((y00 + y01) / 2)}L${x0},${formatter(y00 - thickness / 2)}` : "";
return "line" === options.pathType ? `M${x0},${y00}L${x1},${y10}${endArrowPath}L${x1},${y11}L${x0},${y01}${startArrowPath}Z` : "polyline" === options.pathType ? `M${x0},${y00}L${cpx0},${y00}L${cpx0},${y10}L${x1},${y10}\n ${endArrowPath}L${x1},${y11}L${cpx0},${y11}L${cpx0},${y01}L${x0},${y01}${startArrowPath}Z` : `M${x0},${y00}C${cpx0},${y00},${cpx1},${y10},${x1},${y10}\n ${endArrowPath}L${x1},${y11}C${cpx1},${y11},${cpx0},${y01},${x0},${y01}${startArrowPath}Z`;
};
export const getVerticalPath = (options, ratio) => {
var _a;
const curvature = null !== (_a = options.curvature) && void 0 !== _a ? _a : .5, thickness = "number" == typeof ratio ? options.thickness * ratio : options.thickness;
let y0 = options.y0, y1 = options.y1, x00 = options.x0, x10 = options.x1, cpy0 = y0 + curvature * (y1 - y0), cpy1 = y1 + curvature * (y0 - y1), formatter = v => v;
!1 !== options.round && (formatter = Math.round, y0 = Math.round(y0), y1 = Math.round(y1),
x00 = Math.round(x00), x10 = Math.round(x10), cpy0 = Math.round(cpy0), cpy1 = Math.round(cpy1));
"line" === options.pathType || options.pathType;
"center" === options.align ? (x00 = formatter(options.x0 - thickness / 2), x10 = formatter(options.x1 - thickness / 2)) : "end" === options.align ? (x00 = formatter(options.x0 + options.thickness / 2 - thickness),
x10 = formatter(options.x1 + options.thickness / 2 - thickness)) : (x00 = formatter(options.x0 - options.thickness / 2),
x10 = formatter(options.x1 - options.thickness / 2));
const x01 = formatter(x00 + thickness), x11 = formatter(x10 + thickness), hasLength = Math.abs(y1 - y0) > 1e-6, endArrowPath = options.endArrow && hasLength ? `L${formatter(x10 - thickness / 2)},${y1}L${formatter((x10 + x11) / 2)},${formatter(y1 + thickness)}L${formatter(x11 + thickness / 2)},${y1}` : "", startArrowPath = options.startArrow && hasLength ? `L${formatter(x01 + thickness / 2)},${y0}L${formatter((x01 + x00) / 2)},${formatter(y0 - thickness)}L${formatter(x00 - thickness / 2)},${y0}` : "";
return "line" === options.pathType ? `M${x00},${y0}L${x10},${y1}${endArrowPath}L${x11},${y1}L${x01},${y0}${startArrowPath}Z` : "polyline" === options.pathType ? `M${x00},${y0}L${x00},${cpy0}L${x10},${cpy0}L${x10},${y1}\n ${endArrowPath}L${x11},${y1}L${x11},${cpy0}L${x01},${cpy0}L${x01},${y0}${startArrowPath}Z` : `M${x00},${y0}C${x00},${cpy0},${x10},${cpy1},${x10},${y1}\n ${endArrowPath}L${x11},${y1}C${x11},${cpy1},${x01},${cpy0},${x01},${y0}${startArrowPath}Z`;
};
const encoder = (encodeValues, datum, element, config) => {
var _a;
const direction = null !== (_a = encodeValues.direction) && void 0 !== _a ? _a : null == config ? void 0 : config.direction, parsePath = [ "vertical", "TB", "BT" ].includes(direction) ? getVerticalPath : getHorizontalPath, isRatioShow = "number" == typeof encodeValues.ratio && encodeValues.ratio >= 0 && encodeValues.ratio <= 1, encodeChannels = Object.keys(encodeValues);
return [ "x0", "y0", "x1", "y1" ].every((channel => encodeChannels.includes(channel))) ? {
back: {
path: isRatioShow ? parsePath(encodeValues, 1) : ""
},
front: {
path: parsePath(encodeValues, isRatioShow ? encodeValues.ratio : 1)
}
} : {};
}, linkPathGrowIn = (element, options, animationParameters) => {
const linkValues = {
x0: element.getGraphicAttribute("x0", !1),
x1: element.getGraphicAttribute("x1", !1),
y0: element.getGraphicAttribute("y0", !1),
y1: element.getGraphicAttribute("y1", !1),
thickness: element.getGraphicAttribute("thickness", !1),
round: element.getGraphicAttribute("round", !1),
align: element.getGraphicAttribute("align", !1),
pathType: element.getGraphicAttribute("pathType", !1),
endArrow: element.getGraphicAttribute("endArrow", !1),
startArrow: element.getGraphicAttribute("startArrow", !1)
};
return Object.keys(linkValues).forEach((key => {
isNil(linkValues[key]) && delete linkValues[key];
})), {
from: Object.assign({}, linkValues, {
x1: linkValues.x0,
y1: linkValues.y0
}),
to: linkValues
};
}, linkPathGrowOut = (element, options, animationParameters) => {
const linkValues = {
x0: element.getGraphicAttribute("x0", !0),
x1: element.getGraphicAttribute("x1", !0),
y0: element.getGraphicAttribute("y0", !0),
y1: element.getGraphicAttribute("y1", !0),
thickness: element.getGraphicAttribute("thickness", !0),
round: element.getGraphicAttribute("round", !0),
align: element.getGraphicAttribute("align", !0),
pathType: element.getGraphicAttribute("pathType", !0),
endArrow: element.getGraphicAttribute("endArrow", !0),
startArrow: element.getGraphicAttribute("startArrow", !0)
};
return Object.keys(linkValues).forEach((key => {
isNil(linkValues[key]) && delete linkValues[key];
})), {
from: linkValues,
to: Object.assign({}, linkValues, {
x1: linkValues.x0,
y1: linkValues.y0
})
};
}, linkPathUpdate = (element, options, animationParameters) => {
const bassLinkValues = {
thickness: element.getGraphicAttribute("thickness", !1),
round: element.getGraphicAttribute("round", !1),
align: element.getGraphicAttribute("align", !1),
pathType: element.getGraphicAttribute("pathType", !1),
endArrow: element.getGraphicAttribute("endArrow", !1),
startArrow: element.getGraphicAttribute("startArrow", !1)
};
Object.keys(bassLinkValues).forEach((key => {
isNil(bassLinkValues[key]) && delete bassLinkValues[key];
}));
return {
from: Object.assign(Object.assign({
x0: element.getGraphicAttribute("x0", !0),
x1: element.getGraphicAttribute("x1", !0),
y0: element.getGraphicAttribute("y0", !0),
y1: element.getGraphicAttribute("y1", !0)
}, bassLinkValues), bassLinkValues),
to: Object.assign({
x0: element.getGraphicAttribute("x0", !1),
x1: element.getGraphicAttribute("x1", !1),
y0: element.getGraphicAttribute("y0", !1),
y1: element.getGraphicAttribute("y1", !1)
}, bassLinkValues)
};
};
export const registerLinkPathGlyph = () => {
Factory.registerGlyph("linkPath", {
back: "path",
front: "path"
}).registerFunctionEncoder(encoder).registerChannelEncoder("backgroundStyle", ((channel, encodeValue) => ({
back: encodeValue
}))).registerDefaultEncoder((() => ({
back: {
zIndex: 0
},
front: {
zIndex: 1
}
}))), Factory.registerAnimationType("linkPathGrowIn", linkPathGrowIn), Factory.registerAnimationType("linkPathGrowOut", linkPathGrowOut),
Factory.registerAnimationType("linkPathUpdate", linkPathUpdate), registerGlyphMark(),
registerGlyphGraphic(), registerPathGraphic();
};
//# sourceMappingURL=link-path.js.map