vuecharts3
Version:
the vue toolkit based on echarts
178 lines (177 loc) • 7.76 kB
JavaScript
import { defineComponent, ref, markRaw, shallowReactive, watch, provide, onMounted, onUnmounted, } from 'vue';
import { throttle } from "echarts/core";
import { contextSymbol, useChartContext } from './Chart';
export const series = [
'Line', 'Bar', 'Pie', 'Scatter', 'EffectScatter', 'Radar', 'Tree', 'Treemap',
'Sunburst', 'Boxplot', 'Candlestick', 'Heatmap', 'Map', 'Parallel', 'Lines',
'Graph', 'Sankey', 'Funnel', 'Gauge', 'PictorialBar', 'ThemeRiver', 'Custom',
];
export const visualMap = ['VisualMap', 'Continuous', 'Piecewise'];
export const dataZoom = ['DataZoom', 'Inside', 'Slider'];
const defaultTypeMap = {
Legend: "plain",
XAxis: "category",
YAxis: "value",
RadiusAxis: "value",
AngleAxis: "category",
DataZoom: "inside",
VisualMap: "continuous",
AxisPointer: "line",
ParallelAxis: "value",
SingleAxis: "value",
Timeline: "slider",
};
// export const uniqueId = () => Date.now().toString(36) + Math.random().toString(36).substring(2);
function uniqueId() {
return Date.now().toString(36) + Math.random().toString(36).substring(2);
}
const lower = (name) => name.charAt(0).toLowerCase() + name.slice(1);
function defaultType(name) {
// @ts-ignore
return defaultTypeMap[name] || lower(name);
}
function getKeyByName(name) {
return series.indexOf(name) > -1
? "series"
: visualMap.indexOf(name) > -1
? "visualMap"
: dataZoom.indexOf(name) > -1
? "dataZoom"
: lower(name);
}
// https://github.com/vuejs/vue/blob/main/types/v3-define-component.d.ts#L71
// ComponentOptionsWithoutProps
// 使用attrs替代props(可以不用再依赖ts-transformer-keys转换配置项key列表)
export function Components(name, type = '', key = '') {
type = type || defaultType(name);
key = key || getKeyByName(name);
return defineComponent({
name,
// 移除:使用ts-transformer-keys自动生成字段
// props: props as any,
inject: [contextSymbol],
// @ts-ignore
setup(props, { slots, attrs }) {
// @ts-ignore
const { id: pid, type: ptype, action, ...other } = attrs;
// @ts-ignore
const { removeOption, setOption } = useChartContext();
// 这里使用一个初始化的id
const id = ref((pid || uniqueId()));
// Graphic
const state = shallowReactive({
options: markRaw([]),
// eslint-disable-next-line @typescript-eslint/no-explicit-any
setOption: (key, option) => {
state.removeOption(key, option.id);
// @ts-ignore
state.options.push({ ...option, z: option.z || other.z });
},
removeOption: (key, id) => {
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-explicit-any
state.options = state.options.filter((i) => i.id !== id.value);
}
});
provide(contextSymbol, state);
// 如果id有变化的时候,先移除旧的,再生成新的
watch(() => attrs.id, (newId) => {
removeOption(key, id);
id.value = newId;
update();
});
const update = throttle(() => {
const options = markRaw({
...other,
type: ptype || type || undefined,
id: id.value,
});
if (key === "graphic") {
if (type == "group") {
// @ts-ignore
options["children"] = state.options;
}
// @ts-ignore
options["@action"] = action || "merge";
}
setOption(key, options);
}, 40, true);
// 监听attrs变化,更新配置信息
watch(() => attrs, update, { deep: true });
// 挂载组件的时候,初始化配置信息
onMounted(update);
onUnmounted(() => removeOption(key, id));
return () => key === "graphic" && type === "group" ? slots.default && slots.default() : null;
}
});
}
export const Title = Components("Title");
export const Legend = Components("Legend");
export const Grid = Components("Grid");
export const XAxis = Components("XAxis");
export const YAxis = Components("YAxis");
export const Polar = Components("Polar");
export const RadiusAxis = Components("RadiusAxis");
export const AngleAxis = Components("AngleAxis");
// Radar和series.radar重合
export const RadarAxis = Components("RadarAxis");
// // DataZoom
export const DataZoom = Components("DataZoom");
export const Inside = Components("Inside");
export const Slider = Components("Slider");
// visualMap
export const VisualMap = Components("VisualMap");
export const Continuous = Components("Continuous");
export const Piecewise = Components("Piecewise");
export const Tooltip = Components("Tooltip");
export const AxisPointer = Components("AxisPointer");
export const Toolbox = Components("Toolbox");
export const Brush = Components("Brush");
export const Geo = Components("Geo");
// Parallel: [], // 这个和series.parallel重合了 ParallelCoordinates
export const ParallelCoordinates = Components("ParallelCoordinates");
export const ParallelAxis = Components("ParallelAxis");
export const SingleAxis = Components("SingleAxis");
export const Timeline = Components("Timeline");
// TODO Graphic: 这里可以尝试把Graphic里面的暴露出来
export const Graphic = Components("Graphic", "graphic", "graphic");
export const Group = Components("Group", "group", "graphic");
export const Image = Components("Image", "image", "graphic");
export const Text = Components("Text", "text", "graphic");
export const Rect = Components("Rect", "rect", "graphic");
export const Circle = Components("Circle", "circle", "graphic");
export const Ring = Components("Ring", "ring", "graphic");
export const Sector = Components("Sector", "sector", "graphic");
export const Arc = Components("Arc", "arc", "graphic");
export const Polygon = Components("Polygon", "polygon", "graphic");
export const Polyline = Components("Polyline", "polyline", "graphic");
// graphic.elements-line 不能和series.line重名
export const GraphicLine = Components("GraphicLine", "line", "graphic");
export const BezierCurve = Components("BezierCurve", "bezierCurve", "graphic");
export const Calendar = Components("Calendar");
export const Dataset = Components("Dataset");
export const Aria = Components("Aria");
// series
export const Line = Components("Line");
export const Bar = Components("Bar");
export const Pie = Components("Pie");
export const Scatter = Components("Scatter");
export const EffectScatter = Components("EffectScatter");
export const Radar = Components("Radar");
export const Tree = Components("Tree");
export const Treemap = Components("Treemap");
export const Sunburst = Components("Sunburst");
export const Boxplot = Components("Boxplot");
export const Candlestick = Components("Candlestick");
export const Heatmap = Components("Heatmap");
export const Map = Components("Map");
export const Parallel = Components("Partial");
export const Lines = Components("Lines");
export const Graph = Components("Graph");
export const Sankey = Components("Sankey");
export const Funnel = Components("Funnel");
export const Gauge = Components("Gauge");
export const PictorialBar = Components("PictorialBar");
export const ThemeRiver = Components("ThemeRiver");
export const Custom = Components("Custom");
export * from './Chart';