🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
:-: echarts组件添加--数形图 #### 一.添加echarts数图选择对象 ~~~ { // 新增树图 name: "", type: "treemap", coverImage: contextPath + "/images/componenttypes/" + locale + "/echarts/pie.png", coverImageWidth: a, tip: "树图" } ~~~ ps(type:"treemap" 重要--------) * * * * * 二.设置树图的初始数据 `var treemapdata=[{"value":17.6,"name":"保险"},{"value":16.5,"name":"知识产权"},{"value":16.5,"name":"出版"},{"value":15.5,"name":"轻工业"},{"value":14.8,"name":"金融"},{"value":13.7,"name":"化工"},{"value":13.6,"name":"科技"},{"value":13.4,"name":"教育"},{"value":13.1,"name":"对外经贸合作"},{"value":12.6,"name":"节能"},{"value":12.6,"name":"电力"},{"value":12.6,"name":"资源综合利用"},{"value":12.4,"name":"能源"},{"value":12.2,"name":"矿产"},{"value":12,"name":"信息产业"},{"value":12,"name":"基础设施"},{"value":11.7,"name":"物流"},{"value":11.6,"name":"环境保护"},{"value":11.6,"name":"国家安全"},{"value":11.6,"name":"水运"}]` ps(每一个代数据的图形都需要初始化数据) * * * * * 三.添加树图echarts组件基础对象 ~~~ // 树图对象 var treemapOptionTemplate = { // backgroundColor: "#000", // 标题 title: { show: false }, // 提示框 tooltip: { show: true, trigger: "item", // 提示框里的数据 formatter: "{a} <br/>{b} : {c}", axisPointer: { type: "line" }, position: function (p) { console.log([p[1], p[1]]) return [0, p[1]] } }, series: [{ name: vsLang.sample_growth_rate, type: 'treemap', visibleMin: 300, leafDepth: 2, roam: false, //是否开启拖拽漫游(移动和缩放) nodeClick: false, //点击节点后的行为,false无反应 breadcrumb: { show: false }, label: { //描述了每个矩形中,文本标签的样式。 normal: { show: true, textStyle: { color: '#fff', fontSize: 12, }, align: 'center', position: 'center' } }, itemStyle: { normal: { borderWidth: 1, gapWidth: 2, label: { show: true, distance: 0.5, position:"bottom", textStyle: { fontSize: 12 }, formatter: "{b}" }, labelLine: { show: true, length: 1 } }, emphasis: { label: { show: false, position: "center", textStyle: { fontSize: "30", fontWeight: "bold" } } } }, // 数据 data: treemapdata }] }; // end ~~~ 四.在factory大对象里面添加新组件的判断 ~~~ // 是否显示行为 isShowEventCategory: function (scope) { switch (scope.component.type) { case "column": case "mixed": case "pie": case "treemap": case "bar": case "line": return true } return false }, // 树图显示行为所以添加树图的属性 ~~~ * * * * * ~~~ // 联动里面的指标联动 supportReceiveMeasureLink: function (scope) { switch (scope.component.type) { case "column": case "pie": case "treemap": case "bar": case "line": case "chinaAreaMap": return true } return false }, // 树图需要联动所以添加树图的属性 ~~~ * * * * * internalInit在这个函数里添加判断--条件属性(type="treemap") ~~~ case "treemap": // 组件需要的数据 var serieData = option.series[0].data; 提示框的位置 option.tooltip.position = function (p) { return [0, p[1]] }; break; ~~~ [教程](https://www.cnblogs.com/cupsuccess/p/6483284.html) * * * * * 添加internalRefreshTreeMapModelData这个函数 重要 重要 重要。 ~~~ var internalRefreshTreeMapModelData = function () { // 综合数据 var option = component.config.chartConfig; // 维度 var dimensions = component.config.datasourceConfig.dimensions; // 度量 var measures = component.config.datasourceConfig.measures; console.log(measures) var data = component.context.data; // 判断data是不是null if (data == null) { return } // 判断度量选择了几个 if (measures.length>2) { alert('请选择一项指标') return } // 初始化度量索引为0 var measureIdx = 0; if (component.config.receiveMeasureLink != null && component.config.receiveMeasureLink === true) { var newMeasures = scope.getSelectedLinkMeasure(component, component.config.datasourceConfig.measures); for (var i = 0; i < measures.length; i++) { if (newMeasures[i] != null) { measureIdx = i; break } } } // 数据初始化为0 var serieData = []; for (var i = 0; i < data.length; i++) { var dimValue = data[i][dimensions[dimensions.length - 1].name]; // 函数在vs-utils.js if (VSUtils.isEmpty(dimValue)) { continue } // datapush进去每一个度量里的key 和 value serieData.push({ name: dimValue, value: data[i][measures[measureIdx].name] }); } console.log(serieData) // 判断如果数据没有那么就为空数组 if (serieData.length == 0) { serieData = [""]; } // 数据赋值给echarts对象里面的data option.series[0].data = serieData; option.series[0].name = measures[measureIdx].label; option.series[0].seriesIndex = measureIdx; if (component.config["measureAlias_" + measureIdx] != null && component.config["measureAlias_" + measureIdx].length > 0) { option.series[0].name = component.config["measureAlias_" + measureIdx] } // 处理提示框的数据 option.tooltip.formatter = function (p) { if (component.config.tooltipStatus != null && component.config.tooltipStatus === "hide") { return "" } var seriesIndex = option.series[0].seriesIndex; if (!VSUtils.isEmpty(component.config.tooltipValueScript)) { try { var f = eval("(function(name, params, VSUtils){ " + Base64.decode(component.config.tooltipValueScript) + "})"); return f.call(null, p[1], p, VSUtils) } catch (e) { console.log(e) } } console.log(component.config["unit_" + seriesIndex]) var unit = component.config["unit_" + seriesIndex]; if (unit == null) { unit = "" } var displayValue = $vsUtils.processValue(p[2], component.config["digit_" + seriesIndex]); console.log(displayValue) console.log(p[1] + "<br/>" + p[0] + ": " + $vsUtils.comdifyValue(displayValue) + "" + unit + "(" + p[3] + "%)") // 提示框里显示的每一个指标的数据 return p[1] + "<br/>" + p[0] + ": " + $vsUtils.comdifyValue(displayValue); }; rebuildPieChart(scope, element, option); if (component.config.hideOnFirstShow && !component.context.firstShowTooltip) { component.context.firstShowTooltip = true; return } }; ~~~ * * * * * 在所有组件data函数的下面加一个switch判断 ~~~ case "treemap": internalRefreshTreeMapModelData(); break; ~~~ * * * * * buildDataDescription在这个数据绑定函数里<br> ~~~ scope.$on(event_chartDimensionValueChange, function (s, event) { // 添加内容 switch (component.type) { case "treemap": // 判断提示框是显示 还是隐藏或者禁用 if (!component.config.chartConfig.tooltip.show) { component.context.chart.component.tooltip.hideTip(); return } var dataIndex = -1; for (var i = 0; i < component.config.chartConfig.series[0].data.length; i++) { if ("" + component.config.chartConfig.series[0].data[i].name === "" + event.source.value) { dataIndex = i; break } } if (dataIndex < 0) { component.context.chart.component.tooltip.hideTip(); return } if (dataIndex > -1) { component.context.chart.component.tooltip.showTip({ // name: event.source.value, // seriesIndex: 0 dataIndex: dataIndex, seriesIndex: 0 }) } break; } }) ~~~ ps(里面 已经有判断了 我们只需要添加单独的判断条件和逻辑代码即可) * * * * * refreshMeasureCategoryDescription在这个函数里添加 * * * * * ~~~ case "treemap": watchers.push(scope.$watch("component.config.measureAlias" + identifier, function (newValue) { if (newValue != null) { scope.$broadcast(event_refreshChartView, {}) } })); watchers.push(scope.$watch("component.config.unit" + identifier, function (newValue) { if (newValue != null) { scope.$broadcast(event_refreshChartView, {}) } })); break; ~~~ * * * * * 在已有的判断里添加树形图 这里是判断基本并监听基本属性改变值 * * * * * ~~~ switch (component.type) { case "bar": case "line": case "area": case "pie": case "treemap": case "mixed": case "column": scope.$watch("component.config.legendItemHeight", function (newValue, oldValue) { if (newValue != null && oldValue != null) { var option = component.config.chartConfig; option.legend.itemHeight = newValue; scope.component.context.chart.setOption(option, true) } }); scope.$watch("component.config.legendItemWidth", function (newValue, oldValue) { if (newValue != null && oldValue != null) { var option = component.config.chartConfig; option.legend.itemWidth = newValue; scope.component.context.chart.setOption(option, true) } }); scope.$watch("component.config.showLegend", function (newValue) { if (newValue != null) { var option = component.config.chartConfig; if (option.legend == null) { option.legend = { show: false, orient: "horizontal", x: "right", y: "top", data: [vsLang.sample_revenue], textStyle: { color: "#999", fontSize: 12 } }; option.legend.show = newValue === "show"; scope.$broadcast(event_refreshChartView, {}) } else { option.legend.show = newValue === "show"; scope.component.context.chart.setOption(option, true) } } }); scope.$watch("component.config.legendSelectedModeObj", function (newValue) { if (newValue != null) { component.config.legendSelectedMode = newValue.value; var option = component.config.chartConfig; option.legend.selectedMode = newValue.value; scope.component.context.chart.setOption(option, true) } }); scope.$watch("component.config.legendOrient", function (newValue) { if (newValue != null) { var option = component.config.chartConfig; option.legend.orient = newValue; scope.component.context.chart.setOption(option, true) } }); scope.$watch("component.config.legendPosY", function (newValue) { if (newValue != null) { var option = component.config.chartConfig; option.legend.y = newValue; scope.component.context.chart.setOption(option, true) } }); scope.$watch("component.config.legendOffsetY", function (newValue) { if (newValue != null) { var option = component.config.chartConfig; option.legend.y = newValue; scope.component.context.chart.setOption(option, true) } }); scope.$watch("component.config.legendPosX", function (newValue) { if (newValue != null) { var option = component.config.chartConfig; option.legend.x = newValue; scope.component.context.chart.setOption(option, true) } }); scope.$watch("component.config.legendFontColor", function (newValue) { if (isValidColorValue(newValue)) { var option = component.config.chartConfig; if (option.legend.textStyle == null) { option.legend.textStyle = {} } option.legend.textStyle.color = newValue; scope.component.context.chart.setOption(option, true) } }); scope.$watch("component.config.legendFontSize", function (newValue) { if (newValue != null) { var option = component.config.chartConfig; if (option.legend.textStyle == null) { option.legend.textStyle = {} } option.legend.textStyle.fontSize = newValue; scope.component.context.chart.setOption(option, true) } }); scope.$watch("component.config.legendItemGap", function (newValue) { var option = component.config.chartConfig; if (newValue != null) { option.legend.itemGap = parseInt(newValue) } else { if (option.legend != null) { delete option.legend.itemGap } } scope.component.context.chart.setOption(option, true) }); break } ~~~ * * * * * 在buildChartWatchers函数里添加 ~~~ case "treemap": scope.$watchCollection("component.config.colorSeries", function (newValue) { if (newValue != null) { var option = component.config.chartConfig; option.color = newValue; rebuildPieChart(scope, element, option) } }); scope.$watch("component.config.pieSize", function (newValue) { if (newValue != null) { var option = component.config.chartConfig; if (component.config.pieInnerSize == null) { component.config.pieInnerSize = 0 } option.series[0].radius = [component.config.pieInnerSize + "%", newValue + "%"]; scope.component.context.chart.setOption(option, true) } }); scope.$watch("component.config.pieInnerSize", function (newValue) { if (newValue != null) { var option = component.config.chartConfig; if (component.config.pieSize == null) { component.config.pieSize = parseInt(option.series[0].radius) } option.series[0].radius = [newValue + "%", component.config.pieSize + "%"]; scope.component.context.chart.setOption(option, true) } }); scope.$watch("component.config.showEmphasis", function (newValue) { if (newValue != null) { var option = component.config.chartConfig; if (option.series[0].itemStyle.emphasis == null) { option.series[0].itemStyle.emphasis = { label: { show: false, position: "center", textStyle: { fontSize: "30", fontWeight: "bold" } } } } option.series[0].itemStyle.emphasis.label.show = newValue === "show"; scope.component.context.chart.setOption(option, true) } }); scope.$watch("component.config.emphasisFontSize", function (newValue) { if (newValue != null) { var option = component.config.chartConfig; if (option.series[0].itemStyle.emphasis == null) { option.series[0].itemStyle.emphasis = { label: { show: false, position: "center", textStyle: { fontSize: "30", fontWeight: "bold" } } } } option.series[0].itemStyle.emphasis.label.textStyle.fontSize = newValue + ""; scope.component.context.chart.setOption(option, true) } }); scope.$watch("component.config.itemStyleType", function (newValue) { console.log(component.config) if (newValue != null) { var option = component.config.chartConfig; console.log() option.series[0].itemStyle.normal.show = newValue === "show"; option.series[0].itemStyle.normal.show = newValue === "show"; scope.component.context.chart.setOption(option, true) } }); scope.$watch("component.config.showLegend", function (newValue) { if (newValue != null) { var option = component.config.chartConfig; option.legend.show = newValue === "show"; scope.component.context.chart.setOption(option, true) } }); scope.$watch("component.config.legendOrient", function (newValue) { if (newValue != null) { var option = component.config.chartConfig; option.legend.orient = newValue; scope.component.context.chart.setOption(option, true) } }); scope.$watch("component.config.legendPosY", function (newValue) { if (newValue != null) { var option = component.config.chartConfig; option.legend.y = newValue; scope.component.context.chart.setOption(option, true) } }); scope.$watch("component.config.legendPosX", function (newValue) { if (newValue != null) { var option = component.config.chartConfig; option.legend.x = newValue; scope.component.context.chart.setOption(option, true) } }); scope.$watch("component.config.pieCenterY", function (newValue) { if (newValue != null) { var option = component.config.chartConfig; if (component.config.pieCenterX == null) { component.config.pieCenterX = parseInt(option.series[0].center[0]) } option.series[0].center = [component.config.pieCenterX + "%", newValue + "%"]; scope.component.context.chart.setOption(option, true) } }); scope.$watch("component.config.pieCenterX", function (newValue) { if (newValue != null) { var option = component.config.chartConfig; if (component.config.pieCenterY == null) { component.config.pieCenterY = parseInt(option.series[0].center[1]) } option.series[0].center = [newValue + "%", component.config.pieCenterY + "%"]; scope.component.context.chart.setOption(option, true) } }); scope.$watch("component.config.legendValueType", function (newValue) { if (newValue != null) { var option = component.config.chartConfig; scope.component.context.chart.setOption(option, true) } }); scope.$watch("component.config.legendSelectedModeObj", function (newValue) { if (newValue != null) { component.config.legendSelectedMode = newValue.value; var option = component.config.chartConfig; option.legend.selectedMode = newValue.value; scope.component.context.chart.setOption(option, true) } }); break; ~~~ * * * * * 在buildChartOption函数里的switch判断力添加 * * * * * ~~~ case "treemap": option = angular.copy(treemapOptionTemplate); break; ~~~ * * * * * #### 五.在design.js里添加新组件对应的判断和逻辑 在internalBuildEChartsComponent函数里添加 ~~~ case "treemap": var serieData = option.series[0].data; option.tooltip.position = function (p) { return [0, p[1]] }; break; ~~~ * * * * * 同样添加internalRefreshTreemapModelData函数 ~~~ var internalRefreshTreemapModelData = function () { var option = component.config.chartConfig; var dimensions = component.config.datasourceConfig.dimensions; var measures = component.config.datasourceConfig.measures; var data = component.context.data; var measureIdx = 0; if (component.config.receiveMeasureLink != null && component.config.receiveMeasureLink === true) { var newMeasures = scope.getSelectedLinkMeasure(component, component.config.datasourceConfig.measures); for (var i = 0; i < measures.length; i++) { if (newMeasures[i] != null) { measureIdx = i; break } } } var serieData = []; var legendData = []; for (var i = 0; i < data.length; i++) { var dimValue = data[i][dimensions[dimensions.length - 1].name]; if (VSUtils.isEmpty(dimValue)) { continue } serieData.push({ name: dimValue, value: data[i][measures[measureIdx].name] }); legendData.push(dimValue) } console.log(serieData) if (serieData.length == 0) { serieData = [""]; legendData = [""] } option.series[0].data = serieData; option.series[0].name = measures[measureIdx].label; option.series[0].seriesIndex = measureIdx; if (component.config["measureAlias_" + measureIdx] != null && component.config["measureAlias_" + measureIdx].length > 0) { option.series[0].name = component.config["measureAlias_" + measureIdx] } option.tooltip.formatter = function (p) { if (component.config.tooltipStatus != null && component.config.tooltipStatus === "hide") { return "" } var seriesIndex = option.series[0].seriesIndex; if (!VSUtils.isEmpty(component.config.tooltipValueScript)) { try { var f = eval("(function(name, params, VSUtils){ " + Base64.decode(component.config.tooltipValueScript) + "})"); return f.call(null, p[1], p, VSUtils) } catch (e) { console.log(e) } } var unit = component.config["unit_" + seriesIndex]; if (unit == null) { unit = "" } var displayValue = $vsUtils.processValue(p[2], component.config["digit_" + seriesIndex]); // console.log(p[1] + "<br/>" + p[0] + ": " + $vsUtils.comdifyValue(displayValue) + "" + unit + "(" + p[3] + "%)") return p[1] + "<br/>" + p[0] + ": " + $vsUtils.comdifyValue(displayValue); }; console.log(legendData) console.log(option) option.data = legendData; rebuildPieChart(scope, element, option); if (component.config.hideOnFirstShow && !component.context.firstShowTooltip) { component.context.firstShowTooltip = true; return } if (component.config.chartConfig.tooltip.show) { $timeout(function () { var cachedSelectedValue = scope.getCachedDimensionValue(dimensions[dimensions.length - 1].name); if (cachedSelectedValue != null) { component.context.chart.component.tooltip.showTip({ name: cachedSelectedValue, seriesIndex: 0 }) } }, 800) } }; ~~~ * * * * * ps:和设置页的data函数一样 * * * * * 在refreshChartView函数里添加 ~~~ case "treemap": internalRefreshTreemapModelData(); break; ~~~ * * * * * 在已有的switch里添加一个判断 (这里是判断提示框的显示隐藏禁用) ~~~ scope.$on(event_chartDimensionValueChange, function (s, event) { switch (component.type) { case "treemap": if (!component.config.chartConfig.tooltip.show) { return } var dataIndex = -1; for (var i = 0; i < component.config.chartConfig.series[0].data.length; i++) { if ("" + component.config.chartConfig.series[0].data[i].name === "" + event.source.value) { dataIndex = i; break } } if (dataIndex < 0) { component.context.chart.component.tooltip.hideTip(); return } if (dataIndex > -1) { component.context.chart.component.tooltip.showTip({ name: event.source.value, seriesIndex: 0 }) } break; } }) ~~~ 因为树图折现图和饼图基础部分一样 在已有的判断力加上treemap属性 ~~~ switch (scope.component.type) { case "mixed": case "bar": case "line": case "treemap": case "line": case "column": component.context.chart.on(echarts.config.EVENT.CLICK, function (param) { var paramName = param.name; if (component.context.originalYAxisLabels != null && component.context.originalYAxisLabels.length > param.dataIndex) { paramName = component.context.originalYAxisLabels[param.dataIndex] } if (component.context.originalXAxisLabels != null && component.context.originalXAxisLabels.length > param.dataIndex) { paramName = component.context.originalXAxisLabels[param.dataIndex] } if (!VSUtils.isEmpty(component.context.tooltipDataValue) && "" + component.context.tooltipDataValue === "" + paramName) { scope.onComponentClickEvent(component, true) } }); break } ~~~