UNPKG

@visactor/vchart

Version:

charts lib based @visactor/VGrammar

422 lines (413 loc) 25.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: !0 }), exports.DataFilterBaseComponent = void 0; const model_1 = require("../../util/model"), base_component_1 = require("../base/base-component"), interface_1 = require("../interface"), util_1 = require("./util"), register_1 = require("../../data/register"), vscale_1 = require("@visactor/vscale"), common_1 = require("../axis/cartesian/util/common"), vutils_1 = require("@visactor/vutils"), vdataset_1 = require("@visactor/vdataset"), compilable_data_1 = require("../../compile/data/compilable-data"), zoomable_1 = require("../../interaction/zoom/zoomable"), initialize_1 = require("../../data/initialize"), attribute_1 = require("../../constant/attribute"), data_filter_event_1 = require("./data-filter-event"), event_1 = require("../../constant/event"); class DataFilterBaseComponent extends base_component_1.BaseComponent { get isHorizontal() { return this._isHorizontal; } get stateScale() { return this._stateScale; } get relatedAxisComponent() { return this._relatedAxisComponent; } setStartAndEnd(start, end, rangeMode = [ "percent", "percent" ]) { const [startMode = "percent", endMode = "percent"] = rangeMode, startPercent = "percent" === startMode ? start : (0, util_1.dataToStatePoint)(start, this._stateScale, this._isHorizontal), endPercent = "percent" === endMode ? end : (0, util_1.dataToStatePoint)(end, this._stateScale, this._isHorizontal); this._handleChange(startPercent, endPercent, !0); } enableInteraction() { this._dataFilterEvent.enableInteraction(); } disableInteraction() { this._dataFilterEvent.disableInteraction(); } zoomIn(location) { this._dataFilterEvent.zoomIn(location); } zoomOut(location) { this._dataFilterEvent.zoomOut(location); } _initEvent() { var _a; this._dataFilterEvent.initZoomEvent(), null === (_a = this._relatedAxisComponent) || void 0 === _a || _a.event.on(event_1.ChartEvent.scaleRawDomainUpdate, (({model: model}) => { console.log("scaleRawDomainUpdate", model.getRawDomain()); })); } _handleChange(start, end, updateComponent) { var _a, _b; null !== (_b = null === (_a = this._spec) || void 0 === _a ? void 0 : _a.zoomLock) && void 0 !== _b && _b || end - start !== this._spanCache && (end - start < this._minSpan || end - start > this._maxSpan) ? this._shouldChange = !1 : (this._shouldChange = !0, this._spanCache = end - start); } _updateRangeFactor(tag) { const axis = this._relatedAxisComponent, axisScale = axis.getScale(), reverse = (0, util_1.isReverse)(axis, this._isHorizontal), newRangeFactor = reverse ? [ 1 - this._end, 1 - this._start ] : [ this._start, this._end ]; if (reverse) switch (tag) { case "startHandler": axis.scaleRangeFactorEnd(newRangeFactor[1]); break; case "endHandler": axis.scaleRangeFactorStart(newRangeFactor[0]); break; default: axis.scaleRangeFactorStart(newRangeFactor[0], !0), axis.scaleRangeFactorEnd(newRangeFactor[1]); } else switch (tag) { case "startHandler": axis.scaleRangeFactorStart(newRangeFactor[0]); break; case "endHandler": axis.scaleRangeFactorEnd(newRangeFactor[1]); break; default: axis.scaleRangeFactorEnd(newRangeFactor[1], !0), axis.scaleRangeFactorStart(newRangeFactor[0]); } const newFactor = axisScale.rangeFactor(); newFactor ? (this._start = reverse ? 1 - newFactor[1] : newFactor[0], this._end = reverse ? 1 - newFactor[0] : newFactor[1]) : (this._start = 0, this._end = 1); } get visible() { return this._visible; } constructor(spec, options) { super(spec, options), this.layoutType = "none", this._orient = "left", this._cacheVisibility = void 0, this._dataUpdating = !1, this._hasInitStateScale = !1, this._shouldChange = !0, this._stateField = "x", this._handleStateChange = (startValue, endValue, tag) => { var _a, _b; return this._startValue = startValue, this._endValue = endValue, this._newDomain = (0, util_1.parseDomainFromState)(this._startValue, this._endValue, this._stateScale), null === (_b = (_a = this.effect).onZoomChange) || void 0 === _b || _b.call(_a, tag), !0; }, this.effect = { onZoomChange: tag => { var _a, _b; const axis = this._relatedAxisComponent; if (axis && "axis" === this._filterMode) { const axisScale = axis.getScale(), axisSpec = axis.getSpec(); this._auto && (0, util_1.getAxisBandSize)(axisSpec) && this._spec.ignoreBandSize && (axisScale.bandwidth("auto"), axisScale.maxBandwidth("auto"), axisScale.minBandwidth("auto")), this._updateRangeFactor(tag), this._auto && (null === (_b = null === (_a = this._component) || void 0 === _a ? void 0 : _a.setStartAndEnd) || void 0 === _b || _b.call(_a, this._start, this._end)), axis.effect.scaleUpdate({ value: "force" }); } else (0, model_1.eachSeries)(this._regions, (s => { var _a; null === (_a = s.getViewData()) || void 0 === _a || _a.markRunning(); }), { userId: this._seriesUserId, specIndex: this._seriesIndex }), (0, model_1.eachSeries)(this._regions, (s => { s.reFilterViewData(); }), { userId: this._seriesUserId, specIndex: this._seriesIndex }); } }, this._visible = !0, this._orient = (0, common_1.getOrient)(spec), this._isHorizontal = "horizontal" === (0, common_1.getDirectionByOrient)(this._orient), this._dataFilterEvent = new data_filter_event_1.DataFilterEvent(this.type, this._spec, this._handleChange.bind(this), this.getLayoutRect.bind(this), (() => ({ start: this._start, end: this._end })), (() => this._regions), (() => this._option).bind(this), (() => this.event)); } created() { super.created(), this._setAxisFromSpec(), this._setRegionsFromSpec(), this._initEvent(), this._initData(), this._initStateScale(), this._setStateFromSpec(); } initLayout() { super.initLayout(), this._layout && (this._layout.layoutOrient = this._orient); } init(option) { super.init(option), this._addTransformToSeries(), 0 === this._start && 1 === this._end || this.effect.onZoomChange(); } _compareSpec(spec, prevSpec) { const result = super._compareSpec(spec, prevSpec); return result.reMake || (0, vutils_1.isEqual)(prevSpec, spec) || (result.reRender = !0, result.reMake = !0), result; } reInit(spec) { super.reInit(spec), this._marks.forEach((g => { g.getMarks().forEach((m => { this.initMarkStyleWithSpec(m, this._spec[m.name]); })); })); } onLayoutStart(layoutRect, viewRect) { super.onLayoutStart(layoutRect, viewRect); const isShown = this._autoUpdate(layoutRect); this._autoVisible(isShown), this._dataUpdating = !1; } updateLayoutAttribute() { this._visible && this._createOrUpdateComponent(), this._hasInitStateScale || (0 === this._start && 1 === this._end || (this._newDomain = (0, util_1.parseDomainFromStateAndValue)(this._spec.start, this._startValue, this._spec.end, this._endValue, this._stateScale), this.effect.onZoomChange()), this._hasInitStateScale = !0); } _initAfterLayout() { this._stateScale = null, this._initStateScale(), this._updateScaleRange(), this._setStateFromAxis(); } _beforeLayoutEnd() { this._hasInitStateScale ? this._updateScaleRange() : this._initAfterLayout(); } onLayoutEnd() { var _a; this._beforeLayoutEnd(); const isShown = !(0 === this._start && 1 === this._end); this._autoVisible(isShown), super.onLayoutEnd(), null === (_a = this._relatedAxisComponent) || void 0 === _a || _a.updateScaleRange(); } getBoundsInRect(rect) { const result = { x1: this.getLayoutStartPoint().x, y1: this.getLayoutStartPoint().y, x2: 0, y2: 0 }; return this._isHorizontal ? (result.y2 = result.y1 + this._height, result.x2 = result.x1 + rect.width) : (result.x2 = result.x1 + this._width, result.y2 = result.y1 + rect.height), result; } setAttrFromSpec() { var _a; super.setAttrFromSpec(), this._dataFilterEvent.setEventAttrFromSpec(), this._field = this._spec.field, this._width = this._computeWidth(), this._height = this._computeHeight(), this._visible = null === (_a = this._spec.visible) || void 0 === _a || _a; } _setAxisFromSpec() { if ((0, vutils_1.isValid)(this._spec.axisId) ? this._relatedAxisComponent = this._option.getComponentByUserId(this._spec.axisId) : (0, vutils_1.isValid)(this._spec.axisIndex) && (this._relatedAxisComponent = this._option.getComponentByIndex("axes", this._spec.axisIndex)), (0, vutils_1.isNil)(this._spec.field) && !this._relatedAxisComponent) { const axes = this._option.getComponentsByKey("axes"), sameOrientAxis = axes.find((cm => (0, common_1.getDirectionByOrient)(cm._orient) === (0, common_1.getDirectionByOrient)(this._orient))); if (sameOrientAxis) this._relatedAxisComponent = sameOrientAxis; else { const bandAxis = axes.find((cm => !(0, vscale_1.isContinuous)(cm.getScale().type))); this._relatedAxisComponent = bandAxis; } } this._relatedAxisComponent && "axis" === this._filterMode && (this._relatedAxisComponent.autoIndentOnce = !0); } _setRegionsFromSpec() { var _a, _b; this._regions = this._relatedAxisComponent ? this._relatedAxisComponent.getRegions() : this._option.getAllRegions(); const bindSeriesFilter = this._relatedAxisComponent ? null === (_b = (_a = this._relatedAxisComponent).getBindSeriesFilter) || void 0 === _b ? void 0 : _b.call(_a) : null; if ((0, vutils_1.isValid)(bindSeriesFilter) && ((0, vutils_1.isValid)(bindSeriesFilter.userId) && (this._seriesUserId = (0, vutils_1.array)(bindSeriesFilter.userId)), (0, vutils_1.isValid)(bindSeriesFilter.specIndex) && (this._seriesIndex = (0, vutils_1.array)(bindSeriesFilter.specIndex))), (0, vutils_1.isValid)(this._spec.seriesId)) { const specSeriesId = (0, vutils_1.array)(this._spec.seriesId); this._seriesUserId ? this._seriesUserId = this._seriesUserId.filter((s => specSeriesId.includes(s))) : this._seriesUserId = specSeriesId; } if ((0, vutils_1.isValid)(this._spec.seriesIndex)) { const specSeriesIndex = (0, vutils_1.array)(this._spec.seriesIndex); this._seriesIndex ? this._seriesIndex = this._seriesIndex.filter((s => specSeriesIndex.includes(s))) : this._seriesIndex = specSeriesIndex; } if ((0, vutils_1.isValid)(this._spec.regionIndex)) { const regionsFromSpec = this._option.getRegionsInIndex((0, vutils_1.array)(this._spec.regionIndex)); this._regions = this._regions.filter((r => regionsFromSpec.includes(r))); } else if ((0, vutils_1.isValid)(this._spec.regionId)) { const ids = (0, vutils_1.array)(this._spec.regionId); this._regions = ids.length ? this._regions.filter((r => ids.includes(r.id))) : []; } else ; } _initData() { const dataCollection = [], seriesCollection = [], stateFields = [], valueFields = []; let isCategoryState; if (this._relatedAxisComponent) { const originalStateFields = {}; (0, model_1.eachSeries)(this._regions, (s => { var _a, _b; const xAxisHelper = "cartesian" === s.coordinate ? s.getXAxisHelper() : "polar" === s.coordinate ? s.angleAxisHelper : null, yAxisHelper = "cartesian" === s.coordinate ? s.getYAxisHelper() : "polar" === s.coordinate ? s.radiusAxisHelper : null; if (!xAxisHelper || !yAxisHelper) return; const stateAxisHelper = xAxisHelper.getAxisId() === this._relatedAxisComponent.id ? xAxisHelper : yAxisHelper.getAxisId() === this._relatedAxisComponent.id ? yAxisHelper : this._isHorizontal ? xAxisHelper : yAxisHelper, valueAxisHelper = stateAxisHelper === xAxisHelper ? yAxisHelper : xAxisHelper, isValidateValueAxis = (0, vscale_1.isContinuous)(valueAxisHelper.getScale(0).type), isValidateStateAxis = (0, vscale_1.isContinuous)(stateAxisHelper.getScale(0).type); dataCollection.push(s.getRawData()); const seriesSpec = s.getSpec(), xField = "cartesian" === s.coordinate ? (0, vutils_1.array)(seriesSpec.xField) : (0, vutils_1.array)(null !== (_a = seriesSpec.angleField) && void 0 !== _a ? _a : seriesSpec.categoryField), yField = "cartesian" === s.coordinate ? (0, vutils_1.array)(seriesSpec.yField) : (0, vutils_1.array)(null !== (_b = seriesSpec.radiusField) && void 0 !== _b ? _b : seriesSpec.valueField); if (originalStateFields[s.id] = "link" === s.type ? [ "from_xField" ] : stateAxisHelper === xAxisHelper ? xField : yField, isValidateStateAxis ? (isCategoryState = !1, stateFields.push(originalStateFields[s.id])) : (isCategoryState = !0, stateFields.push(originalStateFields[s.id][0])), this._valueField) { const valueField = "link" === s.type ? [ "from_yField" ] : valueAxisHelper === xAxisHelper ? xField : yField; isValidateValueAxis && valueFields.push(...valueField); } }), { userId: this._seriesUserId, specIndex: this._seriesIndex }), this._originalStateFields = originalStateFields; } else (0, model_1.eachSeries)(this._regions, (s => { dataCollection.push(s.getRawData()), seriesCollection.push(s), stateFields.push(this._field), this._valueField && valueFields.push(this._spec.valueField); }), { userId: this._seriesUserId, specIndex: this._seriesIndex }); const {dataSet: dataSet} = this._option; (0, register_1.registerDataSetInstanceParser)(dataSet, "dataview", vdataset_1.dataViewParser), (0, register_1.registerDataSetInstanceTransform)(dataSet, "dataFilterComputeDomain", util_1.dataFilterComputeDomain); const data = new vdataset_1.DataView(dataSet, { name: `${this.type}_${this.id}_data` }); data.transform({ type: "dataFilterComputeDomain", options: { input: { dataCollection: dataCollection, seriesCollection: seriesCollection, stateFields: stateFields, valueFields: valueFields, isCategoryState: isCategoryState }, output: { stateField: this._stateField, valueField: this._valueField } } }, !1), this._data = new compilable_data_1.CompilableData(this._option, data), data.reRunAllTransform(), dataSet.multipleDataViewAddListener(dataCollection, "change", this._handleDataCollectionChange.bind(this)); } _addTransformToSeries() { this._relatedAxisComponent && "axis" === this._filterMode || ((0, register_1.registerDataSetInstanceTransform)(this._option.dataSet, "dataFilterWithNewDomain", util_1.dataFilterWithNewDomain), (0, register_1.registerDataSetInstanceTransform)(this._option.dataSet, "lockStatisticsFilter", util_1.lockStatisticsFilter), (0, model_1.eachSeries)(this._regions, (s => { s.getViewDataStatistics().transform({ type: "lockStatisticsFilter", options: { originalFields: () => s.getViewDataStatistics().getFields(), getNewDomain: () => this._newDomain, field: () => { var _a; return null !== (_a = this._field) && void 0 !== _a ? _a : this._parseFieldOfSeries(s); }, isContinuous: () => (0, vscale_1.isContinuous)(this._stateScale.type) }, level: 1 }, !1), s.addViewDataFilter({ type: "dataFilterWithNewDomain", options: { getNewDomain: () => this._newDomain, field: () => { var _a; return null !== (_a = this._field) && void 0 !== _a ? _a : this._parseFieldOfSeries(s); }, isContinuous: () => (0, vscale_1.isContinuous)(this._stateScale.type) }, level: initialize_1.TransformLevel.dataZoomFilter }); }), { userId: this._seriesUserId, specIndex: this._seriesIndex })); } onDataUpdate() { var _a; const domain = this._computeDomainOfStateScale((0, vscale_1.isContinuous)(this._stateScale.type)); this._stateScale.domain(domain, !1), this._handleChange(this._start, this._end, !0), this._spec.auto && !(0, vutils_1.isEqual)(this._domainCache, domain) && (this._domainCache = domain, this._dataUpdating = !0, null === (_a = this.getChart()) || void 0 === _a || _a.setLayoutTag(!0, null, !1)); } _parseFieldOfSeries(s) { var _a; return null === (_a = this._originalStateFields) || void 0 === _a ? void 0 : _a[s.id]; } _setStateFromSpec() { let start, end; if (this._auto = !!this._spec.auto, this._spec.rangeMode) { const [startMode, endMode] = this._spec.rangeMode; (0, util_1.modeCheck)("start", startMode, this._spec) && (0, util_1.modeCheck)("end", endMode, this._spec) && (start = "percent" === startMode ? this._spec.start : (0, util_1.dataToStatePoint)(this._spec.startValue, this._stateScale, this._isHorizontal), end = "percent" === endMode ? this._spec.end : (0, util_1.dataToStatePoint)(this._spec.endValue, this._stateScale, this._isHorizontal)); } else start = this._spec.start ? this._spec.start : this._spec.startValue ? (0, util_1.dataToStatePoint)(this._spec.startValue, this._stateScale, this._isHorizontal) : 0, end = this._spec.end ? this._spec.end : this._spec.endValue ? (0, util_1.dataToStatePoint)(this._spec.endValue, this._stateScale, this._isHorizontal) : 1; this._start = Math.max(0, Math.min(1, start)), this._end = Math.max(0, Math.min(1, end)); } _setStateFromAxis() { var _a, _b; this._setStateFromSpec(); const axis = this._relatedAxisComponent; this._startValue = (0, util_1.statePointToData)(this._start, this._stateScale, (0, util_1.isReverse)(axis, this._isHorizontal)), this._endValue = (0, util_1.statePointToData)(this._end, this._stateScale, (0, util_1.isReverse)(axis, this._isHorizontal)), this._minSpan = null !== (_a = this._spec.minSpan) && void 0 !== _a ? _a : 0, this._maxSpan = null !== (_b = this._spec.maxSpan) && void 0 !== _b ? _b : 1, (0, vscale_1.isContinuous)(this._stateScale.type) && this._stateScale.domain()[0] !== (0, vutils_1.last)(this._stateScale.domain()) && (this._spec.minValueSpan && (this._minSpan = this._spec.minValueSpan / ((0, vutils_1.last)(this._stateScale.domain()) - this._stateScale.domain()[0])), this._spec.maxValueSpan && (this._maxSpan = this._spec.maxValueSpan / ((0, vutils_1.last)(this._stateScale.domain()) - this._stateScale.domain()[0]))), this._minSpan = Math.max(0, this._minSpan), this._maxSpan = Math.min(this._maxSpan, 1), axis && (axis && "axis" === this._filterMode || 0 === this._start && 1 === this._end || (this._newDomain = (0, util_1.parseDomainFromState)(this._startValue, this._endValue, this._stateScale))); } _initStateScale() { var _a, _b, _c, _d, _e, _f; const defaultRange = [ 0, 1 ]; if (this._relatedAxisComponent) { const scale = this._relatedAxisComponent.getScale().clone(); this._stateScale = scale, null === (_b = (_a = scale).maxBandwidth) || void 0 === _b || _b.call(_a, "auto", !0), null === (_d = (_c = scale).minBandwidth) || void 0 === _d || _d.call(_c, "auto", !0), null === (_f = (_e = scale).bandwidth) || void 0 === _f || _f.call(_e, "auto", !0), scale.rangeFactor(defaultRange, !0).range(defaultRange); } else { let fieldLinear = !0; this._field && (0, model_1.eachSeries)(this._regions, (s => { const stats = s.getRawDataStatisticsByField(this._field); (0, vutils_1.isValidNumber)(null == stats ? void 0 : stats.min) && (0, vutils_1.isValidNumber)(null == stats ? void 0 : stats.max) || (fieldLinear = !1); }), { userId: this._seriesUserId, specIndex: this._seriesIndex }), this._stateScale = fieldLinear ? new vscale_1.LinearScale : new vscale_1.BandScale, this._stateScale.domain(this._computeDomainOfStateScale(fieldLinear), !0).range(defaultRange); } } _computeDomainOfStateScale(isContinuous) { if (this._spec.customDomain) return this._spec.customDomain; const domain = this._data.getLatestData().map((d => d[this._stateField])); if (isContinuous) { const domainNum = domain.map((n => 1 * n)); return domain.length ? [ (0, vutils_1.minInArray)(domainNum), (0, vutils_1.maxInArray)(domainNum) ] : [ -1 / 0, 1 / 0 ]; } return domain; } _autoVisible(isShown) { if (!this._auto) return; isShown ? this.show() : this.hide(); const sizeKey = this._isHorizontal ? "height" : "width"; this.layout.setLayoutRect({ [sizeKey]: isShown ? this[`_${sizeKey}`] : 0 }, { [sizeKey]: attribute_1.AttributeLevel.Built_In }); } hide() { var _a; null === (_a = this._component) || void 0 === _a || _a.hideAll(); } show() { var _a; null === (_a = this._component) || void 0 === _a || _a.showAll(); } _autoUpdate(rect) { var _a, _b, _c, _d, _e, _f; if (!this._auto) return this._cacheVisibility = void 0, !0; const axis = this._relatedAxisComponent, axisSpec = null == axis ? void 0 : axis.getSpec(), axisScale = null == axis ? void 0 : axis.getScale(), bandSizeResult = (0, util_1.getAxisBandSize)(axisSpec); if (!this._dataUpdating && (0, vscale_1.isDiscrete)(axisScale.type) && (null == rect ? void 0 : rect.height) === (null === (_a = this._cacheRect) || void 0 === _a ? void 0 : _a.height) && (null == rect ? void 0 : rect.width) === (null === (_b = this._cacheRect) || void 0 === _b ? void 0 : _b.width) && this._fixedBandSize === (null == bandSizeResult ? void 0 : bandSizeResult.bandSize)) return this._cacheVisibility; let isShown = !0; if (this._isHorizontal && (null == rect ? void 0 : rect.width) !== (null === (_c = this._cacheRect) || void 0 === _c ? void 0 : _c.width) ? axisScale.range(axis.getInverse() ? [ rect.width, 0 ] : [ 0, rect.width ]) : (null == rect ? void 0 : rect.height) !== (null === (_d = this._cacheRect) || void 0 === _d ? void 0 : _d.height) && axisScale.range(axis.getInverse() ? [ 0, rect.height ] : [ rect.height, 0 ]), this._cacheRect = { width: null == rect ? void 0 : rect.width, height: null == rect ? void 0 : rect.height }, this._fixedBandSize = null == bandSizeResult ? void 0 : bandSizeResult.bandSize, (0, vscale_1.isDiscrete)(axisScale.type)) { bandSizeResult && (this._start || this._end) && (this.type === interface_1.ComponentTypeEnum.scrollBar && (this._start = 0, this._end = 1), this._updateRangeFactor()); const [start, end] = null !== (_e = axisScale.rangeFactor()) && void 0 !== _e ? _e : []; isShown = (!(0, vutils_1.isNil)(start) || !(0, vutils_1.isNil)(end)) && !(0 === start && 1 === end); } else { const [start, end] = null !== (_f = axisScale.rangeFactor()) && void 0 !== _f ? _f : [ this._start, this._end ]; isShown = !(0 === start && 1 === end); } return this.setStartAndEnd(this._start, this._end), this._cacheVisibility = isShown, isShown; } _getNeedClearVRenderComponents() { return [ this._component ]; } } exports.DataFilterBaseComponent = DataFilterBaseComponent, (0, vutils_1.mixin)(DataFilterBaseComponent, zoomable_1.Zoomable); //# sourceMappingURL=data-filter-base-component.js.map