UNPKG

@visactor/vgrammar-core

Version:

VGrammar is a visual grammar library

284 lines (257 loc) 16.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: !0 }), exports.Crosshair = exports.generatePolygonCrosshairAttributes = exports.generateCircleCrosshairAttributes = exports.generateSectorCrosshairAttributes = exports.generateRingCrosshairAttributes = exports.generateRectCrosshairAttributes = exports.generateLineCrosshairAttributes = void 0; const vutils_1 = require("@visactor/vutils"), vrender_components_1 = require("@visactor/vrender-components"), base_1 = require("./base"), enums_1 = require("../graph/enums"), vscale_1 = require("@visactor/vscale"), util_1 = require("../parse/util"), computeCrosshairStartEnd = (point, scale, type, groupSize, config, offset = 0) => { var _a, _b; const start = { x: 0, y: 0 }, end = { x: 0, y: 0 }, radius = "angle" === type ? null !== (_a = null == config ? void 0 : config.radius) && void 0 !== _a ? _a : Math.min(groupSize.width, groupSize.height) / 2 : null, center = "angle" === type ? null !== (_b = null == config ? void 0 : config.center) && void 0 !== _b ? _b : { x: groupSize.width / 2, y: groupSize.height / 2 } : null; let current = 0; if ((0, vscale_1.isDiscrete)(scale.type)) { if ("x" === type) current = scale.scale(scale.invert(point.x)); else if ("y" === type) current = scale.scale(scale.invert(point.y)); else if ("angle" === type) { const angle = (0, vutils_1.clampRadian)((0, vutils_1.getAngleByPoint)(center, point) + 2 * Math.PI); current = scale.scale(scale.invert(angle)); } } else (0, vscale_1.isContinuous)(scale.type) && ("x" === type ? current = point.x : "y" === type ? current = point.y : "angle" === type && (current = (0, vutils_1.getAngleByPoint)(center, point))); switch (current += offset, type) { case "x": start.x = current, start.y = 0, end.x = current, end.y = groupSize.height; break; case "y": start.x = 0, start.y = current, end.x = groupSize.width, end.y = current; break; case "angle": start.x = center.x, start.y = center.y, end.x = center.x + radius * Math.cos(current), end.y = center.y + radius * Math.sin(current); } return { start: start, end: end }; }, computeRadiusOfTangential = (point, scale, type, groupSize, config, addition) => { var _a, _b, _c; const center = null !== (_b = null !== (_a = null == addition ? void 0 : addition.center) && void 0 !== _a ? _a : null == config ? void 0 : config.center) && void 0 !== _b ? _b : { x: groupSize.width / 2, y: groupSize.height / 2 }; let currentRadius = 0; if ((0, vscale_1.isDiscrete)(scale.type)) { const offset = "band" === scale.type ? scale.bandwidth() / 2 : 0, radius = Math.sqrt((point.x - center.x) ** 2 + (point.y - center.y) ** 2); currentRadius = scale.scale(scale.invert(radius)) + offset; } else if ((0, vscale_1.isContinuous)(scale.type)) { const maxRadius = null !== (_c = null == config ? void 0 : config.radius) && void 0 !== _c ? _c : Math.min(groupSize.width, groupSize.height) / 2; currentRadius = Math.min(maxRadius, Math.sqrt((point.x - center.x) ** 2 + (point.y - center.y) ** 2)); } return { radius: currentRadius, center: center }; }, generateLineCrosshairAttributes = (point, scale, type, groupSize, config, theme, addition) => { var _a, _b, _c; const crosshairTheme = null === (_a = null == theme ? void 0 : theme.components) || void 0 === _a ? void 0 : _a.lineCrosshair, offset = "band" === scale.type ? scale.bandwidth() / 2 : 0, points = computeCrosshairStartEnd(point, scale, type, groupSize, { radius: null !== (_b = null == addition ? void 0 : addition.radius) && void 0 !== _b ? _b : null == config ? void 0 : config.radius, center: null !== (_c = null == addition ? void 0 : addition.center) && void 0 !== _c ? _c : null == config ? void 0 : config.center }, offset); return (0, vutils_1.merge)({}, crosshairTheme, points, null != addition ? addition : {}); }; exports.generateLineCrosshairAttributes = generateLineCrosshairAttributes; const generateRectCrosshairAttributes = (point, scale, type, groupSize, config, theme, addition) => { var _a, _b, _c; const crosshairTheme = null === (_a = null == theme ? void 0 : theme.components) || void 0 === _a ? void 0 : _a.rectCrosshair, defaultSize = "band" === scale.type || "point" === scale.type ? scale.step() : void 0, customRectStyle = null == addition ? void 0 : addition.rectStyle, size = null != defaultSize ? defaultSize : "y" === type ? null !== (_b = null == customRectStyle ? void 0 : customRectStyle.width) && void 0 !== _b ? _b : crosshairTheme.rectStyle.width : null !== (_c = null == customRectStyle ? void 0 : customRectStyle.height) && void 0 !== _c ? _c : crosshairTheme.rectStyle.height, points = computeCrosshairStartEnd(point, scale, type, groupSize, config, "band" === scale.type ? 0 : -size / 2), rectStyle = {}; "x" === type ? rectStyle.width = size : rectStyle.height = size; const attribute = (0, vutils_1.merge)({}, crosshairTheme, { start: points.start, end: points.end, rectStyle: rectStyle }, null != addition ? addition : {}); return "x" === type ? attribute.rectStyle.height = attribute.end.y - attribute.start.y : attribute.rectStyle.width = attribute.end.x - attribute.start.x, attribute; }; exports.generateRectCrosshairAttributes = generateRectCrosshairAttributes; const generateRingCrosshairAttributes = (point, scale, type, groupSize, config, theme, addition) => { var _a; const crosshairTheme = null === (_a = null == theme ? void 0 : theme.components) || void 0 === _a ? void 0 : _a.circleCrosshair, {center: center, radius: radius} = computeRadiusOfTangential(point, scale, 0, groupSize, config, addition), startAngle = crosshairTheme.startAngle, endAngle = crosshairTheme.endAngle, deltaRadius = "band" === scale.type || "point" === scale.type ? scale.step() : 0; return (0, vutils_1.merge)({}, crosshairTheme, { center: center, innerRadius: radius - deltaRadius / 2, radius: radius + deltaRadius / 2, startAngle: startAngle, endAngle: endAngle }, null != addition ? addition : {}); }; exports.generateRingCrosshairAttributes = generateRingCrosshairAttributes; const generateSectorCrosshairAttributes = (point, scale, type, groupSize, config, theme, addition) => { var _a, _b, _c, _d, _e; const crosshairTheme = null === (_a = null == theme ? void 0 : theme.components) || void 0 === _a ? void 0 : _a.sectorCrosshair, radius = null !== (_c = null !== (_b = null == addition ? void 0 : addition.radius) && void 0 !== _b ? _b : null == config ? void 0 : config.radius) && void 0 !== _c ? _c : Math.min(groupSize.width, groupSize.height) / 2, center = null !== (_e = null !== (_d = null == addition ? void 0 : addition.center) && void 0 !== _d ? _d : null == config ? void 0 : config.center) && void 0 !== _e ? _e : { x: groupSize.width / 2, y: groupSize.height / 2 }, defaultAngle = crosshairTheme.endAngle - crosshairTheme.startAngle, angle = "band" === scale.type || "point" === scale.type ? scale.step() : defaultAngle; let currentAngle = 0; if ((0, vscale_1.isDiscrete)(scale.type)) { const angle = (0, vutils_1.clampRadian)((0, vutils_1.getAngleByPoint)(center, point) + 2 * Math.PI); currentAngle = scale.scale(scale.invert(angle)) + ("band" === scale.type ? scale.bandwidth() / 2 : 0); } else (0, vscale_1.isContinuous)(scale.type) && (currentAngle = (0, vutils_1.getAngleByPoint)(center, point)); const startAngle = currentAngle - angle / 2, endAngle = currentAngle + angle / 2; return (0, vutils_1.merge)({}, crosshairTheme, { center: center, radius: radius, startAngle: startAngle, endAngle: endAngle }, null != addition ? addition : {}); }; exports.generateSectorCrosshairAttributes = generateSectorCrosshairAttributes; const generateCircleCrosshairAttributes = (point, scale, type, groupSize, config, theme, addition) => { var _a; const crosshairTheme = null === (_a = null == theme ? void 0 : theme.components) || void 0 === _a ? void 0 : _a.circleCrosshair, {center: center, radius: radius} = computeRadiusOfTangential(point, scale, 0, groupSize, config, addition), startAngle = crosshairTheme.startAngle, endAngle = crosshairTheme.endAngle; return (0, vutils_1.merge)({}, crosshairTheme, { center: center, radius: radius, startAngle: startAngle, endAngle: endAngle }, null != addition ? addition : {}); }; exports.generateCircleCrosshairAttributes = generateCircleCrosshairAttributes; const generatePolygonCrosshairAttributes = (point, scale, type, groupSize, config, theme, addition) => { var _a; const crosshairTheme = null === (_a = null == theme ? void 0 : theme.components) || void 0 === _a ? void 0 : _a.circleCrosshair, {center: center, radius: radius} = computeRadiusOfTangential(point, scale, 0, groupSize, config, addition), startAngle = crosshairTheme.startAngle, endAngle = crosshairTheme.endAngle; return (0, vutils_1.merge)({}, crosshairTheme, { center: center, radius: radius, startAngle: startAngle, endAngle: endAngle }, null != addition ? addition : {}); }; exports.generatePolygonCrosshairAttributes = generatePolygonCrosshairAttributes; class Crosshair extends base_1.BaseInteraction { constructor(view, options) { var _a, _b; super(view, options), this.type = Crosshair.type, this.handleCrosshairShow = event => { var _a; if (!this._crosshairComponent) return; const groupGraphicItem = this._container.getGroupGraphicItem(), point = { x: 0, y: 0 }, globalTransMatrix = groupGraphicItem.globalTransMatrix, containerPoint = { x: globalTransMatrix.e, y: globalTransMatrix.f }; if (globalTransMatrix.transformPoint(event.canvas, point), point.x < 0 || point.x > groupGraphicItem.attribute.width || point.y < 0 || point.y > groupGraphicItem.attribute.height) return void this._crosshairComponent.hideAll(); const crosshairType = null !== (_a = this.options.crosshairType) && void 0 !== _a ? _a : "x", groupSize = { width: groupGraphicItem.attribute.width, height: groupGraphicItem.attribute.height }, scale = ((0, vutils_1.isString)(this.options.scale) ? this.view.getScaleById(this.options.scale) : this.options.scale).getScale(), config = { center: this.options.center, radius: this.options.radius }, theme = this.view.getCurrentTheme(), addition = (0, util_1.invokeFunctionType)(this.options.attributes, this.parameters(), {}, {}); let attributes = {}; switch (this.getCrosshairComponentType()) { case enums_1.CrosshairEnum.lineCrosshair: attributes = (0, exports.generateLineCrosshairAttributes)(point, scale, crosshairType, groupSize, config, theme, addition); break; case enums_1.CrosshairEnum.rectCrosshair: attributes = (0, exports.generateRectCrosshairAttributes)(point, scale, crosshairType, groupSize, config, theme, addition); break; case enums_1.CrosshairEnum.sectorCrosshair: attributes = (0, exports.generateSectorCrosshairAttributes)(point, scale, crosshairType, groupSize, config, theme, addition); break; case enums_1.CrosshairEnum.circleCrosshair: attributes = (0, exports.generateCircleCrosshairAttributes)(point, scale, crosshairType, groupSize, config, theme, addition); break; case enums_1.CrosshairEnum.polygonCrosshair: attributes = (0, exports.generatePolygonCrosshairAttributes)(point, scale, crosshairType, groupSize, config, theme, addition); break; case enums_1.CrosshairEnum.ringCrosshair: attributes = (0, exports.generateRingCrosshairAttributes)(point, scale, crosshairType, groupSize, config, theme, addition); } this.getCrosshairComponentType() !== enums_1.CrosshairEnum.circleCrosshair && (attributes.x = containerPoint.x, attributes.y = containerPoint.y), this._crosshairComponent.showAll(), this._crosshairComponent.setAttributes(attributes); }, this.handleCrosshairHide = () => { this._crosshairComponent && this._crosshairComponent.hideAll(); }, this.options = Object.assign({}, Crosshair.defaultOptions, options), this._container = null !== (_b = null === (_a = view.getMarksBySelector(this.options.container)) || void 0 === _a ? void 0 : _a[0]) && void 0 !== _b ? _b : view.rootMark; } getEvents() { return [ { type: this.options.trigger, handler: this.handleCrosshairShow }, { type: this.options.triggerOff, handler: this.handleCrosshairHide } ]; } getCrosshairComponentType() { var _a, _b; if (this._crosshairComponentType) return this._crosshairComponentType; const shape = null !== (_a = this.options.crosshairShape) && void 0 !== _a ? _a : "line", type = null !== (_b = this.options.crosshairType) && void 0 !== _b ? _b : "x"; return this._crosshairComponentType = "rect" === shape ? "angle" === type ? enums_1.CrosshairEnum.sectorCrosshair : "radius" === type ? enums_1.CrosshairEnum.ringCrosshair : "radius-polygon" === type ? enums_1.CrosshairEnum.polygonCrosshair : enums_1.CrosshairEnum.rectCrosshair : "radius" === type ? enums_1.CrosshairEnum.circleCrosshair : "radius-polygon" === type ? enums_1.CrosshairEnum.polygonCrosshair : enums_1.CrosshairEnum.lineCrosshair, this._crosshairComponentType; } getDefaultCrosshairAttribute() { var _a; const type = null !== (_a = this.options.crosshairType) && void 0 !== _a ? _a : "x"; return "radius" === type || "radius-polygon" === type ? { center: { x: 0, y: 0 }, zIndex: -1 } : { start: { x: 0, y: 0 }, end: { x: 0, y: 0 }, zIndex: -1 }; } bind() { super.bind(); const stage = this.view.renderer.stage(); if (!this._crosshairComponent && stage) { switch (this.getCrosshairComponentType()) { case enums_1.CrosshairEnum.lineCrosshair: this._crosshairComponent = new vrender_components_1.LineCrosshair(this.getDefaultCrosshairAttribute()); break; case enums_1.CrosshairEnum.rectCrosshair: this._crosshairComponent = new vrender_components_1.RectCrosshair(this.getDefaultCrosshairAttribute()); break; case enums_1.CrosshairEnum.sectorCrosshair: this._crosshairComponent = new vrender_components_1.SectorCrosshair(this.getDefaultCrosshairAttribute()); break; case enums_1.CrosshairEnum.circleCrosshair: this._crosshairComponent = new vrender_components_1.CircleCrosshair(this.getDefaultCrosshairAttribute()); break; case enums_1.CrosshairEnum.polygonCrosshair: this._crosshairComponent = new vrender_components_1.PolygonCrosshair(this.getDefaultCrosshairAttribute()); break; case enums_1.CrosshairEnum.ringCrosshair: this._crosshairComponent = new vrender_components_1.SectorCrosshair(this.getDefaultCrosshairAttribute()); } stage.defaultLayer.appendChild(this._crosshairComponent); } } unbind() { super.unbind(); const stage = this.view.renderer.stage(); this._crosshairComponent && stage && (stage.defaultLayer.removeChild(this._crosshairComponent), this._crosshairComponent.release(), this._crosshairComponent = null); } } exports.Crosshair = Crosshair, Crosshair.type = "crosshair", Crosshair.defaultOptions = { trigger: "pointermove", triggerOff: "pointerleave", crosshairType: "x", crosshairShape: "line" }; //# sourceMappingURL=crosshair.js.map