UNPKG

@visactor/vchart

Version:

charts lib based @visactor/VGrammar

279 lines (262 loc) 16.2 kB
import { DataView } from "@visactor/vdataset"; import { BaseComponent } from "../base/base-component"; import { ComponentTypeEnum } from "../interface/type"; import { LayoutZIndex } from "../../constant/layout"; import { layoutByPosition, layoutOuter, placeRectByOrient } from "./layout"; import { CompilableData } from "../../compile/data/compilable-data"; import { normalizeLayoutPaddingSpec } from "../../util/space"; import { MarkPoint } from "@visactor/vrender-components"; import { createGroup, createRect, createSymbol, createText } from "@visactor/vrender-core"; import { transformToGraphic } from "../../util/style"; import { isValid } from "@visactor/vutils"; import { Factory } from "../../core/factory"; import { TransformLevel } from "../../data/initialize"; import { getSpecInfo } from "../util"; export class MapLabelComponent extends BaseComponent { constructor() { super(...arguments), this.type = ComponentTypeEnum.mapLabel, this.name = ComponentTypeEnum.mapLabel, this.specKey = "mapLabel", this.layoutType = "none", this.layoutZIndex = LayoutZIndex.MarkPoint, this._activeDatum = []; } static getSpecInfo(chartSpec) { return getSpecInfo(chartSpec, this.specKey, this.type, (s => s.visible && isValid(s.seriesId))); } setAttrFromSpec() { var _a, _b, _c, _d; this.nameField = null !== (_a = this._spec.nameField) && void 0 !== _a ? _a : null === (_b = this._series) || void 0 === _b ? void 0 : _b.getDimensionField()[0], this.valueField = null !== (_c = this._spec.valueField) && void 0 !== _c ? _c : null === (_d = this._series) || void 0 === _d ? void 0 : _d.getMeasureField()[0]; } created() { super.created(), !1 != !!this._spec.visible && (this.initRelatedInfo(), this.initData(), this.initEvent()); } initRelatedInfo() { var _a, _b, _c, _d, _e, _f, _g, _h; this._series = this._option.getSeriesInUserIdOrIndex([ this._spec.seriesId ])[0], "outer" === this._spec.position && (this._map = null === (_b = null === (_a = this._regions[0].getSeriesInType("map")[0]) || void 0 === _a ? void 0 : _a.getMapViewData()) || void 0 === _b ? void 0 : _b.latestData, this._longitudeField = null === (_e = null === (_d = (_c = this._regions[0]).getSpec) || void 0 === _d ? void 0 : _d.call(_c)) || void 0 === _e ? void 0 : _e.longitudeField, this._latitudeField = null === (_h = null === (_g = (_f = this._regions[0]).getSpec) || void 0 === _g ? void 0 : _g.call(_f)) || void 0 === _h ? void 0 : _h.latitudeField); } initData() { const series = this._series; if (!series) return; const seriesData = series.getViewData(); if (seriesData) { const data = new DataView(this._option.dataSet, { name: `${this.name}_data` }); data.parse([ seriesData ], { type: "dataview" }), data.transform({ type: "copyDataView", level: TransformLevel.copyDataView }, !1), this._data = new CompilableData(this._option, data), data.target.addListener("change", (() => { "hover" !== this._spec.trigger && "click" !== this._spec.trigger && (this._activeDatum = this._data.getLatestData()); })); } } initEvent() { var _a; this.event.on("zoom", { filter: params => this._isRelativeModel(params.model) }, (e => (this.handleZoom(e), !0))), this.event.on("panmove", { filter: params => this._isRelativeModel(params.model) }, (e => (this.handlePan(e), !0))); const trigger = this._spec.trigger; if ("none" === trigger) return; const view = null === (_a = this.getCompiler()) || void 0 === _a ? void 0 : _a.getVGrammarView(); view && ("hover" === trigger ? (view.addEventListener("element-highlight:start", (params => { this._isRelativeSeries(params.options.seriesId) && this._updateDatum(params.elements[0].getDatum()); })), view.addEventListener("element-highlight:reset", (params => { this._isRelativeSeries(params.options.seriesId) && this._updateDatum(null); }))) : "click" === trigger && (view.addEventListener("element-select:start", (params => { this._isRelativeSeries(params.options.seriesId) && this._updateDatum(params.elements[0].getDatum()); })), view.addEventListener("elementSelectReset", (params => { this._isRelativeSeries(params.options.seriesId) && this._updateDatum([]); })))); } handlePan(e) { const {delta: delta} = e; this._markerComponents.forEach((marker => { marker.translate(delta[0], delta[1]); })); } handleZoom(e) { this._updateMarkerLayoutAttribute(); } _updateDatum(datum) { this._activeDatum = datum, this._markerComponents.forEach(((marker, index) => { var _a; const markerDatum = null === (_a = this._data) || void 0 === _a ? void 0 : _a.getLatestData()[index]; this._activeDatum.includes(markerDatum) ? marker.setAttribute("visible", !0) : marker.setAttribute("visible", !1); })); } dataToPosition(datum) { return this._series.dataToPosition(datum); } updateLayoutAttribute() { var _a; const markData = null === (_a = this._data) || void 0 === _a ? void 0 : _a.getLatestData(); markData && 0 !== markData.length && (super.updateLayoutAttribute(), this._updateMarkerLayoutAttribute()); } _updateMarkerLayoutAttribute() { var _a; const layoutPairInfo = [], markerMarks = []; this._markerComponents || (this._markerComponents = null === (_a = this._data) || void 0 === _a ? void 0 : _a.getLatestData().map(((data, index) => { var _a; const cmp = new MarkPoint({ position: void 0, animation: !1 }); return cmp && (cmp.name = `${this.name}_marker_${index}`, cmp.id = null !== (_a = this._spec.id) && void 0 !== _a ? _a : `${this.name}_marker_${this.id}`, cmp.setAttribute("zIndex", this.layoutZIndex)), cmp; }))); this._markerComponents.forEach(((marker, index) => { marker.removeAllChild(); const {pairInfo: pairInfo, contentMarks: contentMarks} = this._evaluateMarker(this._data.getLatestData()[index], index); pairInfo && layoutPairInfo.push(pairInfo), contentMarks && markerMarks.push(contentMarks); })); const positionedRects = this._layoutLabels(layoutPairInfo); this._layoutMarkers(positionedRects, markerMarks), this._renderMarkers(); } _evaluateMarker(data, index) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m; let contentItemCount = 0, paddingWidth = 0, paddingHeight = 0, contentWidth = 0, contentHeight = 0; const position = this._spec.position || "top", offset = this._spec.offset, padding = normalizeLayoutPaddingSpec(null === (_a = this._spec.background) || void 0 === _a ? void 0 : _a.padding), space = this._spec.space || 0; paddingWidth += ((null == padding ? void 0 : padding.left) || 0) + ((null == padding ? void 0 : padding.right) || 0), paddingHeight += ((null == padding ? void 0 : padding.top) || 0) + ((null == padding ? void 0 : padding.bottom) || 0); const contentMarks = {}, positionAttr = this.dataToPosition(data), container = createGroup({}); if (container.name = `${this.name}_marker_itemContainer_${index}`, contentMarks.container = container, null === (_b = this._spec.background) || void 0 === _b ? void 0 : _b.visible) { const labelBackground = createRect(transformToGraphic(Object.assign({}, this._spec.background.style))); labelBackground.setAttributes(positionAttr), contentMarks.labelBackground = labelBackground, container.appendChild(labelBackground); } if (null === (_c = this._spec.icon) || void 0 === _c ? void 0 : _c.visible) { const icon = createSymbol(transformToGraphic(Object.assign({}, this._spec.icon.style))); icon.setAttributes(positionAttr), icon.setAttribute("symbolType", null === (_d = this._spec.icon.style) || void 0 === _d ? void 0 : _d.shape); const iconBound = icon.AABBBounds, iconHeight = null !== (_e = (null == iconBound ? void 0 : iconBound.y2) - (null == iconBound ? void 0 : iconBound.y1)) && void 0 !== _e ? _e : 0, iconWidth = null !== (_f = (null == iconBound ? void 0 : iconBound.x2) - (null == iconBound ? void 0 : iconBound.x1)) && void 0 !== _f ? _f : 0; contentMarks.icon = icon, container.appendChild(icon), contentHeight = iconHeight, contentWidth += iconWidth, contentItemCount++; } if (null === (_g = this._spec.nameLabel) || void 0 === _g ? void 0 : _g.visible) { const nameLabel = createText(transformToGraphic(Object.assign({}, this._spec.nameLabel.style))); nameLabel.setAttributes(positionAttr), nameLabel.setAttribute("text", data[this.nameField]); const nameLabelBound = nameLabel.AABBBounds, nameLabelHeight = null !== (_h = (null == nameLabelBound ? void 0 : nameLabelBound.y2) - (null == nameLabelBound ? void 0 : nameLabelBound.y1)) && void 0 !== _h ? _h : 0, nameLabelWidth = null !== (_j = (null == nameLabelBound ? void 0 : nameLabelBound.x2) - (null == nameLabelBound ? void 0 : nameLabelBound.x1)) && void 0 !== _j ? _j : 0; contentMarks.nameLabel = nameLabel, container.appendChild(nameLabel), contentHeight = Math.max(contentHeight, nameLabelHeight), contentWidth += nameLabelWidth, contentItemCount++; } if ((null === (_k = this._spec.valueLabel) || void 0 === _k ? void 0 : _k.visible) && isValid(data[this.valueField])) { const valueLabel = createText(transformToGraphic(Object.assign({}, this._spec.valueLabel.style))); valueLabel.setAttributes(positionAttr), valueLabel.setAttribute("text", data[this.valueField]); const valueLabelBound = valueLabel.AABBBounds, valueLabelHeight = null !== (_l = (null == valueLabelBound ? void 0 : valueLabelBound.y2) - (null == valueLabelBound ? void 0 : valueLabelBound.y1)) && void 0 !== _l ? _l : 0, valueLabelWidth = null !== (_m = (null == valueLabelBound ? void 0 : valueLabelBound.x2) - (null == valueLabelBound ? void 0 : valueLabelBound.x1)) && void 0 !== _m ? _m : 0; contentMarks.valueLabel = valueLabel, container.appendChild(valueLabel), contentHeight = Math.max(contentHeight, valueLabelHeight), contentWidth += valueLabelWidth, contentItemCount++; } const firstValidMark = Object.values(contentMarks).find((m => !!m && "group" !== m.type)), anchor = { x: null == firstValidMark ? void 0 : firstValidMark.getComputedAttribute("x"), y: null == firstValidMark ? void 0 : firstValidMark.getComputedAttribute("y") }, itemRect = { x: anchor.x, y: anchor.y, width: 0, height: 0 }; itemRect.width = paddingWidth + contentWidth + (contentItemCount - 1) * space, itemRect.height = paddingHeight + contentHeight; const pairInfo = { rect: itemRect, point: anchor, index: index }; if ("outer" !== position) { const anchors = [ "top", "right", "left", "bottom" ].filter((a => a !== position)); pairInfo.rect = placeRectByOrient(itemRect, position, offset), pairInfo.anchors = anchors, pairInfo.offset = offset; } else pairInfo.pointCoord = { x: +(null == data ? void 0 : data[this._longitudeField]), y: +(null == data ? void 0 : data[this._latitudeField]) }; return { pairInfo: pairInfo, contentMarks: contentMarks }; } _layoutMarkers(positionedRects, contentMarks) { var _a, _b, _c; for (let i = 0; i < contentMarks.length; i++) { if (!positionedRects[i] || !contentMarks[i]) return; const {icon: icon, nameLabel: nameLabel, valueLabel: valueLabel, labelBackground: labelBackground, container: container} = contentMarks[i], itemRect = positionedRects[i], padding = normalizeLayoutPaddingSpec(null === (_a = this._spec.background) || void 0 === _a ? void 0 : _a.padding), space = this._spec.space || 0, curY = itemRect.height / 2; let curX = (null == padding ? void 0 : padding.left) || 0; [ icon, nameLabel, valueLabel ].forEach(((item, index) => { var _a, _b; if (item) { const bounds = item.AABBBounds; let offset = 0; "symbol" === item.type && (offset += (null !== (_a = bounds.x2 - bounds.x1) && void 0 !== _a ? _a : 0) / 2), item.setAttributes({ x: curX + offset, y: curY }), curX += null !== (_b = bounds.x2 - bounds.x1) && void 0 !== _b ? _b : 0, 2 !== index && (curX += space); } })), null == labelBackground || labelBackground.setAttributes({ x: 0, y: 0, width: itemRect.width, height: itemRect.height }), null == container || container.setAttributes({ dx: -itemRect.width / 2, dy: -itemRect.height / 2 }); const datum = this._data.getLatestData()[i], anchor = this.dataToPosition(datum), regionPos = this.getRegions()[0].getLayoutStartPoint(), showLeader = !(!(null === (_b = this._spec.leader) || void 0 === _b ? void 0 : _b.visible) || !(icon || nameLabel || valueLabel)); this._markerComponents[i].setAttributes({ x: regionPos.x, y: regionPos.y, position: anchor, visible: this._activeDatum.includes(datum), itemContent: { refX: 0, type: "custom", renderCustomCallback: () => container, autoRotate: !1, offsetX: itemRect.x + itemRect.width / 2 - anchor.x, offsetY: itemRect.y + itemRect.height / 2 - anchor.y }, itemLine: { visible: showLeader, type: "type-po", lineStyle: transformToGraphic(Object.assign({}, null === (_c = this._spec.leader) || void 0 === _c ? void 0 : _c.style)), startSymbol: { visible: !1 } } }); } } _renderMarkers() { if (this._markerComponents && this._markerComponents.length) for (let i = 0; i < this._markerComponents.length; i++) this.getContainer().add(this._markerComponents[i]); } _layoutLabels(rects) { return "outer" === this._spec.position && this._map ? layoutOuter(rects, this._map, (coord => this._series.dataToPosition({ [this._longitudeField]: coord[0], [this._latitudeField]: coord[1] }))) : layoutByPosition(rects); } _isRelativeModel(model) { var _a, _b, _c; const id = null !== (_b = null === (_a = this._series.getXAxisHelper()) || void 0 === _a ? void 0 : _a.getAxisId()) && void 0 !== _b ? _b : null === (_c = this._series.getCoordinateHelper()) || void 0 === _c ? void 0 : _c.getCoordinateId(); return (null == model ? void 0 : model.id) === id; } _isRelativeSeries(model) { return (null == model ? void 0 : model.id) === this._series.id; } onRender(ctx) {} changeRegions() {} _getNeedClearVRenderComponents() { return this._markerComponents; } } MapLabelComponent.type = ComponentTypeEnum.mapLabel, MapLabelComponent.specKey = "mapLabel"; export const registerMapLabel = () => { Factory.registerComponent(MapLabelComponent.type, MapLabelComponent); }; //# sourceMappingURL=component.js.map