@visactor/vchart
Version:
charts lib based @visactor/VGrammar
244 lines (230 loc) • 13.2 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 { mergeSpec } from "@visactor/vutils-extension";
import { Color } from "../../util/color";
import { createScaleWithSpec } from "../../util/scale";
import { GradientType, DEFAULT_GRADIENT_CONFIG } from "../../constant/gradient";
import { AttributeLevel } from "../../constant/attribute";
import { isValidScaleType } from "@visactor/vscale";
import { computeActualDataScheme, getDataScheme } from "../../theme/color-scheme/util";
import { CompilableMark } from "../../compile/mark/compilable-mark";
import { degreeToRadian, isBoolean, isFunction, isNil, isValid } from "@visactor/vutils";
import { curveTypeTransform } from "../utils";
export class BaseMark extends CompilableMark {
constructor(name, option) {
var _a;
super(option, name, option.model), this._extensionChannel = {}, this._computeExChannel = {},
this._attributeContext = option.attributeContext, null === (_a = option.map) || void 0 === _a || _a.set(this.id, this);
}
created() {
this._initStyle();
}
initStyleWithSpec(spec, key) {
spec && (isValid(spec.id) && (this._userId = spec.id), isBoolean(spec.interactive) && (this._markConfig.interactive = spec.interactive),
isValid(spec.zIndex) && (this._markConfig.zIndex = spec.zIndex), isBoolean(spec.visible) && this.setVisible(spec.visible),
this._initSpecStyle(spec, this.stateStyle, key));
}
_transformStyleValue(styleConverter, transform) {
if (styleConverter.scale) {
const scale = styleConverter.scale, range = scale.range();
return scale.range(range.map(transform)), styleConverter;
}
return "function" == typeof styleConverter ? (...args) => transform(styleConverter(...args)) : transform(styleConverter);
}
convertAngleToRadian(styleConverter) {
return this._transformStyleValue(styleConverter, degreeToRadian);
}
isUserLevel(level) {
return [ AttributeLevel.User_Mark, AttributeLevel.User_Series, AttributeLevel.User_Chart, AttributeLevel.User_SeriesStyle ].includes(level);
}
setStyle(style, state = "normal", level = 0, stateStyle = this.stateStyle) {
if (isNil(style)) return;
void 0 === stateStyle[state] && (stateStyle[state] = {});
const isUserLevel = this.isUserLevel(level);
Object.keys(style).forEach((attr => {
let attrStyle = style[attr];
isNil(attrStyle) || (attrStyle = this._filterAttribute(attr, attrStyle, state, level, isUserLevel, stateStyle),
this.setAttribute(attr, attrStyle, state, level, stateStyle));
}));
}
getStyle(key, state = "normal") {
var _a;
return null === (_a = this.stateStyle[state][key]) || void 0 === _a ? void 0 : _a.style;
}
_filterAttribute(attr, style, state, level, isUserLevel, stateStyle = this.stateStyle) {
let newStyle = this._styleConvert(style);
if (isUserLevel) switch (attr) {
case "angle":
newStyle = this.convertAngleToRadian(newStyle);
break;
case "innerPadding":
case "outerPadding":
newStyle = this._transformStyleValue(newStyle, (value => -value));
break;
case "curveType":
newStyle = this._transformStyleValue(newStyle, (value => curveTypeTransform(value, this._option.model.direction)));
}
return newStyle;
}
setReferer(mark, styleKey, state, stateStyle = this.stateStyle) {
var _a;
if (mark) if (styleKey && state) {
const style = null !== (_a = stateStyle[state]) && void 0 !== _a ? _a : {
[styleKey]: {}
};
stateStyle[state][styleKey] = Object.assign(Object.assign({}, style[styleKey]), {
referer: mark
});
} else Object.entries(stateStyle).forEach((([state, style]) => {
Object.entries(style).forEach((([styleKey, style]) => {
stateStyle[state][styleKey].referer = mark;
}));
}));
}
setPostProcess(key, postProcessFunc, state = "normal") {
var _a;
(null === (_a = this.stateStyle[state]) || void 0 === _a ? void 0 : _a[key]) && (this.stateStyle[state][key].postProcess = postProcessFunc);
}
getAttribute(key, datum, state = "normal", opt) {
return this._computeAttribute(key, state)(datum, opt);
}
setAttribute(attr, style, state = "normal", level = 0, stateStyle = this.stateStyle) {
var _a;
void 0 === stateStyle[state] && (stateStyle[state] = {}), void 0 === stateStyle[state][attr] && (stateStyle[state][attr] = {
level: level,
style: style,
referer: void 0
});
const attrLevel = null === (_a = stateStyle[state][attr]) || void 0 === _a ? void 0 : _a.level;
isValid(attrLevel) && attrLevel <= level && mergeSpec(stateStyle[state][attr], {
style: style,
level: level
}), "normal" !== state && attr in this._extensionChannel && this._extensionChannel[attr].forEach((key => {
void 0 === stateStyle[state][key] && (stateStyle[state][key] = stateStyle.normal[key]);
}));
}
_getDefaultStyle() {
return {
visible: !0,
x: 0,
y: 0
};
}
_styleConvert(style) {
if (!style) return style;
if (isValidScaleType(style.type) || style.scale) {
const scale = createScaleWithSpec(style, {
globalScale: this._option.globalScale,
seriesId: this._option.seriesId
});
if (scale) return {
scale: scale,
field: style.field,
changeDomain: style.changeDomain
};
}
return style;
}
_computeAttribute(key, state) {
var _a;
let stateStyle = null === (_a = this.stateStyle[state]) || void 0 === _a ? void 0 : _a[key];
stateStyle || (stateStyle = this.stateStyle.normal[key]);
const baseValueFunctor = this._computeStateAttribute(stateStyle, key, state), hasPostProcess = isFunction(null == stateStyle ? void 0 : stateStyle.postProcess), hasExCompute = key in this._computeExChannel;
if (hasPostProcess && hasExCompute) {
const exCompute = this._computeExChannel[key];
return (datum, opt) => {
let baseValue = baseValueFunctor(datum, opt);
return baseValue = stateStyle.postProcess(baseValue, datum, this._attributeContext, opt, this.getDataView()),
exCompute(key, datum, state, opt, baseValue);
};
}
if (hasPostProcess) return (datum, opt) => stateStyle.postProcess(baseValueFunctor(datum, opt), datum, this._attributeContext, opt, this.getDataView());
if (hasExCompute) {
const exCompute = this._computeExChannel[key];
return (datum, opt) => exCompute(key, datum, state, opt, baseValueFunctor(datum, opt));
}
return baseValueFunctor;
}
_computeStateAttribute(stateStyle, key, state) {
var _a;
return stateStyle ? stateStyle.referer ? stateStyle.referer._computeAttribute(key, state) : stateStyle.style ? "function" == typeof stateStyle.style ? (datum, opt) => stateStyle.style(datum, this._attributeContext, opt, this.getDataView()) : GradientType.includes(stateStyle.style.gradient) ? this._computeGradientAttr(stateStyle.style) : [ "outerBorder", "innerBorder" ].includes(key) ? this._computeBorderAttr(stateStyle.style) : isValidScaleType(null === (_a = stateStyle.style.scale) || void 0 === _a ? void 0 : _a.type) ? (datum, opt) => {
let data = datum;
return "series" === this.model.modelType && this.model.getMarkData && (data = this.model.getMarkData(datum)),
stateStyle.style.scale.scale(data[stateStyle.style.field]);
} : (datum, opt) => stateStyle.style : (datum, opt) => stateStyle.style : (datum, opt) => {};
}
_initStyle() {
const defaultStyle = this._getDefaultStyle();
this.setStyle(defaultStyle, "normal", 0);
}
_initSpecStyle(spec, stateStyle, key) {
spec.style && this.setStyle(spec.style, "normal", AttributeLevel.User_Mark, stateStyle);
const state = spec.state;
state && Object.keys(state).forEach((key => {
const stateTemp = state[key];
if ("style" in stateTemp) {
const style = stateTemp.style;
let stateInfo = {
stateValue: key
};
"level" in stateTemp && (stateInfo.level = stateTemp.level), "filter" in stateTemp && (stateInfo = isFunction(stateTemp.filter) ? Object.assign({
filter: stateTemp.filter
}, stateInfo) : Object.assign(Object.assign({}, stateTemp.filter), stateInfo)),
this.state.addStateInfo(stateInfo), this.setStyle(style, key, AttributeLevel.User_Mark, stateStyle);
} else this.setStyle(stateTemp, key, AttributeLevel.User_Mark, stateStyle);
}));
}
_computeGradientAttr(gradientStyle) {
var _a, _b;
const {gradient: gradient, scale: scale, field: field} = gradientStyle, rest = __rest(gradientStyle, [ "gradient", "scale", "field" ]);
let colorScale = scale, colorField = field;
if (!(scale && field || "series" !== this.model.modelType)) {
const {scale: globalColorScale, field: globalField} = this.model.getColorAttribute();
scale || (colorScale = globalColorScale), colorField || (colorField = globalField);
}
const themeColor = computeActualDataScheme(getDataScheme(this.model.getColorScheme(), "series" === this.model.modelType ? null === (_b = (_a = this.model).getSpec) || void 0 === _b ? void 0 : _b.call(_a) : void 0), this.model.getDefaultColorDomain()), mergedStyle = Object.assign(Object.assign({}, DEFAULT_GRADIENT_CONFIG[gradient]), rest);
return (data, opt) => {
const computeStyle = {}, markData = this.getDataView();
return Object.keys(mergedStyle).forEach((key => {
const value = mergedStyle[key];
"stops" === key ? computeStyle.stops = value.map((stop => {
const {opacity: opacity, color: color, offset: offset} = stop;
let computeColor = null != color ? color : null == colorScale ? void 0 : colorScale.scale(data[colorField]);
return isFunction(color) && (computeColor = color(data, this._attributeContext, opt, markData)),
isValid(opacity) && (computeColor = Color.SetOpacity(computeColor, opacity)), {
offset: isFunction(offset) ? offset(data, this._attributeContext, opt, markData) : offset,
color: computeColor || themeColor[0]
};
})) : isFunction(value) ? computeStyle[key] = value(data, this._attributeContext, opt, markData) : computeStyle[key] = value;
})), computeStyle.gradient = gradient, computeStyle;
};
}
_computeBorderAttr(borderStyle) {
const {scale: scale, field: field} = borderStyle, mergedStyle = __rest(borderStyle, [ "scale", "field" ]);
return (data, opt) => {
var _a, _b, _c;
const computeStyle = {};
if (Object.keys(mergedStyle).forEach((key => {
const value = mergedStyle[key];
isFunction(value) ? computeStyle[key] = value(data, this._attributeContext, opt, this.getDataView()) : computeStyle[key] = value;
})), "stroke" in computeStyle) GradientType.includes(null === (_c = mergedStyle.stroke) || void 0 === _c ? void 0 : _c.gradient) && (computeStyle.stroke = this._computeGradientAttr(mergedStyle.stroke)(data, opt)); else {
const themeColor = computeActualDataScheme(getDataScheme(this.model.getColorScheme(), "series" === this.model.modelType ? null === (_b = (_a = this.model).getSpec) || void 0 === _b ? void 0 : _b.call(_a) : void 0), this.model.getDefaultColorDomain());
let colorScale = scale, colorField = field;
if (!(scale && field || "series" !== this.model.modelType)) {
const {scale: globalColorScale, field: globalField} = this.model.getColorAttribute();
scale || (colorScale = globalColorScale), colorField || (colorField = globalField),
computeStyle.stroke = (null == colorScale ? void 0 : colorScale.scale(data[colorField])) || themeColor[0];
}
}
return computeStyle;
};
}
}
//# sourceMappingURL=base-mark.js.map