@visactor/vchart
Version:
charts lib based @visactor/VGrammar
265 lines (260 loc) • 15.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: !0
}), exports.BaseMarker = void 0;
const vdataset_1 = require("@visactor/vdataset"), vutils_1 = require("@visactor/vutils"), base_component_1 = require("../base/base-component"), space_1 = require("../../util/space"), utils_1 = require("./utils"), util_1 = require("../../util"), array_1 = require("../../data/parser/array"), util_2 = require("../util"), register_1 = require("../../data/register"), aggregation_1 = require("../../data/transforms/aggregation"), marker_filter_1 = require("../../data/transforms/marker-filter"), data_view_utils_1 = require("../../data/data-view-utils"), MARKER_FORMAT_METHOD_PLACEHOLDER = "__vchart_marker_format_method__", MARKER_COORDINATE_PLACEHOLDER = "__vchart_marker_coordinate__", MARKER_TEXT_PLACEHOLDER = "__vchart_marker_text__", MARKER_AUTO_RANGE_PLACEHOLDER = "__vchart_marker_auto_range__", MARKER_STYLE_PLACEHOLDER = "__vchart_marker_style__", MARKER_DOMAIN_POSITION_SPEC_KEYS = [ "coordinate", "coordinates", "x", "y", "x1", "y1", "angle", "angle1", "radius", "radius1" ], MARKER_LAYOUT_POSITION_SPEC_KEYS = [ "position", "positions", "coordinatesOffset", "regionRelative" ], MARKER_ITEM_CONTENT_LAYOUT_SPEC_KEYS = [ "offsetX", "offsetY", "confine" ], normalizeMarkerLabelFormatMethod = label => Array.isArray(label) ? label.map(normalizeMarkerLabelFormatMethod) : label && "object" == typeof label ? "function" != typeof label.formatMethod ? label : Object.assign(Object.assign({}, label), {
formatMethod: MARKER_FORMAT_METHOD_PLACEHOLDER
}) : label, normalizeMarkerStyles = value => {
if (Array.isArray(value)) return value.map(normalizeMarkerStyles);
if (!value || "object" != typeof value) return value;
const normalized = Object.assign({}, value);
return Object.keys(normalized).forEach((key => {
"style" === key || key.endsWith("Style") ? normalized[key] = MARKER_STYLE_PLACEHOLDER : normalized[key] = normalizeMarkerStyles(normalized[key]);
})), normalized;
}, normalizeMarkerSpecForComponentOnlyUpdate = (spec, options) => {
if (!spec || "object" != typeof spec) return spec;
const normalized = Object.assign({}, spec);
options.normalizeDomainPosition && MARKER_DOMAIN_POSITION_SPEC_KEYS.forEach((key => {
normalized[key] = MARKER_COORDINATE_PLACEHOLDER;
})), options.normalizeAutoRange && "autoRange" in normalized && (normalized.autoRange = MARKER_AUTO_RANGE_PLACEHOLDER),
MARKER_LAYOUT_POSITION_SPEC_KEYS.forEach((key => {
key in normalized && (normalized[key] = MARKER_COORDINATE_PLACEHOLDER);
})), "label" in normalized && (normalized.label = normalizeMarkerLabelFormatMethod(normalized.label)),
Object.keys(normalized).forEach((key => {
normalized[key] = normalizeMarkerStyles(normalized[key]);
}));
const itemContent = normalized.itemContent;
if (itemContent && "object" == typeof itemContent) {
normalized.itemContent = Object.assign({}, itemContent), MARKER_ITEM_CONTENT_LAYOUT_SPEC_KEYS.forEach((key => {
key in normalized.itemContent && (normalized.itemContent[key] = MARKER_COORDINATE_PLACEHOLDER);
}));
const text = normalized.itemContent.text;
text && "object" == typeof text && (normalized.itemContent.text = Object.assign(Object.assign({}, normalizeMarkerLabelFormatMethod(text)), {
text: MARKER_TEXT_PLACEHOLDER
}));
}
return normalized;
};
class BaseMarker extends base_component_1.BaseComponent {
constructor() {
super(...arguments), this.layoutType = "none", this._markerDataChangeHandler = null,
this._markerDataOwned = !1, this._layoutOffsetX = 0, this._layoutOffsetY = 0;
}
getRelativeSeries() {
return this._relativeSeries;
}
getMarkerData() {
return this._markerData;
}
static _getMarkerCoordinateType(markerSpec) {
return "cartesian";
}
static getSpecInfo(chartSpec) {
return (0, util_2.getSpecInfo)(chartSpec, this.specKey, this.type, (s => !1 !== s.visible && this._getMarkerCoordinateType(s) === this.coordinateType));
}
getMarkAttributeContext() {
return this._markAttributeContext;
}
_buildMarkerAttributeContext() {
this._markAttributeContext = {
relativeSeries: this._relativeSeries,
startRelativeSeries: this._startRelativeSeries,
endRelativeSeries: this._endRelativeSeries,
vchart: this._option.globalInstance
};
}
created() {
super.created(), this._bindSeries(), this._initDataView(), this.initEvent(), this._buildMarkerAttributeContext();
}
_getAllRelativeSeries() {
return {
getRelativeSeries: () => this._relativeSeries,
getStartRelativeSeries: () => this._startRelativeSeries,
getEndRelativeSeries: () => this._endRelativeSeries
};
}
_getAutoRangeExtendDomainKeyPrefix() {
return `marker_${this.type}_${this.id}`;
}
_getAutoRangeExtendDomainKey(axisKey) {
return `${this._getAutoRangeExtendDomainKeyPrefix()}_${axisKey}_extend`;
}
_clearAutoRangeExtendDomain() {
var _a, _b;
(0, vutils_1.array)(null === (_b = (_a = this._option).getAllSeries) || void 0 === _b ? void 0 : _b.call(_a)).forEach((series => {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
null === (_c = null === (_b = null === (_a = null == series ? void 0 : series.getXAxisHelper) || void 0 === _a ? void 0 : _a.call(series)) || void 0 === _b ? void 0 : _b.setExtendDomain) || void 0 === _c || _c.call(_b, this._getAutoRangeExtendDomainKey("xAxis"), void 0),
null === (_f = null === (_e = null === (_d = null == series ? void 0 : series.getYAxisHelper) || void 0 === _d ? void 0 : _d.call(series)) || void 0 === _e ? void 0 : _e.setExtendDomain) || void 0 === _f || _f.call(_e, this._getAutoRangeExtendDomainKey("yAxis"), void 0),
null === (_h = null === (_g = null == series ? void 0 : series.angleAxisHelper) || void 0 === _g ? void 0 : _g.setExtendDomain) || void 0 === _h || _h.call(_g, this._getAutoRangeExtendDomainKey("angleAxis"), void 0),
null === (_k = null === (_j = null == series ? void 0 : series.radiusAxisHelper) || void 0 === _j ? void 0 : _j.setExtendDomain) || void 0 === _k || _k.call(_j, this._getAutoRangeExtendDomainKey("radiusAxis"), void 0);
}));
}
_updateMarkerLayout() {
this._clearAutoRangeExtendDomain(), this._markerLayout();
}
_getFieldInfoFromSpec(dim, spec, relativeSeries) {
const specKeyByDim = {
x: "xField",
y: "yField",
radius: "valueField",
angle: "categoryField",
areaName: "nameField"
};
return (0, vutils_1.isString)(spec) && (0, utils_1.isAggrSpec)(spec) ? {
field: relativeSeries.getSpec()[specKeyByDim[dim]],
aggrType: spec
} : spec;
}
_processSpecByDims(dimSpec) {
const relativeSeries = this._relativeSeries, dimMap = {};
return dimSpec.forEach((d => dimMap[d.dim] = this._getFieldInfoFromSpec(d.dim, d.specValue, relativeSeries))),
Object.assign(Object.assign({}, dimMap), this._getAllRelativeSeries());
}
_processSpecCoo(spec) {
return Object.assign(Object.assign({
coordinates: spec.coordinates || spec.coordinate
}, this._getAllRelativeSeries()), {
getSeriesByIdOrIndex: (seriesUserId, seriesIndex) => this._getSeriesByIdOrIndex(seriesUserId, seriesIndex),
coordinateType: this.coordinateType
});
}
_getRelativeDataView() {
if (this._specifiedDataSeries) {
let resultData = [];
(0, vutils_1.array)(this._specifiedDataSeries).forEach((series => {
resultData = resultData.concat(series.getViewData().latestData);
}));
const dataSet = new vdataset_1.DataSet;
return dataSet.registerParser("array", array_1.arrayParser), new vdataset_1.DataView(dataSet).parse(resultData, {
type: "array"
});
}
return this._relativeSeries.getViewData();
}
_setMarkerData(data, owned = !1) {
this._releaseMarkerData(), this._markerData = data, this._markerDataOwned = owned;
}
_bindMarkerDataChange() {
var _a;
(null === (_a = this._markerData) || void 0 === _a ? void 0 : _a.target) && (this._markerDataChangeHandler = () => {
this._updateMarkerLayout();
}, this._markerData.target.on("change", this._markerDataChangeHandler));
}
_releaseMarkerData() {
const markerData = this._markerData;
(null == markerData ? void 0 : markerData.target) && this._markerDataChangeHandler && markerData.target.removeListener("change", this._markerDataChangeHandler),
this._markerDataChangeHandler = null, this._markerDataOwned && (0, data_view_utils_1.releaseDataViewWithDependencies)(markerData, (dataView => dataView.name === `${this.type}_${this.id}_data`)),
this._markerData = null, this._markerDataOwned = !1;
}
updateLayoutAttribute() {
var _a, _b, _c;
if (null === (_a = this._spec.visible) || void 0 === _a || _a) {
if (!this._markerComponent) {
const markerComponent = this._createMarkerComponent();
markerComponent.name = null !== (_b = this._spec.name) && void 0 !== _b ? _b : this.type,
markerComponent.id = null !== (_c = this._spec.id) && void 0 !== _c ? _c : `${this.type}-${this.id}`,
this._markerComponent = markerComponent, this.getContainer().add(this._markerComponent),
this._markerComponent.on("*", ((event, type) => {
this._delegateEvent(this._markerComponent, event, type, null, this.getMarkerData.bind(this));
}));
}
this._updateMarkerLayout();
}
super.updateLayoutAttribute();
}
_getSeriesByIdOrIndex(seriesUserId, seriesIndex) {
var _a, _b;
let series;
return series = null === (_a = this._option.getSeriesInUserIdOrIndex((0, vutils_1.isValid)(seriesUserId) ? [ seriesUserId ] : [], [ seriesIndex ])) || void 0 === _a ? void 0 : _a[0],
series || (series = null !== (_b = this._relativeSeries) && void 0 !== _b ? _b : this._getFirstSeries()),
series;
}
_bindSeries() {
const spec = this._spec;
this._relativeSeries = this._getSeriesByIdOrIndex(spec.relativeSeriesId, spec.relativeSeriesIndex),
this._startRelativeSeries = this._getSeriesByIdOrIndex(spec.startRelativeSeriesId, spec.startRelativeSeriesIndex),
this._endRelativeSeries = this._getSeriesByIdOrIndex(spec.endRelativeSeriesId, spec.endRelativeSeriesIndex),
spec.specifiedDataSeriesIndex && "all" === spec.specifiedDataSeriesIndex || spec.specifiedDataSeriesId && "all" === spec.specifiedDataSeriesId ? this._specifiedDataSeries = this._option.getAllSeries() : (spec.specifiedDataSeriesIndex || spec.specifiedDataSeriesId) && (this._specifiedDataSeries = this._getSeriesByIdOrIndex(spec.specifiedDataSeriesId, spec.specifiedDataSeriesIndex));
}
initEvent() {
"cartesian" !== this._relativeSeries.coordinate && (this._relativeSeries.event.on("zoom", this._updateMarkerLayout.bind(this)),
this._relativeSeries.event.on("panmove", this._updateMarkerLayout.bind(this)), this._relativeSeries.event.on("scroll", this._updateMarkerLayout.bind(this)));
}
clear() {
super.clear(), this._markerComponent = null, this._firstSeries = null;
}
release() {
this._releaseMarkerData(), super.release();
}
_getFirstSeries() {
var _a;
if (this._firstSeries) return this._firstSeries;
const firstSeries = (0, util_1.getFirstSeries)(this._regions);
return firstSeries ? (this._firstSeries = firstSeries, firstSeries) : (null === (_a = this._option) || void 0 === _a || _a.onError("need at least one series"),
null);
}
_getNeedClearVRenderComponents() {
return [ this._markerComponent ];
}
onLayoutStart(layoutRect, chartViewRect) {
(0, vutils_1.isNil)(this._spec.offsetX) || (this._layoutOffsetX = (0, space_1.calcLayoutNumber)(this._spec.offsetX, chartViewRect.width, chartViewRect)),
(0, vutils_1.isNil)(this._spec.offsetY) || (this._layoutOffsetY = (0, space_1.calcLayoutNumber)(this._spec.offsetY, chartViewRect.height, chartViewRect)),
super.onLayoutStart(layoutRect, chartViewRect);
}
_compareSpec(spec, prevSpec) {
const result = super._compareSpec(spec, prevSpec);
return (0, vutils_1.isEqual)(prevSpec, spec) || (result.reRender = !0, result.change = !0,
result.reMake || result.reCompile || !this._isComponentOnlySpecChange(spec, prevSpec) ? result.reMake || result.reCompile || !this._isAutoRangeSpecChange(spec, prevSpec) ? result.reMake = !0 : result.effects = Object.assign(Object.assign({}, result.effects), {
component: !0,
scaleDomain: !0,
layout: !0,
render: !0
}) : result.effects = Object.assign(Object.assign({}, result.effects), {
component: !0,
layout: !0,
render: !0
})), result;
}
_isComponentOnlySpecChange(spec, prevSpec) {
const normalizeDomainPosition = !(null == spec ? void 0 : spec.autoRange) && !(null == prevSpec ? void 0 : prevSpec.autoRange);
return (0, vutils_1.isEqual)(normalizeMarkerSpecForComponentOnlyUpdate(prevSpec, {
normalizeDomainPosition: normalizeDomainPosition
}), normalizeMarkerSpecForComponentOnlyUpdate(spec, {
normalizeDomainPosition: normalizeDomainPosition
}));
}
_isAutoRangeSpecChange(spec, prevSpec) {
return !(!(null == spec ? void 0 : spec.autoRange) && !(null == prevSpec ? void 0 : prevSpec.autoRange)) && (0,
vutils_1.isEqual)(normalizeMarkerSpecForComponentOnlyUpdate(prevSpec, {
normalizeDomainPosition: !0,
normalizeAutoRange: !0
}), normalizeMarkerSpecForComponentOnlyUpdate(spec, {
normalizeDomainPosition: !0,
normalizeAutoRange: !0
}));
}
reInit(spec) {
super.reInit(spec), this._releaseMarkerData(), this._bindSeries(), this._initDataView(),
this._buildMarkerAttributeContext(), this._markerComponent && this._updateMarkerLayout();
}
_initCommonDataView() {
const {options: options} = this._computeOptions(), seriesData = this._getRelativeDataView();
(0, register_1.registerDataSetInstanceTransform)(this._option.dataSet, "markerAggregation", aggregation_1.markerAggregation),
(0, register_1.registerDataSetInstanceTransform)(this._option.dataSet, "markerFilter", marker_filter_1.markerFilter),
this._releaseMarkerData();
const data = new vdataset_1.DataView(this._option.dataSet, {
name: `${this.type}_${this.id}_data`
});
data.parse([ seriesData ], {
type: "dataview"
}), data.transform({
type: "markerAggregation",
options: options
}), data.transform({
type: "markerFilter",
options: this._getAllRelativeSeries()
}), this._setMarkerData(data, !0), this._bindMarkerDataChange();
}
}
exports.BaseMarker = BaseMarker;
//# sourceMappingURL=base-marker.js.map