🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
### # 设计页 html 路径D:\ireport365\ireport365.war\WEB-INF\pages\enduser\designer\index.jsp 添加两个js 百度的 key值上线的时候申请成自己的 `<script src="http://api.map.baidu.com/api?v=2.0&ak=XlQ9m3CqMs1UKUbuPIN15LsDp7VC6hoM"></script> ` 添加bmap.js `_scripts.push({url: "https://cdn.bootcss.com/echarts/4.0.3/extension/bmap.min.js?v="+updateVersion});` ### js 路径D:\ireport365\ireport365.war\js\enduser\designer\vs-component-echarts.js 一 添加线图 ~~~ { name: "", type: "echartsMap", coverImage: contextPath + "/images/componenttypes/" + locale + "/widget/zh_baiduMap.png?v=3", coverImageWidth: "50%", tip: "echarts线路-轨迹-支持省市县" } ~~~ 二 初始化组件大小 ~~~ if (b.type === "echartsMap") { b.sizeX = 4; b.sizeY = 18 } ~~~ 三 添加模板 ~~~ // echarts轨迹图模板start var trajectoryColor = ['#a6c84c', '#ffa022', '#46bee9']; // 初始化坐标 var addr = [ [{ name: '琴台大剧院' }, { jd:114.2592716217 , wd: 30.5616327403 }], [{ name: '钟家村' }, { jd:114.26728 , wd: 30.549565 }], [{ name: '汉阳区江堤街江堤社区北方向' }, { jd:114.2530059814 , wd: 30.5378686275 }], [{ name: '汉阳大道钟家村公交站' }, { jd:114.254722 , wd: 30.550605 }] ]; // 地图自定义样式 var bmap = { center: [addr[i][1].jd,addr[i][1].wd], zoom: 15, roam: true, mapStyle: { styleJson: [{ 'featureType': 'land', //调整土地颜色 'elementType': 'geometry', 'stylers': { 'color': '#081734' }}, { 'featureType': 'building', //调整建筑物颜色 'elementType': 'geometry', 'stylers': { 'color': '#04406F' }}, { 'featureType': 'building', //调整建筑物标签是否可视 'elementType': 'labels', 'stylers': { 'visibility': 'off' }}, { 'featureType': 'highway', //调整高速道路颜色 'elementType': 'geometry', 'stylers': { 'color': '#015B99' }}, { 'featureType': 'highway', //调整高速名字是否可视 'elementType': 'labels', 'stylers': { 'visibility': 'off' }}, { 'featureType': 'arterial', //调整一些干道颜色 'elementType': 'geometry', 'stylers': { 'color':'#003051' }}, { 'featureType': 'arterial', 'elementType': 'labels', 'stylers': { 'visibility': 'off' }}, { 'featureType': 'green', 'elementType': 'geometry', 'stylers': { 'visibility': 'off' }}, { 'featureType': 'water', //调整水的颜色 'elementType': 'geometry', 'stylers': { 'color': '#044161' }}, { 'featureType': 'subway', //调整地铁颜色 'elementType': 'geometry.stroke', 'stylers': { 'color': '#003051' }}, { 'featureType': 'subway', //地铁名字是否可视 'elementType': 'labels', 'stylers': { 'visibility': 'off' }}, { 'featureType': 'railway', //铁路名字是否可视 'elementType': 'geometry', 'stylers': { 'visibility': 'off' }}, { 'featureType': 'railway', 'elementType': 'labels', 'stylers': { 'visibility': 'off' }}, { 'featureType': 'all', //调整所有的标签的边缘颜色 'elementType': 'labels.text.stroke', 'stylers': { 'color': '#313131' }}, { 'featureType': 'all', //调整所有标签的填充颜色 'elementType': 'labels.text.fill', 'stylers': { 'color': '#FFFFFF' }}, { 'featureType': 'manmade', 'elementType': 'geometry', 'stylers': { 'visibility': 'off' }}, { 'featureType': 'manmade', 'elementType': 'labels', 'stylers': { 'visibility': 'off' }}, { 'featureType': 'local', 'elementType': 'geometry', 'stylers': { 'visibility': 'off' }}, { 'featureType': 'local', 'elementType': 'labels', 'stylers': { 'visibility': 'off' }}, { 'featureType': 'subway', 'elementType': 'geometry', 'stylers': { 'lightness': -65 }}, { 'featureType': 'railway', 'elementType': 'all', 'stylers': { 'lightness': -40 }}, { 'featureType': 'boundary', 'elementType': 'geometry', 'stylers': { 'color': '#8b8787', 'weight': '1', 'lightness': -29 }}] } } // 数据空数组 var trajectorySeries2 = []; addr.forEach(function(item, i) { trajectorySeries2.push({ name: addr[i][0].name , type: 'effectScatter', // 坐标点数据 coordinateSystem: 'bmap', zlevel: 2, rippleEffect: { brushType: 'stroke' }, label: { normal: { show: false, position: 'right', formatter: '{b}' } }, symbolSize: 20, showEffectOn: 'render', itemStyle: { normal: { color: 'red' } }, data: [{ name: addr[i][0].name, value: [addr[i][1].jd, addr[i][1].wd] }] } ); }); addr.forEach(function(item, i) { if(i<addr.length-1){ var endNum=i+1; trajectorySeries2.push({ type: 'lines', coordinateSystem: 'bmap', // 线连接, 只需要坐标,为 起点和终点 zlevel: 2, effect: { show: true, period: 6, trailLength: 0, symbol:'circle', symbolSize: 10 }, lineStyle: { normal: { color: 'yellow', width: 1, opacity: 0.4, curveness: 0 } }, data: [{ coords: [[addr[i][1].jd,addr[i][1].wd],[addr[endNum][1].jd,addr[endNum][1].wd]]}] }); } }); addr.forEach(function(item, i) { if(i<addr.length-1){ var endNum=i+1; //点移动的拖尾特效 trajectorySeries2.push({ type: 'lines', coordinateSystem: 'bmap', zlevel: 1, effect: { show: true, period: 6, trailLength: 0.7, color: '#ff8800', symbolSize: 3 }, lineStyle: { normal: { color: trajectoryColor[i], width: 0, curveness: 0.0 } }, data: [{ coords: [ [addr[i][1].jd,addr[i][1].wd],[addr[endNum][1].jd,addr[endNum][1].wd]]}] }); } }); // console.log(trajectorySeries2) var trajectoryOptionTemplate = { bmap: bmap, zoom: 13, color: ['gold', 'aqua', 'lime'], title: { show: false }, lineColor:'yellow', borderC:'red', borderWeiColor:'#ff8800', activeColor:'#ff8800', tooltip: { trigger: 'item', transitionDuration: 0, }, legend: { //工具栏,可以进行 类型数据显示的选择 show: false, orient: 'vertical', top: 'top', left: 'right', textStyle: { color: '#ff8800' }, selectedMode: 'single' }, series: trajectorySeries2 }; // 结束 end ~~~ 四 在buildChartOption函数里添加 ~~~ case "echartsMap": option = angular.copy(trajectoryOptionTemplate); break; ~~~ 五 添加判断处理数据函数方法 ~~~ case "echartsMap": internalRefreshEchartsMapModelData(); break; ~~~ 六 组件的数据处理函数 ~~~ //echartsMap 处理数据函数 var internalRefreshEchartsMapModelData = function(){ var option = component.config.chartConfig; var dimensions = component.config.datasourceConfig.dimensions; var measures = component.config.datasourceConfig.measures; var data = component.context.data; console.log(data) var dd = option.series[0] if (data == null || data.length < 1 || measures.length < 1) { return } 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 } } } // console.log(dimensions[dimensions.length-1].name) var addr = []; // console.log(option) // console.log(data) for (var i = 0; i < data.length; i++) { // console.log(data[i]) addr.push([{ name:data[i][dimensions[measureIdx].name] },{ jd:data[i].lat, wd:data[i].lng }]) } // console.log(addr) // 数据空数组 var trajectorySeries2 = []; addr.forEach(function(item, i) { trajectorySeries2.push({ name: addr[i][0].name , type: 'effectScatter', // 坐标点数据 coordinateSystem: 'bmap', zlevel: 2, rippleEffect: { brushType: 'stroke' }, label: { normal: { show: false, position: 'right', formatter: '{b}' } }, symbolSize: 20, showEffectOn: 'render', itemStyle: { normal: { color: option.borderC } }, data: [{ name: addr[i][0].name, value: [addr[i][1].jd, addr[i][1].wd] }] } ); }); addr.forEach(function(item, i) { if(i<addr.length-1){ var endNum=i+1; trajectorySeries2.push({ type: 'lines', coordinateSystem: 'bmap', // 线连接, 只需要坐标,为 起点和终点 zlevel: 2, effect: { show: true, period: 6, trailLength: 0, symbol:'circle', symbolSize: 10 }, lineStyle: { normal: { color: option.lineColor, width: 1, opacity: 0.4, curveness: 0 } }, data: [{ coords: [[addr[i][1].jd,addr[i][1].wd],[addr[endNum][1].jd,addr[endNum][1].wd]]}] }); } }); addr.forEach(function(item, i) { if(i<addr.length-1){ var endNum=i+1; //点移动的拖尾特效 trajectorySeries2.push({ type: 'lines', coordinateSystem: 'bmap', zlevel: 1, effect: { show: true, period: 6, trailLength: 0.7, color: option.borderWeiColor, symbolSize: 3 }, lineStyle: { normal: { color: trajectoryColor[i], width: 0, curveness: 0.0 } }, data: [{ coords: [ [addr[i][1].jd,addr[i][1].wd],[addr[endNum][1].jd,addr[endNum][1].wd]]}] }); } }); // console.log(option) // option = trajectoryOptionTemplate; option.series = trajectorySeries2 option.bmap.center = [addr[0][1].jd,addr[0][1].wd]; // option.bmap.zoom = 7; component.context.chart.setOption(option, true) // console.log(option) } ~~~ 七 接收联动指令 ~~~ case "echartsMap": // console.log(component) var option = component.config.chartConfig; var dataIndex = -1; for(var i = 0; i<component.context.data.length;i++){ // 每次全部恢复颜色 // option.series[i].itemStyle.normal.color = option.borderColor; option.series[i].itemStyle.normal.color = option.borderColor; option.series[i].label.normal.show = false; } for(var i = 0; i<component.context.data.length;i++){ // 每次全部恢复颜色 // option.series[i].itemStyle.normal.color = option.borderColor; if ("" + option.series[i].name === "" + event.source.value) { dataIndex = i; break } } // 这个指标联动变颜色 option.series[dataIndex].itemStyle.normal.color = option.activeColor; // 显示该指标弹框 option.series[dataIndex].label.normal.show = true; // option.bmap.zoom = 7; component.context.chart.setOption(option, true) break; ~~~ 八 推送联动指令 ~~~ case "echartsMap": component.context.chart.on("click", function (param) { // console.log(param) if (component.config.datasourceConfig.measures == null || component.config.datasourceConfig.dimensions == null) { return } var data = component.context.data; var dataIndex = param.dataIndex; // console.log(data) // console.log(dataIndex) // console.log(param.data.name) var to = param.data.name; // if (to != null && component.context.tooltipName != null && "" + component.context.tooltipName === "" + to) { // return // } if (to == null || param.value == null || param.value === "-") { return } // console.log(component.context.tooltipName) component.context.tooltipName = to; scope.notifyDimensionValueChange(null, scope.getLastDimension(), to) }); break; ~~~ 九 在internalBuildChartDescription函数里添加 配置设置 这个函数最前面是 ~~~ var measureCategory = { name: "measureConfig", title: vsLang.measures, groups: [] }; component.description.categories.push(measureCategory); ~~~ 修改成以下 线图不需要度量 ~~~ // 如果是echarts轨迹图或者3d地图就不加度量 if (component.type !== "echartsMap") { var measureCategory = { name: "measureConfig", title: vsLang.measures, groups: [] }; component.description.categories.push(measureCategory); } ~~~ 十 在和气泡图一起的switch (component.type) {}判断里加以下代码 ~~~ case "echartsMap": // chartCategory.groups.push({ // title: { // text: "工具箱配置" // }, // elements: [{ // title: "工具箱", // type: "radio", // bind: "showDataLabel", // items: [{ // name: vsLang.on, // value: true // }, { // name: vsLang.off, // value: false // }] // }, { // title: "上下位置", // type: "select-s", // bind: "dataLabelPositionObjTop", // items: [{ // name: vsLang.position_top, // value: "top" // }, { // name: vsLang.position_bottom, // value: "bottom" // }] // }, { // title: "左右位置", // type: "select-s", // bind: "dataLabelPositionObjLeft", // items: [{ // name: vsLang.position_left, // value: "left" // }, { // name: vsLang.position_right, // value: "right" // }] // }, { // title: "工具箱颜色", // type: "colorpicker", // bind: "gjColor" // }] // }) chartCategory.groups.push({ title: { text: "图形配置" }, elements: [{ title: "线条颜色", type: "colorpicker", bind: "linkColor" },{ title: "点颜色", type: "colorpicker", bind: "borderColor" },{ title: "尾灯颜色", type: "colorpicker", bind: "borderWeiColor" },{ title: "激活点颜色", type: "colorpicker", bind: "activeColor" },{ title: "视图大小", type: "configSlide", bind: "viewZoom", config: { slideEnd: 100 } }] }) break; ~~~ ![](https://box.kancloud.cn/29295a9ed8c513c54c06539a7c86dc39_585x243.png) 十一 在监听配置面板监听函数里 添加监听方法 和气泡地图一起 ~~~ case "echartsMap": // 监听工具箱开关 scope.$watch("component.config.showDataLabel", function (newValue) { console.log(newValue) if (newValue != null) { var option = component.config.chartConfig; option.legend.show = newValue; scope.component.context.chart.setOption(option, true); } }); // 监听工具箱上下位置 scope.$watch("component.config.dataLabelPositionObjTop", function (newValue) { if (newValue != null) { // console.log(newValue.value) var option = component.config.chartConfig; option.legend.top = newValue.value; scope.component.context.chart.setOption(option, true) } }); // 监听工具箱左右位置 scope.$watch("component.config.dataLabelPositionObjLeft", function (newValue) { if (newValue != null) { var option = component.config.chartConfig; // console.log(option) // console.log(newValue.value) option.legend.left = newValue.value; scope.component.context.chart.setOption(option, true) } }); // 监听工具箱颜色 scope.$watch("component.config.gjColor", function (newValue) { if (newValue != null) { var option = component.config.chartConfig; option.legend.textStyle.color = newValue; scope.component.context.chart.setOption(option, true) } }); // 监听线条颜色 scope.$watch("component.config.linkColor", function (newValue) { if (newValue != null) { var option = component.config.chartConfig; console.log(option) option.lineColor = newValue; scope.component.context.chart.setOption(option, true) } }); // 监听点颜色 scope.$watch("component.config.borderColor", function (newValue) { if (newValue != null) { var option = component.config.chartConfig; option.borderColor = newValue; scope.component.context.chart.setOption(option, true) } }); // 监听尾灯颜色 scope.$watch("component.config.borderWeiColor", function (newValue) { if (newValue != null) { var option = component.config.chartConfig; option.borderWeiColor = newValue; scope.component.context.chart.setOption(option, true) } }); // 监听激活点颜色 scope.$watch("component.config.activeColor", function (newValue) { if (newValue != null) { var option = component.config.chartConfig; option.activeColor = newValue; scope.component.context.chart.setOption(option, true) } }); // 监听视图大小 scope.$watch("component.config.viewZoom", function (newValue) { if (newValue != null) { var option = component.config.chartConfig; option.bmap.zoom = newValue; scope.component.context.chart.setOption(option, true) } }); break; ~~~ ![](https://box.kancloud.cn/a6ef4d05d86ca929518bb306cadf63a3_500x193.png) # 分享页 ### html 路径 D:\ireport365\ireport365.war\WEB-INF\classes\system-resource\report-template.html `<script src="http://api.map.baidu.com/api?v=2.0&ak=XlQ9m3CqMs1UKUbuPIN15LsDp7VC6hoM"></script>` `_scripts.push({url: "https://cdn.bootcss.com/echarts/4.0.3/extension/bmap.min.js"});` ### js 路径 D:\ireport365\ireport365.war\WEB-INF\classes\report-resource\design.js 一 判断数据处理函数 ~~~ case "echartsMap": internalRefreshEchartsMapModelData(); break; ~~~ 二 数据处理函数 ~~~ // echarts地图-轨迹数据处理函数 var internalRefreshEchartsMapModelData = function(){ var option = component.config.chartConfig; var dimensions = component.config.datasourceConfig.dimensions; var measures = component.config.datasourceConfig.measures; var data = component.context.data; var trajectoryColor = ['#a6c84c', '#ffa022', '#46bee9']; console.log(option.borderColor) if (data == null || data.length < 1 || measures.length < 1) { return } // console.log(dimensions[dimensions.length-1].name) var addr = []; // console.log(option) // console.log(data) for (var i = 0; i < data.length; i++) { // console.log(data[i]) addr.push([{ name:data[i][dimensions[dimensions.length-1].name] },{ jd:data[i].lat, wd:data[i].lng }]) } // // 初始化坐标 // var addr1 = [ // [{ name: '琴台大剧院' }, { jd:119.2592716217 , wd: 30.5616327403 }], // [{ name: '钟家村' }, { jd:118.26728 , wd: 30.549565 }], // [{ name: '汉阳区江堤街江堤社区北方向' }, { jd:119.2530059814 , wd: 30.5378686275 }], // [{ name: '汉阳大道钟家村公交站' }, { jd:114.254722 , wd: 30.550605 }] // ]; // console.log(addr) // console.log(addr1) // 数据空数组 var trajectorySeries2 = []; addr.forEach(function(item, i) { trajectorySeries2.push({ name: addr[i][0].name , type: 'effectScatter', // 坐标点数据 coordinateSystem: 'bmap', zlevel: 2, rippleEffect: { brushType: 'stroke' }, label: { normal: { show: false, position: 'right', formatter: '{b}' } }, symbolSize: 20, showEffectOn: 'render', itemStyle: { normal: { color: option.borderC } }, data: [{ name: addr[i][0].name, value: [addr[i][1].jd, addr[i][1].wd] }] } ); }); addr.forEach(function(item, i) { if(i<addr.length-1){ var endNum=i+1; trajectorySeries2.push({ type: 'lines', coordinateSystem: 'bmap', // 线连接, 只需要坐标,为 起点和终点 zlevel: 2, effect: { show: true, period: 6, trailLength: 0, symbol:'circle', symbolSize: 10 }, lineStyle: { normal: { color: option.lineColor, width: 1, opacity: 0.4, curveness: 0 } }, data: [{ coords: [[addr[i][1].jd,addr[i][1].wd],[addr[endNum][1].jd,addr[endNum][1].wd]]}] }); } }); addr.forEach(function(item, i) { if(i<addr.length-1){ var endNum=i+1; //点移动的拖尾特效 trajectorySeries2.push({ type: 'lines', coordinateSystem: 'bmap', zlevel: 1, effect: { show: true, period: 6, trailLength: 0.7, color: option.borderWeiColor, symbolSize: 3 }, lineStyle: { normal: { color: trajectoryColor[i], width: 0, curveness: 0.0 } }, data: [{ coords: [ [addr[i][1].jd,addr[i][1].wd],[addr[endNum][1].jd,addr[endNum][1].wd]]}] }); } }); // console.log(option) // option = trajectoryOptionTemplate; option.series = trajectorySeries2 option.bmap.center = [addr[0][1].jd,addr[0][1].wd]; component.context.chart.setOption(option, true) // console.log(option) } ~~~ 三 接收联动指标 ~~~ case "echartsMap": var option = component.config.chartConfig; var dataIndex = -1; for(var i = 0; i<component.context.data.length;i++){ // 每次全部恢复颜色 // option.series[i].itemStyle.normal.color = option.borderColor; option.series[i].itemStyle.normal.color = option.borderColor; option.series[i].label.normal.show = false; } for(var i = 0; i<component.context.data.length;i++){ // 每次全部恢复颜色 // option.series[i].itemStyle.normal.color = option.borderColor; if ("" + option.series[i].name === "" + event.source.value) { dataIndex = i; break } } // 这个指标联动变颜色 option.series[dataIndex].itemStyle.normal.color = option.activeColor; // 显示该指标弹框 option.series[dataIndex].label.normal.show = true; // option.bmap.zoom = 7; component.context.chart.setOption(option, true) break ~~~ 四 推送联动 ~~~ case "echartsMap": var option = component.config.chartConfig; var dataIndex = -1; for(var i = 0; i<component.context.data.length;i++){ // 每次全部恢复颜色 // option.series[i].itemStyle.normal.color = option.borderColor; option.series[i].itemStyle.normal.color = option.borderColor; option.series[i].label.normal.show = false; } for(var i = 0; i<component.context.data.length;i++){ // 每次全部恢复颜色 // option.series[i].itemStyle.normal.color = option.borderColor; if ("" + option.series[i].name === "" + event.source.value) { dataIndex = i; break } } // 这个指标联动变颜色 option.series[dataIndex].itemStyle.normal.color = option.activeColor; // 显示该指标弹框 option.series[dataIndex].label.normal.show = true; // option.bmap.zoom = 7; component.context.chart.setOption(option, true) break ~~~