he wei
2025-05-08 84ff051d5c6bbf10e71f6f8d1d57740c26619d9e
src/components/myCharts/MapChart.vue
@@ -1,244 +1,444 @@
<script>
import echarts from "echarts";
import BaseChart from "./BaseChart";
import common from "@/components/diagram/js/common";
import { getAllMapOutlineAction } from "@/views/home/js/api";
const { throttle } = common;
import HomeNormal from "@/assets/images/home.png";
// let mapHomeImage = new Image();
// mapHomeImage.src = HomeNormal;
// 正常的图标
import HomeNormalImage from "@/assets/images/home-normal.png";
// let homeNormalImage = new Image();
// homeNormalImage.src = HomeNormalImage;
// 充电的图标
import HomeChargeImage from "@/assets/images/home-charge.png";
// let homeChargeImage = new Image();
// homeChargeImage.src = HomeChargeImage;
// 告警图标
import HomeWarnImage from "@/assets/images/home-warn.png";
// let homeWarnImage = new Image();
// homeWarnImage.src = HomeWarnImage;
// 放电图标
import HomeDischargeImage from "@/assets/images/home-discharge.png";
// let homeDischargeImage = new Image();
// homeDischargeImage.src = HomeDischargeImage;
// 停电放电图标
import HomeTingDianImage from "@/assets/images/home-tingdian.png";
// let homeTingDianImage = new Image();
// homeTingDianImage.src = HomeTingDianImage;
// 透明背景图标
import HomeTransImage from "@/assets/images/home-trans.png";
// let homeTransImage = new Image();
// homeTransImage.src = HomeTransImage;
const subwayLines = [
    {
        name: '地铁 1 号线',
        coords: [
            [114.287177, 30.598208],
            [114.293133, 30.594368],
            // 更多站点经纬度...
        ]
    },
];
const colorList = ['#f00', '#00ff6c', '#ff00f0', '#f5f500', '#f1bb4c', '#ff5a06', '#9b00ff', '#00faaf', '#e5741c'];
// 生成随机颜色的函数
function getRandomColor() {
  const letters = '0123456789ABCDEF';
  let color = '#';
  for (let i = 0; i < 6; i++) {
      color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
}
// [1,2,3,4] => [1,2] [2,3], [3,4]
function transformArray(arr, label) {
    const result = [];
    for (let i = 0, j = arr.length -1; i < j; i++) {
        result.push({coords: [arr[i], arr[i + 1]], label});
    }
    return result;
}
export default {
  name: "MapChart",
  extends: BaseChart,
  props: {
    roam: {
      type: [String, Boolean],
      validator: (v) => [true, false, "scale", "move"].includes(v),
      default: true,
    },
    subway: {
      type: String,
      default: ''
    }
  },
  data() {
    return {}
    return {
      name: "zhongguo",
      subWaySeries: [],
    };
  },
  methods: {
    setData() {
      let option = this.getOption();
      this.setOption(option);
    async getSubWayData() {
      let subwayData = await require(`../../../public/mapJson/subway/${this.subway}.json`);
      // console.log('sub', subwayData, '=============');
      // format 数据
      try {
        this.subWaySeries = subwayData.l.map((item, index) => {
          let points = item.st.map(v => v.sl.split(',').map(vv => vv*1));
          return {
            type: 'lines',
            coordinateSystem: 'geo',
            name: item.ln,
            data: transformArray(points, item.ln),
            lineStyle: {
              color: colorList[index % colorList.length],
              width: 2
            },
            z: 3
          }
        })
      } catch (error) {
        this.subWaySeries = [];
        console.log('error', error, '=============');
      }
      // console.log('subwayseries', JSON.stringify(this.subWaySeries), '=============');
    },
    getOption() {
      let myChart = this.$options.chart;
      let mapName = 'zhongguo';
      let data = [
        {name:"北京市",value:199},
        {name:"天津市",value:42},
        {name:"河北省",value:102},
        {name:"山西省",value:81},
        {name:"内蒙古自治区",value:47},
        {name:"辽宁",value:67},
        {name:"吉林",value:82},
        {name:"黑龙江",value:123},
        {name:"上海",value:24},
        {name:"江苏",value:92},
        {name:"浙江",value:114},
        {name:"安徽",value:109},
        {name:"福建",value:116},
        {name:"江西",value:91},
        {name:"山东",value:119},
        {name:"河南",value:137},
        {name:"湖北",value:116},
        {name:"湖南",value:114},
        {name:"重庆",value:91},
        {name:"四川",value:125},
        {name:"贵州",value:62},
        {name:"云南",value:83},
        {name:"西藏",value:9},
        {name:"陕西",value:80},
        {name:"甘肃",value:56},
        {name:"青海",value:10},
        {name:"宁夏",value:18},
        {name:"新疆",value:180},
        {name:"广东",value:123},
        {name:"广西",value:59},
        {name:"海南",value:14},
      ];
      let geoCoordMap = {};
      let toolTipData = [
        {name:"北京",value:[{name:"科技人才总数",value:95},{name:"理科",value:82}]},
        {name:"天津",value:[{name:"文科",value:22},{name:"理科",value:20}]},
        {name:"河北",value:[{name:"文科",value:60},{name:"理科",value:42}]},
        {name:"山西",value:[{name:"文科",value:40},{name:"理科",value:41}]},
        {name:"内蒙古",value:[{name:"文科",value:23},{name:"理科",value:24}]},
        {name:"辽宁",value:[{name:"文科",value:39},{name:"理科",value:28}]},
        {name:"吉林",value:[{name:"文科",value:41},{name:"理科",value:41}]},
        {name:"黑龙江",value:[{name:"文科",value:35},{name:"理科",value:31}]},
        {name:"上海",value:[{name:"文科",value:12},{name:"理科",value:12}]},
        {name:"江苏",value:[{name:"文科",value:47},{name:"理科",value:45}]},
        {name:"浙江",value:[{name:"文科",value:57},{name:"理科",value:57}]},
        {name:"安徽",value:[{name:"文科",value:57},{name:"理科",value:52}]},
        {name:"福建",value:[{name:"文科",value:59},{name:"理科",value:57}]},
        {name:"江西",value:[{name:"文科",value:49},{name:"理科",value:42}]},
        {name:"山东",value:[{name:"文科",value:67},{name:"理科",value:52}]},
        {name:"河南",value:[{name:"文科",value:69},{name:"理科",value:68}]},
        {name:"湖北",value:[{name:"文科",value:60},{name:"理科",value:56}]},
        {name:"湖南",value:[{name:"文科",value:62},{name:"理科",value:52}]},
        {name:"重庆",value:[{name:"文科",value:47},{name:"理科",value:44}]},
        {name:"四川",value:[{name:"文科",value:65},{name:"理科",value:60}]},
        {name:"贵州",value:[{name:"文科",value:32},{name:"理科",value:30}]},
        {name:"云南",value:[{name:"文科",value:42},{name:"理科",value:41}]},
        {name:"西藏",value:[{name:"文科",value:5},{name:"理科",value:4}]},
        {name:"陕西",value:[{name:"文科",value:38},{name:"理科",value:42}]},
        {name:"甘肃",value:[{name:"文科",value:28},{name:"理科",value:28}]},
        {name:"青海",value:[{name:"文科",value:5},{name:"理科",value:5}]},
        {name:"宁夏",value:[{name:"文科",value:10},{name:"理科",value:8}]},
        {name:"新疆",value:[{name:"文科",value:36},{name:"理科",value:31}]},
        {name:"广东",value:[{name:"文科",value:63},{name:"理科",value:60}]},
        {name:"广西",value:[{name:"文科",value:29},{name:"理科",value:30}]},
        {name:"海南",value:[{name:"文科",value:8},{name:"理科",value:6}]},
      ];
      myChart.showLoading();
      let geoJson = require(`../../../public/mapJson/zhongguo.json`);
      echarts.registerMap("map", geoJson);
      let mapFeatures = geoJson.features;
      myChart.hideLoading();
      console.log(mapFeatures);
      mapFeatures.forEach(function(v) {
        // 地区名称
        let name = v.properties.name;
        // 地区经纬度
        geoCoordMap[name] = v.properties.center;
      });
      let max = 480,
        min = 9; // todo
      let maxSize4Pin = 100,
        minSize4Pin = 20;
      let convertData = function(data) {
        let res = [];
        for (let i = 0; i < data.length; i++) {
          let geoCoord = geoCoordMap[data[i].name];
          console.log(data[i].name);
          if (geoCoord) {
            res.push({
              name: data[i].name,
              value: geoCoord.concat(data[i].value),
    setMapName() {
      //查询激活轮廓图
      getAllMapOutlineAction()
        .then((res) => {
          let rs = res.data;
          if (rs.code == 1) {
            let data = rs.data;
            data.map((item, index) => {
              if (item.status == 1) {
                this.name = item.name;
              }
            });
          }
          this.setData([]);
        })
        .catch((err) => {
          this.setData([]);
          console.log(err);
        });
    },
    setData(data) {
      let option = this.getOption(data);
      this.setOption(option);
    },
    getOption(list) {
      let mapName = this.name;
      let data = [
        {
          name: "节",
          label: "测试机房1",
          value: 8,
          color: "#7668F9",
          points: [120.548762, 31.293819],
        },
        {
          name: "",
          label: "测试机房2",
          value: 100,
          color: "#0081FF",
          points: [120.614052, 31.30514],
        },
        // {
        //   name: "",
        //   label: "测试机房3",
        //   value: 100,
        //   color: "#0081FF",
        //   points: [110.3467, 41.4899],
        // },
        // {
        //   name: "节",
        //   label: "测试机房4",
        //   value: 50,
        //   color: "#FF6B6C",
        //   points: [125.8154, 44.2584],
        // },
        // {
        //   name: "",
        //   value: 8,
        //   label: "测试机房6",
        //   color: "#7668F9",
        //   points: [116.4551, 40.2539],
        // },
        // {
        //   name: "节",
        //   label: "测试机房7",
        //   value: 8,
        //   color: "#66F842",
        //   points: [123.1238, 42.1216],
        // },
        // {
        //   name: "节",
        //   label: "测试机房8",
        //   value: 100,
        //   color: "#0081FF",
        //   points: [114.4995, 38.1006],
        // },
      ];
      data = list;
      let geoJson = require(`../../../public/mapJson/${mapName}.json`);
      echarts.registerMap(mapName, geoJson);
      let areaList = geoJson.features || [];
      let data0 = [];
      areaList.forEach((v) => {
        data0.push({
          name: v.properties.name,
          value: Math.floor(Math.random() * 2) * 100,
        });
      });
      let convertData = function (data) {
        let res = [];
        for (let i = 0; i < data.length; i++) {
          let item = data[i];
          res.push({
            name: item.name,
            color: item.color,
            fontColor: item.fontColor,
            value: item.points.concat(data[i].value),
            label: item.label ? item.label : "",
            data: item,
          });
        }
        return res;
      };
      return {
        tooltip: {
          show: true,
          formatter(params) {
            // console.log(params);
            return params.data.label;
          },
        },
        visualMap:
        {
          show: false,
          type: "continuous",
          text: ["", ""],
          showLabel: true,
          left: "50",
          min: 0,
          max: 100,
          inRange: {
            color: ["#025483", "#116493"],
          },
          // seriesIndex: [1],
          seriesIndex: 1,
        },
        geo: {
          show: true,
          map: "map",
          map: mapName,
          label: {
            normal: {
              show: false
              show: false,
            },
            emphasis: {
              show: false,
            }
            },
          },
          roam: true,
          roam: this.roam,
          itemStyle: {
            normal: {
              areaColor: '#023677',
              borderColor: '#1180c7',
              borderColor: "rgba(147, 235, 248, 1)",
              borderWidth: 1,
              areaColor: {
                type: "radial",
                x: 0.5,
                y: 0.5,
                r: 0.8,
                colorStops: [
                  {
                    offset: 0,
                    color: "rgba(147, 235, 248, 0)", // 0% 处的颜色
                  },
                  {
                    offset: 1,
                    color: "rgba(147, 235, 248, .2)", // 100% 处的颜色
                  },
                ],
                globalCoord: false, // 缺省为 false
              },
              shadowColor: "rgba(128, 217, 248, 1)",
              shadowOffsetX: -2,
              shadowOffsetY: 2,
              shadowBlur: 10,
            },
            emphasis: {
              areaColor: '#4499d0',
            }
          }
        },
        series: [{
          name: '散点',
          type: 'scatter',
          coordinateSystem: 'geo',
          data: convertData(data),
          symbolSize: function(val) {
            return val[2] / 10;
          },
          label: {
            normal: {
              formatter: '{b}',
              position: 'right',
              show: true
              areaColor: "#1ecee5",
              borderWidth: 0,
              label: {
                show: false,
              },
            },
            emphasis: {
              show: true
            }
          },
          itemStyle: {
            normal: {
              color: '#fff'
            }
          }
        },
        series: [
          // 图片底色
          // {
          //   name: "",
          //   type: "scatter",
          //   coordinateSystem: "geo",
          //   symbol: "circle",
          //   symbolSize: [24, 24],
          //   label: {
          //     formatter: "{b}",
          //     position: "inside",
          //     show: true,
          //     color: "#FFFFFF",
          //     fontWeight: "bold",
          //   },
          //   itemStyle: {
          //     color(params) {
          //       return params.data.color;
          //     },
          //   },
          //   data: convertData(data),
          //   z: 3,
          // },
          // {
          //   //图片
          //   name: "图片",
          //   type: "scatter",
          //   coordinateSystem: "geo",
          //   symbol: function (value, params) {
          //     let img;
          //     let color = params.data.color;
          //     // let color = "#ff6b6c";
          //     switch (color) {
          //       case "#0081ff": // 浮充
          //         img = HomeChargeImage;
          //         break;
          //       case "#ff6b6c": // 放电
          //         img = HomeDischargeImage;
          //         break;
          //       case "#66f842": // 充电
          //         img = HomeNormalImage;
          //         break;
          //       case "#7668f9": // 停电
          //         img = HomeTingDianImage;
          //         break;
          //       default:
          //         // img = HomeChargeImage;
          //         img = HomeTransImage;
          //         break;
          //     }
          //     return params.data.name ? "circle" : "image://" + img;
          //   },
          //   symbolSize: [24, 24],
          //   label: {
          //     formatter: "{b}",
          //     position: "inside",
          //     show: true,
          //     color: "#FFFFFF",
          //     fontWeight: "bold",
          //   },
          //   itemStyle: {
          //     color(params) {
          //       return params.data.color;
          //     },
          //   },
          //   data: convertData(data),
          //   showEffectOn: "render",
          //   rippleEffect: {
          //     brushType: "stroke",
          //   },
          //   hoverAnimation: true,
          //   // zlevel: 3
          //   z: 4,
          // },
          // {
          //   name: "波纹",
          //   type: "effectScatter",
          //   coordinateSystem: "geo",
          //   rippleEffect: {
          //     scale: 3,
          //   },
          //   symbolSize: [18, 18],
          //   data: convertData(data),
          //   itemStyle: {
          //     color(params) {
          //       return params.data.color;
          //     },
          //   },
          //   tooltip: {
          //     show: true,
          //   },
          //   // zlevel: 2
          //   z: 2,
          // },
          {
            type: 'map',
            type: "map",
            map: mapName,
            show: false,
            geoIndex: 0,
            aspectScale: 0.75, //长宽比
            showLegendSymbol: false, // 存在legend时显示
            label: {
              normal: {
                show: true
                show: true,
              },
              emphasis: {
                show: false,
                textStyle: {
                  color: '#fff'
                }
              }
                  color: "#FF0000",
                },
              },
            },
            itemStyle: {
              areaColor: "#FF0000",
            },
            roam: true,
            itemStyle: {
              normal: {
                areaColor: '#031525',
                borderColor: '#3B5077',
              },
              emphasis: {
                areaColor: '#2B91B7'
              }
            },
            animation: false,
            data: data
            data: data0,
            tooltip: {
              show: false,
            },
          },
          {
            name: '点',
            type: 'scatter',
            coordinateSystem: 'geo',
            zlevel: 6,
          },
          {
            name: 'Top 5',
            type: 'effectScatter',
            coordinateSystem: 'geo',
            data: convertData(data.sort(function(a, b) {
              return b.value - a.value;
            }).slice(0, 10)),
            symbolSize: function(val) {
              return val[2] / 10;
            },
            showEffectOn: 'render',
            rippleEffect: {
              brushType: 'stroke'
            },
            hoverAnimation: true,
            label: {
              normal: {
                formatter: '{b}',
                position: 'left',
                show: false
              }
            },
            itemStyle: {
              normal: {
                color: 'yellow',
                shadowBlur: 10,
                shadowColor: 'yellow'
              }
            },
            zlevel: 1
          },
        ]
          ...this.subWaySeries
        ],
      };
    }
    },
    handleClick(params) {
      if (params.seriesIndex == 0) {
        let data = params.data;
        this.$emit("handleClick", data.data);
      }
    },
  },
  mounted() {
    this.setData();
  }
}
  async mounted() {
    let chart = this.$options.chart;
    if (this.subway) {
      // 如果需要显示地铁 则先加载地铁数据
      await this.getSubWayData();
    }
    this.setMapName();
    chart.off("click"); //防止chart点击触发多次
    chart.on("click", (params) => {
      this.handleClick(params);
    });
    chart.off("georoam");
    chart.on(
      "georoam",
      throttle(() => {
        let option = chart.getOption();
        chart.setOption(option);
      }, 100)
    );
  },
};
</script>