import { getColorValue } from './chart'; import { isTypeof, objectMerge } from '@/components/thrid/em-element-ui/src/tools/utils'; export function formatLegendData(params) { let result = '', number = 4, name = params.name.toString(), str = name.replace(/^\s+|\s+$/g, ''), len = str.length; number = len > number ? Math.ceil(len / 2) : number; for (let i = 0; i < len; i++) { if (i > 0 && i < len && (i % number) == 0) { result += '\n'; } result += str.charAt(i); } //str.replace(/(?=(?:.{4})+$)/g, '\n'); return result; } export function debounce(func, wait, immediate) { let timeout, args, context, timestamp, result const later = function () { // 据上一次触发时间间隔 const last = +new Date() - timestamp // 上次被包装函数被调用时间间隔last小于设定时间间隔wait if (last < wait && last > 0) { timeout = setTimeout(later, wait - last) } else { timeout = null // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用 if (!immediate) { result = func.apply(context, args) if (!timeout) context = args = null } } } return function (...args) { context = this timestamp = +new Date() const callNow = immediate && !timeout // 如果延时不存在,重新设定延时 if (!timeout) timeout = setTimeout(later, wait) if (callNow) { result = func.apply(context, args) context = args = null } return result } } //页面data初始化 export function chartsInitData(cls) { let options = {}, option = { elChart: null, //chart对象 chartOptions: { //画图使用的默认值 options: { type: 'line', //chart类型,默认为line x: 'name', y: 'value', tickCount: 5, scrollNum: 6, ScrollColor: 'F1F2F6', tooltip: { showCrosshairs: true }, size: 2, adjust: '', shape: '' } }, color: getColorValue(1), //chart颜色值 }; Object.assign(options, option); if (arguments.length > 1) { options = objectMerge(options, arguments[1]()); } return options; } function isChartScrollBar(_this, chart) { let option = chart.options; if (!option.scroll) return false; if (option.type == 'pie' || (!option.type && option.axis === false)) return false; //是否显示scrollBar let names = [], xname = option.x, series = chart.data.series, scrollMax = option.scroll && option.scroll['number'] ? option.scroll['number'] : option.scrollNum, scrollColor = option.scroll && option.scroll['color'] ? option.scroll['color'] : option.scrollColor; //option.adjust = '';//滚动不支持adjust //name重新组合,并去重 series.forEach(item => { names.push(item[xname]); }); names = names.filter((item, index) => names.indexOf(item) === index); if (names.length > scrollMax) { names = names.filter((item, index) => index < scrollMax); option.scrollBar = { mode: 'x', xStyle: { backgroundColor: scrollColor, fillerColor: scrollColor, offsetY: -5 } }; let valueArea = { values: names }; sourceDefs(option, xname, valueArea); /*{ min: 0, max: scrollMax };type:line*/ } } function sourceDefs(option, key, value) { if(option.defs){ option.defs = option.defs.filter(item => item.key!==key); }else{ option.defs = []; } option.defs.push({ key: key, value: value }); } //init merge data function getObjectValue(currObj, paramObj) { let result = Object.create(currObj ? currObj : null); if (currObj) { result = objectMerge(result, paramObj); return result; } else { return paramObj; } } function initDefSource(_this, chart) { let flagX = false, data = chart.downList ? chart.downList : chart.data.series, defs = chart.options.defs || [], currDef = {}; if (Array.isArray(defs)) { defs.forEach(item => { if (chart.options.x == item.key) { flagX = true; } currDef[item.key] = item.value; }); } //如果没有y轴校验,增加默认 if (!currDef[chart.options.y]){ currDef[chart.options.y] = { tickCount: 5 } } _this.elChart.source(data, currDef); } function initDefScale(_this, chart) { let scale = chart.options.scale; if (Array.isArray(scale)) { scale.forEach(item => { _this.elChart.scale(item.key, item.value); }); } } function initPieLabel(_this, chart) { let pieLabel = chart.options.pieLabel; if (pieLabel) { _this.elChart.pieLabel(pieLabel) } } function initReloadShape(_this, chart){ let draw = chart.options.draw; // 绘制内阴影 if(draw && draw.iShadow){ const frontPlot = _this.elChart.get('frontPlot'); const coord = _this.elChart.get('coord'); // 获取坐标系对象 frontPlot.addShape('sector', { attrs: { x: coord.center.x, y: coord.center.y, r: coord.circleRadius * coord.innerRadius * 1.2, // 全半径 r0: coord.circleRadius * coord.innerRadius, fill: '#000', opacity: 0.15 } }); _this.elChart.get('canvas').draw(); } } function initDefCoord(_this, chart) { let coord = chart.options.coord; if (Array.isArray(coord)) { coord.forEach(item => { if (item.value) { _this.elChart.coord(item.key, item.value); } else { _this.elChart.coord(item.key); } }); } } function axisTextLabels(text, index, total){ const textCfg = {}; /*if (index === 0) { textCfg.textAlign = 'start'; } else if (index === total - 1) { textCfg.textAlign = 'right'; }*/ return textCfg; } function initDefAxis(_this, chart) { let axis = chart.options.axis; if (isTypeof(axis) === 'array') { axis.forEach(item => { _this.elChart.axis(item.key, item.value ? item.value : { label(text, index, total){ return chart.options.scroll ? {} : axisTextLabels(text, index, total); } }); }); } else if (isTypeof(axis) === 'object'){ _this.elChart.axis(axis.key, { label: function(text, index, total){ let number = axis.number ? axis.number : 1, textCfg = chart.options.scroll ? {} : axisTextLabels(text, index, total); if(text < chart.data.series.length) { if(axis.mapping) textCfg.text = chart.data.series[parseInt(text)][axis.mapping]; return textCfg; } } }); } else if (isTypeof(axis) === 'string'){ _this.elChart.axis(axis, { label: function(text, index, total){ return chart.options.scroll ? {} : axisTextLabels(text, index, total); } }); } else if (axis === false) { _this.elChart.axis(axis); } } function initDefLegend(_this, chart) { let legend = chart.options.legend; if (Array.isArray(legend)) { legend.forEach(item => { if(item.key){ _this.elChart.legend(item.key, item.value); }else{ _this.elChart.legend(item); } }); } else { _this.elChart.legend(legend); } } function initDefTooltip(_this, chart, option) { let tooltip = chart.options.tooltip; if (tooltip) { tooltip = getObjectValue(option.tooltip, tooltip); } _this.elChart.tooltip(tooltip); } function initDefScrollBar(_this, chart, option) { let scrollBar = chart.options.scrollBar; if (scrollBar) { scrollBar = getObjectValue(option.scrollBar, scrollBar); } _this.elChart.scrollBar(scrollBar); } function initDefGuide(_this, chart) { let guide = chart.options.guide; if (Array.isArray(guide)) { guide.forEach(item => { _this.elChart.guide().text(item); }); } } function initMarkTag(_this, chart) { let mark = chart.options.mark; if (mark && mark.isTrue) { let number = mark.number, name = mark.name; // 绘制辅助线 _this.elChart.guide().line({ start: function start(xScale, yScales) { let price = yScales[0].max * number / yScales[1].max; return ['min', price]; }, end: function end(xScale, yScales) { let price = yScales[0].max * number / yScales[1].max; return ['max', price]; }, style: { stroke: 'red', // 线的颜色 lineDash: [0, 2, 2], // 虚线的设置 lineWidth: 1 // 线的宽度 // 图形样式配置 } }); _this.elChart.guide().text({ position: function position(xScale, yScales) { let price = yScales[0].max * number / yScales[1].max; return ['max', price]; }, content: name + ':' + number, style: { textAlign: 'end', textBaseline: 'bottom', fill: 'red' }, offsetY: -5 }); } } function panEventProcessReload(_this, chart) { let yValues = [], option = chart.options, xScale = _this.elChart.getXScale(), source = _this.elChart.get('data'); source.map(obj => { if (xScale.translate(obj.year) >= 0) { yValues.push(obj.sales); } }); sourceDefs(option, option.x, {values: xScale.values});//x轴 sourceDefs(option, option.y, { min: 0, tickCount: 5, max: Math.max.apply(null, yValues) });//y轴 initDefSource(_this, chart); _this.elChart.changeData(source); } function panEventEndReload(_this, chart) { _this.elChart.repaint(); } function initDefRender(_this, chart) { let axis = chart.options.axis; if (isTypeof(axis) === 'array') { axis.forEach(item => { if (item.position) { drawChartType(_this, chart, item); } }); } else { drawChartType(_this, chart); } if(chart.options.scroll){ _this.elChart.interaction('pan', { mode: 'x', onProcess: () => { panEventProcessReload(_this, chart); }, onEnd: () => { panEventEndReload(_this, chart); } }); } _this.elChart.render(); } function drawChartTypeMap(type){ let map = { path: '.path()', point: '.point()', line: '.line()', area: '.area()', interval: '.interval()', polygon: '.polygon()', schema: '.schema()' }; return map[type] || false; } function chartColorValue(options){ if(options.mode && options.mode == 'more'){ return '.color(name, color)'; }else{ return '.color(color)'; } } function chartAdjustValue(options){ if (options.adjust) { if(isTypeof(options.adjust) === 'object') return '.adjust(' + JSON.stringify(options.adjust) + ')'; else if(isTypeof(options.adjust) === 'string') return '.adjust("' + options.adjust + '")'; } return ''; } function chartSizeValue(options){ if(options.size) return '.size("' + options.size + '")'; return ''; } function chartShapeValue(options){ if(options.shape) return '.shape("' + options.shape + '")'; return ''; } function chartStyleValue(type, options){ if(options.style){ if(isTypeof(options.style) == 'string'){ return '.style("' + options.style + '")'; }else if(isTypeof(options.style) == 'object'){ if(options.style.type == type){ return '.style(' + JSON.stringify(options.style) + ')'; } }else if(isTypeof(options.style) == 'array'){ options.style.forEach(item => { if(item.type == type){ return '.style(' + JSON.stringify(item) + ')'; } }); } } return ''; } function execDrawRender(type, options){ let execDrawChart = '_this.elChart', execPostions = '.position(position)',//坐标 execType = drawChartTypeMap(type),//根据类型执行对应的函数 execColor = chartColorValue(options), execAdjust = chartAdjustValue(options), execSize = type === 'line' ? '' : chartSizeValue(options), execStyle = chartStyleValue(type, options), execShape = chartShapeValue(options), animate = '.animate({update: {duration: 1000}})'; return execDrawChart + execType + execPostions + execColor + execAdjust + execShape + execSize + execStyle + animate; } function drawChartType(_this, chart, item) { let options = chart.options, color = options.color ? options.color : _this.color, size = options.size ? options.size : '', adjust = options.adjust ? options.adjust : '', shape = options.shape ? options.shape : '', name = options.name ? options.name : '', key = options.x ? options.x : '', value = options.y ? options.y : '', position = key + '*' + value, type = options.type ? options.type : ''; if (typeof (item) == 'object') { type = item.type ? item.type : type; value = item.position ? item.position : value; position = key + '*' + value; } if(isTypeof(type) === 'string'){ eval('(' + execDrawRender(type, options) + ')'); }else if(isTypeof(type) === 'object'){ for(let [k, v] of Object.entries(type)){ if(v && drawChartTypeMap(k)) eval('(' + execDrawRender(k, options) + ')'); } } } export function mergeChartsOptions(_this) { let option = {}, chartOptions = objectMerge(_this.chartOptions, _this.chart.chartOptions); isChartScrollBar(_this, chartOptions); //判断是否显示滚动条 initDefSource(_this, chartOptions); initDefScale(_this, chartOptions); initDefCoord(_this, chartOptions); initDefAxis(_this, chartOptions); initDefLegend(_this, chartOptions); initDefTooltip(_this, chartOptions, option); initDefScrollBar(_this, chartOptions, option); initPieLabel(_this, chartOptions); initDefGuide(_this, chartOptions); initMarkTag(_this, chartOptions); initDefRender(_this, chartOptions); initReloadShape(_this, chartOptions); } export function legendSelecthanged(_this, option) { if (!option.legendData) return; _this.elChart.on('legendselectchanged', function (params) { let num = 0, name = params.name; option.series[num].data.forEach((item, index) => { let value = 0; option.legendData[index].forEach(legend => { if (name == legend.subjectName) { value = Number(legend.fee); } }); if (params.selected[name]) { option.series[num].data[index] = item + value; } else { option.series[num].data[index] = item - value; } }); _this.elChart.setOption(option); }); } export function drawCharts(_this) { mergeChartsOptions(_this); }