UNPKG

@visactor/vchart

Version:

charts lib based @visactor/VGrammar

170 lines (157 loc) 8.32 kB
import { ComponentTypeEnum } from "../interface/type"; import { LineCrosshair, SectorCrosshair, CircleCrosshair, PolygonCrosshair } from "@visactor/vrender-components"; import { BaseCrossHair } from "./base"; import { polarToCartesian } from "@visactor/vutils"; import { angleLabelOrientAttribute, radiusLabelOrientAttribute } from "../../util/math"; import { Factory } from "../../core/factory"; import { layoutByValue, layoutCrosshair } from "./utils/polar"; import { getFirstSeries } from "../../util"; import { getSpecInfo } from "../util"; import { crosshair } from "../../theme/builtin/common/component/crosshair"; export class PolarCrossHair extends BaseCrossHair { static getSpecInfo(chartSpec) { return getSpecInfo(chartSpec, this.specKey, this.type, (s => s.categoryField && !1 !== s.categoryField.visible || s.valueField && !1 !== s.valueField.visible)); } constructor(spec, options) { super(spec, options), this.type = ComponentTypeEnum.polarCrosshair, this.name = ComponentTypeEnum.polarCrosshair, this._stateByField = { categoryField: { coordKey: "angle", anotherAxisKey: "radius", currentValue: new Map, labelsComp: { all: null } }, valueField: { coordKey: "radius", anotherAxisKey: "angle", currentValue: new Map, labelsComp: { all: null } } }; } setAxisValue(datum, axis) { "radius" === axis.getOrient() ? this._stateByField.valueField.currentValue.set(axis.getSpecIndex(), { datum: datum, axis: axis }) : this._stateByField.categoryField.currentValue.set(axis.getSpecIndex(), { datum: datum, axis: axis }); } _findAllAxisContains(relativeX, relativeY) { const angleAxisMap = this._getAxisInfoByField("category"), radiusAxisMap = this._getAxisInfoByField("value"); return { angleAxisMap: this._filterAxisByPoint(angleAxisMap, relativeX, relativeY), radiusAxisMap: this._filterAxisByPoint(radiusAxisMap, relativeX, relativeY) }; } _getDatumAtPoint(axis, point) { const {x: axisStartX, y: axisStartY} = axis.getLayoutStartPoint(), {x: x, y: y} = this.getLayoutStartPoint(); return axis.positionToData({ x: point.x - (axisStartX - x), y: point.y - (axisStartY - y) }); } _layoutCrosshair(relativeX, relativeY, tooltipData, activeType) { let x = relativeX, y = relativeY; if (tooltipData && tooltipData.length) if ("dimension" === activeType) { const dimensionInfo = tooltipData[0]; if (dimensionInfo.axis) { const triggerCoord = dimensionInfo.axis.pointToCoord({ x: x, y: y }), coord = "radius" === dimensionInfo.axis.getOrient() ? { radius: dimensionInfo.position, angle: triggerCoord.angle } : { radius: triggerCoord.radius, angle: dimensionInfo.position }, uniformPos = dimensionInfo.axis.coordToPoint(coord); x = uniformPos.x, y = uniformPos.y; } } else if ("mark" === activeType) { const dimensionData = tooltipData[0], pos = dimensionData.series.dataToPosition(dimensionData.datum[0]); x = pos.x, y = pos.y; } this.clearAxisValue(); const {angleAxisMap: angleAxisMap, radiusAxisMap: radiusAxisMap} = this._findAllAxisContains(x, y); if (0 !== angleAxisMap.size || 0 !== radiusAxisMap.size) angleAxisMap && this._setAllAxisValues(angleAxisMap, { x: x, y: y }, "categoryField"), radiusAxisMap && this._setAllAxisValues(radiusAxisMap, { x: x, y: y }, "valueField"), this.layoutByValue(); else { if (this.enableRemain) return; this.hide(); } } layoutByValue(enableRemain) { if (!this.enable) return; const series = getFirstSeries(this._regions, "polar"); series && (layoutByValue(this._stateByField, series, null != enableRemain ? enableRemain : this.enableRemain), Object.keys(this._stateByField).forEach((field => { this._layoutByField(field); }))); } _layoutByField(fieldName) { var _a, _b, _c; const {cacheInfo: cacheInfo, attributes: attributes, crosshairComp: crosshairComp, labelsComp: labelsComp, coordKey: coordKey} = this._stateByField[fieldName]; if (!cacheInfo || cacheInfo._isCache && this.enableRemain) return; const container = this.getContainer(), {visible: visible, labels: labels, coord: coord, sizeRange: sizeRange, axis: axis} = cacheInfo; if (visible) { const layoutStartPoint = this.getLayoutStartPoint(), smooth = null === (_b = null === (_a = this._spec.valueField) || void 0 === _a ? void 0 : _a.line) || void 0 === _b ? void 0 : _b.smooth, positionAttrs = layoutCrosshair(this._stateByField[fieldName], layoutStartPoint, smooth); if (crosshairComp) crosshairComp.setAttributes(positionAttrs); else { let crosshair; if ("angle" === coordKey) { const crosshairType = "rect" === attributes.type ? "sector" : "line"; "line" === crosshairType ? crosshair = new LineCrosshair(Object.assign(Object.assign({}, positionAttrs), { lineStyle: attributes.style, zIndex: this.gridZIndex, pickable: !1 })) : "sector" === crosshairType && (crosshair = new SectorCrosshair(Object.assign(Object.assign({}, positionAttrs), { sectorStyle: attributes.style, zIndex: this.gridZIndex, pickable: !1 }))); } else { crosshair = "polygon" === (smooth ? "circle" : "polygon") ? new PolygonCrosshair(Object.assign(Object.assign({}, positionAttrs), { lineStyle: attributes.style, zIndex: this.gridZIndex + 1 })) : new CircleCrosshair(Object.assign(Object.assign({}, positionAttrs), { lineStyle: attributes.style, zIndex: this.gridZIndex })); } this._stateByField[fieldName].crosshairComp = crosshair, container.add(crosshair); } const label = labels.all; if (label.visible) { const axisCenter = axis.getCenter(), center = { x: axisCenter.x + layoutStartPoint.x, y: axisCenter.y + layoutStartPoint.y }, orient = "angle" === coordKey ? angleLabelOrientAttribute(coord) : radiusLabelOrientAttribute(axis.startAngle), point = "angle" === coordKey ? polarToCartesian(center, sizeRange[1] + label.offset, coord) : polarToCartesian(center, positionAttrs.radius, axis.startAngle), labelAttrs = Object.assign(Object.assign(Object.assign(Object.assign({}, point), attributes.label), label), { textStyle: Object.assign(Object.assign({}, null === (_c = attributes.label) || void 0 === _c ? void 0 : _c.textStyle), { textAlign: orient.align, textBaseline: orient.baseline }), zIndex: this.labelZIndex }); this._updateCrosshairLabel(labelsComp.all, labelAttrs, (label => { label.name = `crosshair-${coordKey}-label`, labelsComp.all = label; })); } else labelsComp.all && labelsComp.all.hideAll(); } } } PolarCrossHair.specKey = "crosshair", PolarCrossHair.builtInTheme = { crosshair: crosshair }, PolarCrossHair.type = ComponentTypeEnum.polarCrosshair; export const registerPolarCrossHair = () => { Factory.registerComponent(PolarCrossHair.type, PolarCrossHair); }; //# sourceMappingURL=polar.js.map