@visactor/vchart
Version:
charts lib based @visactor/VGrammar
435 lines (410 loc) • 22.9 kB
JavaScript
var __rest = this && this.__rest || function(s, e) {
var t = {};
for (var p in s) Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0 && (t[p] = s[p]);
if (null != s && "function" == typeof Object.getOwnPropertySymbols) {
var i = 0;
for (p = Object.getOwnPropertySymbols(s); i < p.length; i++) e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]) && (t[p[i]] = s[p[i]]);
}
return t;
};
import { isContinuous } from "@visactor/vscale";
import { BaseComponent } from "../base/base-component";
import { CompilableData } from "../../compile/data";
import { AxisEnum, GridEnum } from "./interface";
import { ComponentTypeEnum } from "../interface";
import { eachSeries, getSeries } from "../../util/model";
import { mergeSpec } from "@visactor/vutils-extension";
import { ChartEvent } from "../../constant/event";
import { LayoutZIndex } from "../../constant/layout";
import { animationConfig } from "../../animation/utils";
import { degreeToRadian, pickWithout, isEqual, array, get, isArray, isFunction, isNil, isValid, maxInArray } from "@visactor/vutils";
import { DEFAULT_TITLE_STYLE, transformAxisLineStyle } from "./util";
import { transformAxisLabelStateStyle, transformStateStyle, transformToGraphic } from "../../util/style";
import { DataView } from "@visactor/vdataset";
import { registerComponentMark } from "../../mark/component";
import { Factory } from "../../core/factory";
import { AXIS_ELEMENT_NAME } from "@visactor/vrender-components";
import { scaleParser } from "../../data/parser/scale";
import { registerDataSetInstanceParser } from "../../data/register";
import { getFormatFunction } from "../util";
import { transformFunctionAttribute } from "../../util/spec/transform";
export class AxisComponent extends BaseComponent {
getOrient() {
return this._orient;
}
getScale() {
return this._scale;
}
getScales() {
return this._scales;
}
getTickData(index = 0) {
return this._tickData[index];
}
get visible() {
return this._visible;
}
getInverse() {
return this._inverse;
}
getCoordinateType() {
return this._coordinateType;
}
constructor(spec, options) {
var _a;
super(spec, options), this.specKey = "axes", this._scales = [], this._tickData = [],
this._visible = !0, this._tick = void 0, this._onTickDataChange = tickData => {
this._forceLayout(), null == tickData || tickData.updateData();
}, this._visible = null === (_a = spec.visible) || void 0 === _a || _a, this._coordinateType = "none";
}
getVRenderComponents() {
var _a, _b;
return [ null === (_a = this._axisMark) || void 0 === _a ? void 0 : _a.getProduct(), null === (_b = this._gridMark) || void 0 === _b ? void 0 : _b.getProduct() ].filter(isValid);
}
created() {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
if (super.created(), this.setSeriesAndRegionsFromSpec(), this.initEvent(), this.initScales(),
this.updateSeriesScale(), this._shouldComputeTickData() && this._initData(), this._visible) {
const axisMark = this._createMark({
type: "component",
name: `axis-${this.getOrient()}`
}, {
componentType: "angle" === this.getOrient() ? AxisEnum.circleAxis : AxisEnum.lineAxis,
mode: this._spec.mode
}, {
skipTheme: !0
});
if (this._updateTickDataMarks(axisMark), this._axisMark = axisMark, axisMark.setMarkConfig({
zIndex: this.layoutZIndex
}), isValid(this._spec.id) && axisMark.setUserId(this._spec.id), axisMark.setMarkConfig({
interactive: null !== (_a = this._spec.interactive) && void 0 !== _a ? _a : this.getDefaultInteractive()
}), this._marks.addMark(axisMark), null === (_b = this._spec.grid) || void 0 === _b ? void 0 : _b.visible) {
const gridMark = this._createMark({
type: "component",
name: `axis-${this.getOrient()}-grid`
}, {
componentType: "angle" === this.getOrient() ? GridEnum.circleAxisGrid : GridEnum.lineAxisGrid,
mode: this._spec.mode
}, {
skipTheme: !0
});
this._updateTickDataMarks(gridMark), gridMark.setMarkConfig({
zIndex: null !== (_g = null !== (_e = null === (_d = null === (_c = this._spec.grid) || void 0 === _c ? void 0 : _c.style) || void 0 === _d ? void 0 : _d.zIndex) && void 0 !== _e ? _e : null === (_f = this._spec.grid) || void 0 === _f ? void 0 : _f.zIndex) && void 0 !== _g ? _g : LayoutZIndex.Axis_Grid,
interactive: !1
}), this._marks.addMark(gridMark), this._gridMark = gridMark;
}
if ((null === (_h = this._option.globalInstance) || void 0 === _h ? void 0 : _h.isAnimationEnable()) && !1 !== get(this._option.getChart().getSpec(), "animation") && !0 === this._spec.animation) {
const axisAnimateConfig = animationConfig(null === (_j = Factory.getAnimationInKey("axis")) || void 0 === _j ? void 0 : _j(), {
appear: null !== (_l = null !== (_k = this._spec.animationAppear) && void 0 !== _k ? _k : get(this._option.getChart().getSpec(), "animationAppear.axis")) && void 0 !== _l ? _l : get(this._option.getChart().getSpec(), "animationAppear"),
disappear: null !== (_o = null !== (_m = this._spec.animationDisappear) && void 0 !== _m ? _m : get(this._option.getChart().getSpec(), "animationDisappear.axis")) && void 0 !== _o ? _o : get(this._option.getChart().getSpec(), "animationDisappear"),
enter: null !== (_q = null !== (_p = this._spec.animationEnter) && void 0 !== _p ? _p : get(this._option.getChart().getSpec(), "animationEnter.axis")) && void 0 !== _q ? _q : get(this._option.getChart().getSpec(), "animationEnter"),
exit: null !== (_s = null !== (_r = this._spec.animationExit) && void 0 !== _r ? _r : get(this._option.getChart().getSpec(), "animationExit.axis")) && void 0 !== _s ? _s : get(this._option.getChart().getSpec(), "animationExit"),
update: null !== (_u = null !== (_t = this._spec.animationUpdate) && void 0 !== _t ? _t : get(this._option.getChart().getSpec(), "animationUpdate.axis")) && void 0 !== _u ? _u : get(this._option.getChart().getSpec(), "animationUpdate")
});
axisAnimateConfig.enter && (axisAnimateConfig.update[0].customParameters = {
enter: axisAnimateConfig.enter[0]
}), this._marks.forEach((m => m.setAnimationConfig(axisAnimateConfig)));
}
}
}
_shouldComputeTickData() {
return this.getVisible() || this._spec.forceInitTick;
}
_initData() {
const tickData = this._initTickDataSet(this._tickTransformOption()), tickDataCompile = new CompilableData(this._option, tickData);
this._tickData = [ tickDataCompile ], tickData.target.addListener("change", (() => {
this._onTickDataChange(tickDataCompile);
}));
}
collectData(depth, rawData) {
const data = [];
return eachSeries(this._regions, (s => {
var _a;
let field = this.collectSeriesField(depth, s);
if (field = isArray(field) ? isContinuous(this._scale.type) ? field : [ field[0] ] : [ field ],
depth || (this._dataFieldText = s.getFieldAlias(field[0])), field) {
const viewData = s.getViewData();
if (rawData) field.forEach((f => {
data.push(s.getRawDataStatisticsByField(f, !!isContinuous(this._scale.type)));
})); else if (viewData && viewData.latestData && viewData.latestData.length) {
const seriesData = null === (_a = s.getViewDataStatistics) || void 0 === _a ? void 0 : _a.call(s), userSetBreaks = this.type === ComponentTypeEnum.cartesianLinearAxis && this._spec.breaks && this._spec.breaks.length;
field.forEach((f => {
var _a;
(null === (_a = null == seriesData ? void 0 : seriesData.latestData) || void 0 === _a ? void 0 : _a[f]) && (userSetBreaks ? data.push(Object.assign(Object.assign({}, seriesData.latestData[f]), {
values: viewData.latestData.map((obj => obj[f]))
})) : data.push(seriesData.latestData[f]));
}));
}
}
}), {
userId: this._seriesUserId,
specIndex: this._seriesIndex
}), data;
}
isSeriesDataEnable() {
let enable = !0;
return eachSeries(this._regions, (s => {
var _a;
isArray(null === (_a = s.getViewDataStatistics()) || void 0 === _a ? void 0 : _a.latestData) && (enable = !1);
}), {
userId: this._seriesUserId,
specIndex: this._seriesIndex
}), enable;
}
setSeriesAndRegionsFromSpec() {
const {seriesId: seriesId, seriesIndex: seriesIndex, regionId: regionId, regionIndex: regionIndex} = this._spec;
isValid(seriesId) && (this._seriesUserId = array(seriesId)), isValid(regionId) && (this._regionUserId = array(regionId)),
isValid(seriesIndex) && (this._seriesIndex = array(seriesIndex)), isValid(regionIndex) && (this._regionIndex = array(regionIndex)),
this._regions = this._option.getRegionsInUserIdOrIndex(this._regionUserId, this._regionIndex),
this.layout.layoutBindRegionID = this._regions.map((x => x.id));
}
getBindSeriesFilter() {
return {
userId: this._seriesUserId,
specIndex: this._seriesIndex
};
}
initEvent() {
this.event.on(ChartEvent.scaleUpdate, {
filter: ({model: model}) => (null == model ? void 0 : model.id) === this.id
}, this.effect.scaleUpdate.bind(this));
const viewStatistics = getSeries(this._regions, {
userId: this._seriesUserId,
specIndex: this._seriesIndex
}).map((s => s.getViewDataStatistics())).filter((v => !!v));
viewStatistics.length > 1 ? this._option.dataSet.multipleDataViewAddListener(viewStatistics, "change", (() => {
this.updateScaleDomain();
})) : 1 === viewStatistics.length && viewStatistics[0].target.addListener("change", (() => {
this.updateScaleDomain();
})), eachSeries(this._regions, (s => {
s.event.on(ChartEvent.rawDataUpdate, {
filter: ({model: model}) => (null == model ? void 0 : model.id) === s.id
}, (() => {
this._clearRawDomain();
}));
}), {
userId: this._seriesUserId,
specIndex: this._seriesIndex
});
}
updateScaleDomain() {}
_clearRawDomain() {}
onLayoutEnd() {
this.updateScaleRange();
this.event.emit(ChartEvent.scaleUpdate, {
model: this,
value: "range"
}), super.onLayoutEnd();
}
computeData(updateType) {
"force" !== updateType || this._tickData && this._tickData.length ? !this._tickData || !this._tickData.length || "force" !== updateType && isEqual(this._scale.range(), [ 0, 1 ]) || this._tickData.forEach((tickData => {
tickData.getDataView().reRunAllTransform({
skipEqual: !0
});
})) : eachSeries(this._regions, (s => {
var _a;
null === (_a = s.getViewData()) || void 0 === _a || _a.reRunAllTransform();
}), {
userId: this._seriesUserId,
specIndex: this._seriesIndex
});
}
_updateTickDataMarks(m) {
this._tickData && this._tickData.forEach((d => {
d.addRelatedMark(m);
}));
}
initScales() {
this._scales = [ this._scale ];
const groups = [];
if (eachSeries(this._regions, (s => {
const g = s.getGroups();
g && groups.push(g);
}), {
userId: this._seriesUserId,
specIndex: this._seriesIndex
}), 0 !== groups.length) {
const depth = maxInArray(groups.map((g => g.fields.length)));
for (let i = 1; i < depth; i++) {
const scale = this._scale.clone();
this._scales.push(scale);
}
}
}
_compareSpec(spec, prevSpec) {
const result = super._compareSpec(spec, prevSpec);
return result.reMake ? result : (result.reRender = !0, (null == prevSpec ? void 0 : prevSpec.type) !== (null == spec ? void 0 : spec.type) || (null == prevSpec ? void 0 : prevSpec.visible) !== (null == spec ? void 0 : spec.visible) ? (result.reMake = !0,
result) : (result.reMake = [ "grid", "subGrid", "tick", "subTick", "label", "domainLine", "title" ].some((k => {
var _a, _b;
return (null === (_a = null == prevSpec ? void 0 : prevSpec[k]) || void 0 === _a ? void 0 : _a.visible) !== (null === (_b = null == spec ? void 0 : spec[k]) || void 0 === _b ? void 0 : _b.visible);
})), result));
}
_getAxisAttributes() {
const spec = this._spec, axisAttrs = {
orient: this.getOrient(),
select: !0 !== this._option.disableTriggerEvent && spec.select,
hover: !0 !== this._option.disableTriggerEvent && spec.hover
};
if (spec.domainLine && spec.domainLine.visible ? axisAttrs.line = transformAxisLineStyle(spec.domainLine) : axisAttrs.line = {
visible: !1
}, spec.label && spec.label.visible) {
const labelSpec = pickWithout(spec.label, [ "style", "formatMethod", "state" ]);
axisAttrs.label = labelSpec, spec.label.style && (axisAttrs.label.style = isFunction(spec.label.style) ? (datum, index, data, layer) => {
var _a;
const style = spec.label.style(datum.rawValue, index, datum, data, layer);
return transformToGraphic(mergeSpec({}, null === (_a = this._theme.label) || void 0 === _a ? void 0 : _a.style, style));
} : transformToGraphic(spec.label.style)), (spec.label.formatMethod || spec.label.formatter) && (axisAttrs.label.formatMethod = this._getLabelFormatMethod()),
spec.label.state && (axisAttrs.label.state = transformAxisLabelStateStyle(spec.label.state)),
isFunction(spec.label.dataFilter) && (axisAttrs.label.dataFilter = (data, layer) => spec.label.dataFilter(data, layer, {
vchart: this._option.globalInstance
}));
} else axisAttrs.label = {
visible: !1
};
if (spec.tick && spec.tick.visible ? (axisAttrs.tick = {
visible: spec.tick.visible,
length: spec.tick.tickSize,
inside: spec.tick.inside,
alignWithLabel: spec.tick.alignWithLabel,
dataFilter: isFunction(spec.tick.dataFilter) ? data => spec.tick.dataFilter(data, {
vchart: this._option.globalInstance
}) : void 0
}, spec.tick.style && (axisAttrs.tick.style = isFunction(spec.tick.style) ? (value, index, datum, data) => {
var _a;
const style = spec.tick.style(value, index, datum, data);
return transformToGraphic(mergeSpec({}, null === (_a = this._theme.tick) || void 0 === _a ? void 0 : _a.style, style));
} : transformToGraphic(spec.tick.style)), spec.tick.state && (axisAttrs.tick.state = transformStateStyle(spec.tick.state))) : axisAttrs.tick = {
visible: !1
}, spec.subTick && spec.subTick.visible ? (axisAttrs.subTick = {
visible: spec.subTick.visible,
length: spec.subTick.tickSize,
inside: spec.subTick.inside,
count: spec.subTick.tickCount
}, spec.subTick.style && (axisAttrs.subTick.style = isFunction(spec.subTick.style) ? (value, index, datum, data) => {
var _a;
const style = spec.subTick.style(value, index, datum, data);
return transformToGraphic(mergeSpec({}, null === (_a = this._theme.subTick) || void 0 === _a ? void 0 : _a.style, style));
} : transformToGraphic(spec.subTick.style)), spec.subTick.state && (axisAttrs.subTick.state = transformStateStyle(spec.subTick.state))) : axisAttrs.subTick = {
visible: !1
}, spec.title && spec.title.visible) {
const _a = spec.title, {autoRotate: autoRotate, angle: angle, style: titleStyle = {}, background: titleBackgroundSpec, state: titleState, shape: titleShapeSpec} = _a, restTitleAttrs = __rest(_a, [ "autoRotate", "angle", "style", "background", "state", "shape" ]);
let titleTextStyle, titleAngle = angle;
"left" !== spec.orient && "right" !== spec.orient || autoRotate && isNil(titleAngle) && (titleAngle = "left" === spec.orient ? -90 : 90,
titleTextStyle = DEFAULT_TITLE_STYLE[spec.orient]), axisAttrs.title = Object.assign(Object.assign({}, restTitleAttrs), {
autoRotate: !1,
angle: titleAngle ? degreeToRadian(titleAngle) : null,
textStyle: mergeSpec({}, titleTextStyle, transformToGraphic(titleStyle)),
pickable: !1 !== titleStyle.pickable,
childrenPickable: !1 !== titleStyle.pickable,
state: {}
}), titleShapeSpec && titleShapeSpec.visible ? (axisAttrs.title.shape = Object.assign(Object.assign({}, titleShapeSpec), {
style: transformToGraphic(titleShapeSpec.style)
}), titleShapeSpec.state && (axisAttrs.title.state.shape = transformStateStyle(titleShapeSpec.state))) : axisAttrs.title.shape = {
visible: !1
}, titleBackgroundSpec && titleBackgroundSpec.visible ? (axisAttrs.title.background = Object.assign(Object.assign({}, titleBackgroundSpec), {
style: transformToGraphic(titleBackgroundSpec.style)
}), titleBackgroundSpec.state && (axisAttrs.title.state.background = transformStateStyle(titleBackgroundSpec.state))) : axisAttrs.title.background = {
visible: !1
}, titleState && (axisAttrs.title.state.text = transformStateStyle(titleState));
} else axisAttrs.title = {
visible: !1
};
return spec.background && spec.background.visible ? (axisAttrs.panel = {
visible: !0
}, spec.background.style && (axisAttrs.panel.style = transformToGraphic(spec.background.style)),
spec.background.state && (axisAttrs.panel.state = transformStateStyle(spec.background.state))) : axisAttrs.panel = {
visible: !1
}, axisAttrs;
}
_getGridAttributes() {
const spec = this._spec;
return {
alternateColor: transformFunctionAttribute(spec.grid.alternateColor),
alignWithLabel: spec.grid.alignWithLabel,
style: isFunction(spec.grid.style) ? (datum, index) => {
var _a, _b;
const style = spec.grid.style(null === (_a = datum.datum) || void 0 === _a ? void 0 : _a.rawValue, index, datum.datum);
return transformToGraphic(mergeSpec({}, null === (_b = this._theme.grid) || void 0 === _b ? void 0 : _b.style, style));
} : transformToGraphic(spec.grid.style),
subGrid: !1 === spec.subGrid.visible ? {
visible: !1
} : {
type: "line",
visible: spec.subGrid.visible,
alternateColor: transformFunctionAttribute(spec.subGrid.alternateColor),
style: transformToGraphic(spec.subGrid.style)
}
};
}
_getLabelFormatMethod() {
const {formatMethod: formatMethod, formatter: formatter} = this._spec.label, {formatFunc: formatFunc} = getFormatFunction(formatMethod, formatter);
return formatFunc ? (value, datum, index) => formatFunc(datum.rawValue, datum, formatter) : null;
}
_initTickDataSet(options, index = 0) {
registerDataSetInstanceParser(this._option.dataSet, "scale", scaleParser);
const name = this.registerTicksTransform();
return new DataView(this._option.dataSet, {
name: `${this.type}_${this.id}_ticks_${index}`
}).parse(this._scales[index], {
type: "scale"
}).transform({
type: name,
options: options
}, !1);
}
_tickTransformOption() {
const tick = this._tick || {}, label = this._spec.label || {}, {tickCount: tickCount, forceTickCount: forceTickCount, tickStep: tickStep, tickMode: tickMode} = tick, {style: labelStyle, formatMethod: labelFormatter, minGap: labelGap} = label;
return {
sampling: !1 !== this._spec.sampling,
tickCount: tickCount,
forceTickCount: forceTickCount,
tickStep: tickStep,
tickMode: tickMode,
axisOrientType: this._orient,
coordinateType: this._coordinateType,
labelStyle: labelStyle,
labelFormatter: labelFormatter,
labelGap: labelGap
};
}
addTransformToTickData(options, execute) {
this._tickData.forEach((tickData => {
var _a;
null === (_a = null == tickData ? void 0 : tickData.getDataView()) || void 0 === _a || _a.transform(options, execute);
}));
}
dataToPosition(values) {
return this._scale.scale(values);
}
getDatum(childGraphic) {
var _a;
return childGraphic && childGraphic.name === AXIS_ELEMENT_NAME.label ? childGraphic.data : this._axisMark ? null === (_a = this._axisMark.getComponent()) || void 0 === _a ? void 0 : _a.attribute.items : void 0;
}
scaleRangeFactor(_, slience, clear) {
return this._onTickDataChange(this.getTickData()), this.getScale().rangeFactor(_, slience, clear);
}
scaleRangeFactorEnd(_, slience, clear) {
return this._onTickDataChange(this.getTickData()), this.getScale().rangeFactorEnd(_, slience);
}
scaleRangeFactorStart(_, slience, clear) {
return this._onTickDataChange(this.getTickData()), this.getScale().rangeFactorStart(_, slience);
}
}
AxisComponent.specKey = "axes";
export const registerAxis = () => {
registerComponentMark(), Factory.registerAnimation("axis", (() => ({
appear: {
type: "fadeIn"
},
enter: {
type: "fadeIn"
},
update: {
type: "update"
},
exit: {
type: "fadeOut"
}
})));
};
//# sourceMappingURL=base-axis.js.map