@visactor/vchart
Version:
charts lib based @visactor/VGrammar
422 lines (413 loc) • 25.5 kB
JavaScript
"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