@opentiny/vue-renderless
Version:
An enterprise-class UI component library, support both Vue.js 2 and Vue.js 3, as well as PC and mobile.
474 lines (473 loc) • 14.5 kB
JavaScript
import {
__spreadValues
} from "../chunk-G2ADBYYC.js";
import { on, off } from "@opentiny/utils";
import {
DEFAULT_COLORS,
DEFAULT_THEME,
STATIC_PROPS,
ECHARTS_SETTINGS,
SAAS_DEFAULT_COLORS,
SAAS_DEFAULT_SAME_COLORS,
DEFAULT_CONFIG
} from "./deps/constants";
import { getType, debounce, isObject, cloneDeep, isEqual, htmlHandler, get } from "./deps/utils";
import { xss } from "@opentiny/utils";
import setAnimation from "./modules/animation";
import setExtend from "./modules/extend";
import setMark from "./modules/mark";
const computedCanvasStyle = (props) => () => ({
width: props.width,
height: props.height,
position: "relative"
});
const isStack = ({ props }) => {
let {
settings: { stack },
data: { columns }
} = props;
let flag = false;
if (typeof stack !== "object" || !Array.isArray(columns))
return flag;
Object.keys(stack).forEach((key) => {
stack[key].forEach((stackItem) => {
const isExist = columns.includes(stackItem);
if (isExist) {
flag = true;
}
});
});
return flag;
};
const calcColors = ({ len, type, isStack: isStack2 }) => {
let SAAS_COLOR = SAAS_DEFAULT_COLORS;
let lastColor = "#1B3F86";
if (isStack2 && type === "") {
return len && len > 6 ? [lastColor].concat(SAAS_COLOR.slice(0, len - 1)) : SAAS_COLOR.slice(0, [len || 8]);
}
if (!isStack2 && type === "") {
type = "default";
}
if (type === "blue" || type === "green") {
SAAS_COLOR = SAAS_DEFAULT_SAME_COLORS[type].slice(0, len).sort((a, b) => a.idx - b.idx).map((item) => item.color);
}
return len && len > 6 ? SAAS_COLOR.slice(0, len - 1).concat([lastColor]) : SAAS_COLOR.slice(0, [len || 8]);
};
const computedInitColor = (props) => () => {
let defaultColors = DEFAULT_COLORS;
let { data, colorMode, extend } = props;
let flag = isStack({ props });
if (data && (Array.isArray(data.rows) || Array.isArray(data.columns))) {
const { columns, rows } = data;
const len = Math.max(columns ? columns.length : 0, rows ? rows.length : 0);
defaultColors = calcColors({ len, type: colorMode, isStack: flag });
} else if (Array.isArray(data)) {
defaultColors = calcColors({ len: data.length, type: colorMode, isStack: flag });
} else if (extend && extend.series && Array.isArray(extend.series.data)) {
defaultColors = calcColors({ len: extend.series.data.length, type: colorMode, isStack: flag });
} else if (extend && Array.isArray(extend.series)) {
defaultColors = calcColors({ len: extend.series.length, type: colorMode, isStack: flag });
}
return props.colors || props.theme && props.theme.color || defaultColors;
};
const computedChartColor = (props) => ({ series }) => {
let defaultColors = DEFAULT_COLORS;
let { colorMode } = props;
let flag = isStack({ props });
if (series && Array.isArray(series)) {
const validateList = ["pie", "radar", "sankey", "heatmap", "wordCloud"];
let len = 0;
if (series.some((item) => validateList.includes(item.type))) {
series.forEach((item) => len += item.data && item.data.length);
} else {
len = series.length;
}
defaultColors = calcColors({ len, type: colorMode, isStack: flag });
} else if (series && typeof series === "object") {
defaultColors = calcColors({ len: series.data.length, type: colorMode, isStack: flag });
}
return props.colors || props.theme && props.theme.color || defaultColors;
};
const getDefaultThemeColors = () => () => {
const { blue, green } = SAAS_DEFAULT_SAME_COLORS;
return { default: SAAS_DEFAULT_COLORS, blue, green };
};
const dataHandler = ({ api, props, state, echartsLib, t, vm }) => () => {
if (!api.chartHandler) {
return;
}
let data = props.data;
let isBoxplot = false;
if (vm.prepareBoxplotData && Array.isArray(data)) {
isBoxplot = true;
const obj = vm.prepareBoxplotData(data);
data = {
columns: obj.axisData,
rows: obj.boxData,
outliers: obj.outliers
};
}
let { columns = [], rows = [] } = data;
const extra = {
tooltipVisible: props.tooltipVisible,
legendVisible: props.legendVisible,
echarts: state.echarts,
color: state.chartColor,
tooltipFormatter: props.tooltipFormatter,
_once: state.once,
echartsLib,
t,
vm
};
columns = htmlHandler(columns);
rows = htmlHandler(rows);
if (isBoxplot) {
extra.outliers = data.outliers;
}
if (props.beforeConfig) {
data = props.beforeConfig(data);
}
let options = api.chartHandler(columns, rows, props.settings, extra, props.extend);
if (options) {
if (typeof options.then === "function") {
options.then(api.optionsHandler);
} else {
api.optionsHandler(options);
}
}
};
const nextTickResize = ({ api, nextTick }) => () => nextTick(api.resize);
const resize = ({ props, vm, api }) => () => {
if (!props.cancelResizeCheck) {
if (vm.$el && vm.$el.clientWidth && vm.$el.clientHeight) {
api.echartsResize();
}
} else {
api.echartsResize();
}
};
const echartsResize = (state) => () => state.echarts && state.echarts.resize();
const setOptionsLegend = ({ props, options }) => {
if (props.legendPosition && options.legend) {
options.legend[props.legendPosition] = 10;
if (["left", "right"].includes(props.legendPosition)) {
options.legend.top = "middle";
options.legend.orient = "vertical";
}
}
};
const selfSetting = ({ props, options }) => {
ECHARTS_SETTINGS.forEach((setting) => {
if (props[setting]) {
options[setting] = props[setting];
}
});
};
const applyMarks = ({ props, options }) => {
if (props.markArea || props.markLine || props.markPoint) {
const marks = {
markArea: props.markArea,
markLine: props.markLine,
markPoint: props.markPoint
};
const series = options.series;
if (Array.isArray(series)) {
series.forEach((item) => {
setMark(item, marks);
});
} else if (isObject(series)) {
setMark(series, marks);
}
}
};
const afterConfig = ({ props, options }) => {
if (props.afterConfig) {
options = props.afterConfig(options);
}
return options;
};
const mapChartNotMerge = (props) => {
let setOptionOpts = props.setOptionOpts;
if ((props.settings.bmap || props.settings.amap) && !isObject(setOptionOpts)) {
setOptionOpts = false;
}
return setOptionOpts;
};
const afterSetOption = ({ props, state, options, echartsLib }) => {
if (props.afterSetOption) {
props.afterSetOption(state.echarts, options, echartsLib);
}
};
const afterSetOptionOnce = ({ props, state, options, echartsLib }) => {
if (props.afterSetOptionOnce && !state.once.afterSetOptionOnce) {
state.once.afterSetOptionOnce = true;
props.afterSetOptionOnce(state.echarts, options, echartsLib);
}
};
const judgeWidthHandler = ({ props, api, vm, nextTick }) => () => {
if (!props.judgeWidth) {
return;
}
if (vm.$el.clientWidth || vm.$el.clientHeight) {
api.resize();
} else {
nextTick(() => {
if (vm.$el.clientWidth || vm.$el.clientHeight) {
api.resize();
} else {
setTimeout(() => {
api.resize();
}, props.widthChangeDelay);
}
});
}
};
const optionsHandler = ({ props, state, emit, echartsLib, api, vm }) => (options) => {
if (options.tooltip) {
if (typeof options.tooltip.formatter === "function") {
const formatter = options.tooltip.formatter;
const customFormatter = (...args) => {
const rerutnValue = formatter(...args);
return xss.filterHtml(rerutnValue);
};
options.tooltip.formatter = customFormatter;
} else {
let xssHtml = xss.filterHtml(options.tooltip.formatter);
options.tooltip.formatter = xssHtml;
}
const defaultTooltip = DEFAULT_CONFIG.tooltip || {};
options.tooltip = __spreadValues(__spreadValues({}, defaultTooltip), options.tooltip);
}
if (options.legend) {
const defaultLegend = DEFAULT_CONFIG.legend || {};
options.legend = __spreadValues(__spreadValues({}, defaultLegend), options.legend);
}
setOptionsLegend({ props, options });
selfSetting({ props, options });
setAnimation({ options, animation: props.animation });
applyMarks({ props, options });
if (props.extend) {
setExtend({ options, extend: props.extend });
options.series.label = __spreadValues({ show: false }, options.series.label);
options.series.radius = ["25%", "100%"];
const series = options.series;
if (Array.isArray(series)) {
options.series = series.map((item) => {
if (get(item, "type") === "line" && get(item, "label.show")) {
item.showSymbol = true;
}
return item;
});
}
}
options.color = api.computedChartColor({ series: options.series });
emit("handle-color", options.color, api.getDefaultThemeColors());
options = afterConfig({ props, options });
let setOptionOpts = mapChartNotMerge(props);
if (props.notSetUnchange && props.notSetUnchange.length) {
props.notSetUnchange.forEach((item) => {
const value = options[item];
if (value) {
if (isEqual(value, state.store[item])) {
options[item] = void 0;
} else {
state.store[item] = cloneDeep(value);
}
}
});
if (isObject(setOptionOpts)) {
setOptionOpts.notMerge = false;
} else {
setOptionOpts = false;
}
}
if (vm._isDestroyed) {
return;
}
state.echarts.setOption(options, setOptionOpts);
emit("ready", state.echarts, options, echartsLib);
if (!state.once["ready-once"]) {
state.once["ready-once"] = true;
emit("ready-once", state.echarts, options, echartsLib);
}
api.judgeWidthHandler(options);
afterSetOption({ props, state, options, echartsLib });
afterSetOptionOnce({ props, state, options, echartsLib });
};
const resizeableHandler = ({ api, state }) => (resizeable) => {
if (resizeable && !state.once.onresize) {
api.addResizeListener();
}
if (!resizeable && state.once.onresize) {
api.removeResizeListener();
}
};
const init = ({ state, props, api, vm, echartsLib, markRaw }) => () => {
if (state.echarts) {
return;
}
const ictThemeName = {};
const { settings } = props;
if (settings.line) {
ictThemeName.line = settings.line;
}
const themeName = props.themeName || props.theme || DEFAULT_THEME;
state.echarts = markRaw(
echartsLib.init(vm.$refs.canvas, themeName, __spreadValues(__spreadValues({}, themeName), ictThemeName), props.initOptions)
);
if (props.data) {
api.changeHandler();
}
api.createEventProxy();
if (props.resizeable) {
api.addResizeListener();
}
};
const addResizeListener = ({ state, api }) => () => {
on(window, "resize", api.resizeHandler);
state.once.onresize = true;
};
const removeResizeListener = ({ state, api }) => () => {
off(window, "resize", api.resizeHandler);
state.once.onresize = false;
};
const addWatchToProps = ({ props, watch, api }) => () => {
Object.keys(props).forEach((prop) => {
if (!STATIC_PROPS.includes(prop)) {
const opts = {};
if (["[object Object]", "[object Array]"].includes(getType(props[prop]))) {
opts.deep = true;
} else {
opts.immediate = true;
}
watch(
() => prop,
() => {
api.changeHandler();
},
opts
);
}
});
};
const createEventProxy = ({ props, state }) => () => {
const keys = Object.keys(props.events || {});
keys.length && keys.forEach((event) => {
if (!state.registeredEvents.includes(event)) {
state.registeredEvents.push(event);
state.echarts.on(
event,
((event2) => (...args) => {
if (event2 in props.events) {
props.events[event2].apply(null, args);
}
})(event)
);
}
});
};
const themeChange = ({ api, state }) => () => {
api.clean();
state.echarts = null;
api.init();
};
const clean = ({ props, state, api }) => () => {
if (props.resizeable) {
api.removeResizeListener();
}
state.echarts.dispose();
};
const watchOnMounted = ({ api, vm, watch, props, t }) => {
watch(
() => props.data,
(value) => value && api.changeHandler(),
{ deep: true }
);
watch(
() => props.settings,
(value) => {
if (value.type && vm.chartLib) {
api.chartHandler = vm.chartLib[value.type];
}
api.changeHandler();
},
{ deep: true }
);
watch(
() => [props.width, props.height],
() => api.nextTickResize()
);
watch(
() => props.events,
() => api.createEventProxy(),
{ deep: true }
);
watch(
() => [props.theme, props.themeName],
() => api.themeChange()
);
watch(
() => props.resizeable,
() => api.resizeableHandler()
);
watch(
() => t("ui.chart.emptyText"),
() => api.changeHandler()
);
watch(
() => props.extend,
() => api.changeHandler(),
{ deep: true }
);
};
const mounted = ({ state, api, vm, props, watch, t }) => () => {
state.echarts = null;
state.registeredEvents = [];
state.once = {};
state.store = {};
if (props.extend && props.extend.tooltip) {
if (typeof props.extend.tooltip.formatter === "function") {
const formatter = props.extend.tooltip.formatter;
const customFormatter = (...args) => {
const rerutnValue = formatter(...args);
return xss.filterHtml(rerutnValue);
};
props.extend.tooltip.formatter = customFormatter;
} else {
let xssHtml = xss.filterHtml(props.extend.tooltip.formatter);
props.extend.tooltip.formatter = xssHtml;
}
}
api.chartHandler = vm.chartHandler;
api.resizeHandler = debounce(api.resize, props.resizeDelay);
api.changeHandler = debounce(api.dataHandler, props.changeDelay);
api.addWatchToProps();
api.init();
watchOnMounted({ watch, props, api, vm, t });
};
const changeHandler = ({ api, props }) => () => debounce(api.dataHandler, props.changeDelay);
const resizeHandler = ({ api, props }) => () => debounce(api.resize, props.resizeDelay);
export {
addResizeListener,
addWatchToProps,
changeHandler,
clean,
computedCanvasStyle,
computedChartColor,
computedInitColor,
createEventProxy,
dataHandler,
echartsResize,
getDefaultThemeColors,
init,
judgeWidthHandler,
mounted,
nextTickResize,
optionsHandler,
removeResizeListener,
resize,
resizeHandler,
resizeableHandler,
themeChange,
watchOnMounted
};