手把手·教你用 Echarts 画 ChinaMap

手把手·教你用 ECharts 画 ChinaMap

tip: 学习此教程你需要使用 Echarts 指定版本和 China.js

我使用的版本是下面的

题目要求

地图上显示“省份”,并按照省份统计时长、用不同颜色分档显示;当鼠标移至某个景区,该省份背景图变色(表示被选中),同时显示该省份所有机器的运营时长、有效订单金额等;(说白了就差不多和疫情官网那个图效果差不多)

具体实现的效果如下

实现步骤

  • 根据data画出基础地图
  • 显示省份名称
  • 按运营时长进行分色,运营时长越长的颜色越重,反之相反(这里需要注意,它默认会按 data 中的 value 进行分色,所以我会把运营时长转换为 value)
  • 鼠标悬停选中样式,点击选中,弹出提示框。点击空白区域取消选中,提示框消失
根据data画出基础地图

myChart.setOption(optionMap);

<!DOCTYPE html>
<html>

<head>
  <meta charset='utf-8'>
  <link rel="stylesheet" href="//at.alicdn.com/t/font_2572350_vt8vhw864w.css">
  <script src="https://cdn.bootcss.com/echarts/4.3.0-rc.1/echarts.min.js"></script>
  <script src="./china.js"></script>
  <title>Echarts Test</title>
</head>

<body>
  <div id="myEchartsContent" style="width: 100%;height:600px;background-color: orangered;"></div>
  <script type="text/javascript">
    // 基于准备好的dom,初始化echarts实例
    var myChart = echarts.init(document.getElementById('myEchartsContent'));

    function randomData() {
      return Math.round(Math.random() * 500);
    }
    
    // 模拟假数据
    var mydata = [{
        name: '北京',
        operateTime: randomData(), // 运营时间
        orderAmount: randomData() // 订单金额
      }, {
        name: '天津',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '上海',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '重庆',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '河北',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '河南',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '云南',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '辽宁',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '黑龙江',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '湖南',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '安徽',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '山东',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '新疆',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '江苏',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '浙江',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '江西',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '湖北',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '广西',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '甘肃',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '山西',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '内蒙古',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '陕西',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '吉林',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '福建',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '贵州',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '广东',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '青海',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '西藏',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '四川',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '宁夏',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '海南',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '台湾',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '香港',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '澳门',
        operateTime: randomData(),
        orderAmount: randomData()
      }
    ];

    var optionMap = {
      backgroundColor: '#FFFFFF',
      title: {
        text: '机器人运营大数据',
        subtext: '',
        x: 'center'
      },
      tooltip: {
        trigger: 'item',
      },
      //配置属性
      series: [{
        name: '数据',
        type: 'map',
        mapType: 'china',
        symbolSize: 14,
        roam: true,
        label: {
          emphasis: {
            show: false
          }
        },
        data: myData //数据
      }]
    };
    //使用制定的配置项和数据显示图表
    myChart.setOption(optionMap);

    // 图表自适应
    window.addEventListener('resize', function () {
      myChart.resize()
    })
  </script>
</body>
</html>

这步很简单,引入echarts和china.js,初始化echarts实例,给data一个数据列表,使用配置好的option进行图表绘制即可

显示省份名称

show: true //省份名称

//配置属性
series: [{
    name: '数据',
    type: 'map',
    mapType: 'china',
    symbolSize: 14,
    roam: true,
    selectedMode: "single", // 选中效果固化,字符串取值可选'single','multiple','single'单选,'multiple'多选
    label: {
        normal: {
            // formatter: '{b}',
            show: true //省份名称  
        },
        emphasis: {
            show: false
        }
    },
    data: myData //数据
}]
按运营时长进行分色

主要就是根据data中的value值进行分色,值越大颜色越深

// 处理假数据(根据哪个字段分颜色,哪个字段就改成value)
var newMyData = mydata.map((item) => {
    // console.log(item);
    return {
        name: item.name,
        value: item.operateTime,
        orderAmount: item.orderAmount
    }
})
// console.log(newMyData);

...

//左侧小导航图标
visualMap: {
    show: true,
    x: 'left',
    y: 'center',
    splitList: [{
           start: 200,
           end: 300
        }, {
           start: 100,
           end: 200
        }, {
           start: 0,
           end: 100
        },
    ],
    color: ['#FF9985', '#FFE5DB', '#FFFFFF'],
},

//配置属性
series: [{
    ...
    data: newMyData //数据
}]

这一步处理假数据,把运营时间转换为 value ,在 visualMap 组件里进行颜色分色,重新在series中修改data的新值即可

鼠标悬停选中样式

tooltip

var areaColor = '#C7FFFD' // 选中后的地图颜色
var position = [10, 10] // tooltip初始显示位置
var isClickMap = false // 是否点击了地图

tooltip: {
    trigger: 'item',
        enterable: true, // 是否可以移到提示框上
            // tooltip的初始位置
            // position,
            // alwaysShowContent: true, // 是否一直显示tooltip
            hideDelay: 100, // tooltip隐藏的延迟(alwaysShowContent: true 时无效)
            triggerOn: "click", // 点击地图后显示tooltip

            // 鼠标悬停在地图上时的省机器人信息
            formatter: function (params) { //自行定义formatter格式
                // console.log("formatter params:", params);
                if (!!params.data) {
                   return `
                    <div class="province_robot_info">
                    <div class="pri_head">
                    <span>${params.name}</span>
                    <span id="btn_xiangqing" class="xiangqing">详情<i class="iconfont icon-xiangqing"></i></span>
                    </div>
                    <span>运营时长: ${params.data.value}小时</span>
                    <span>订单金额: ${params.data.orderAmount}元</span>
                    </div>
                   `
                 } else {
                      return
                 }
            },
},

// 点击全局Echarts触发
myChart.getZr().on('click', function () {
    // 如果isClickMap为true才执行(当你点击了地图后才能触发以下逻辑)
    if (isClickMap) {
        isClickMap = false
        myChart.setOption(optionMap) // 因为Echarts是用canvas绘制出来的,所以在这里进行重绘时就可以实现点击空白(非地图)区域取消选中
    }
})

// 地图点击事件
myChart.on("click", function (params) {
    isClickMap = true
    // tooltip 详情点击事件
    var btnXQEve = document.getElementById("btn_xiangqing")
    // console.log(btnXQEve);
    btnXQEve.addEventListener("click", function () {
        console.log("点击详情打开机器人运营统计页面");
    })
})

此步骤最为重要也更难实现,挺难找的感觉,但是实现过后又感觉没啥东西

总结

完整代码在这里

<!DOCTYPE html>
<html>

<head>
  <meta charset='utf-8'>
  <link rel="stylesheet" href="//at.alicdn.com/t/font_2572350_vt8vhw864w.css">
  <script src="https://cdn.bootcss.com/echarts/4.3.0-rc.1/echarts.min.js"></script>
  <script src="./china.js"></script>
  <title>Echarts Test</title>
  <style>
    .province_robot_info {
      display: flex;
      flex-direction: column;
      justify-content: flex-start;
    }

    .pri_head {
      display: flex;
      justify-content: space-between;
      align-items: center;
    }

    .icon-xiangqing {
      font-size: 12px;
      margin-left: 3px;
    }
  </style>
</head>

<body>
  <div id="myEchartsContent" style="width: 100%;height:600px;background-color: orangered;"></div>
  <script type="text/javascript">
    // 基于准备好的dom,初始化echarts实例
    var myChart = echarts.init(document.getElementById('myEchartsContent'));

    function randomData() {
      return Math.round(Math.random() * 500);
    }

    var areaColor = '#C7FFFD' // 选中后的地图颜色
    var position = [10, 10] // tooltip初始显示位置
    var isClickMap = false // 是否点击了地图
    // 模拟假数据
    var mydata = [{
        name: '北京',
        operateTime: randomData(), // 运营时间
        orderAmount: randomData() // 订单金额
      }, {
        name: '天津',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '上海',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '重庆',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '河北',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '河南',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '云南',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '辽宁',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '黑龙江',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '湖南',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '安徽',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '山东',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '新疆',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '江苏',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '浙江',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '江西',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '湖北',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '广西',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '甘肃',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '山西',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '内蒙古',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '陕西',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '吉林',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '福建',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '贵州',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '广东',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '青海',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '西藏',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '四川',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '宁夏',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '海南',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '台湾',
        operateTime: randomData(),
        orderAmount: randomData()
      },
      {
        name: '香港',
        operateTime: randomData(),
        orderAmount: randomData()
      }, {
        name: '澳门',
        operateTime: randomData(),
        orderAmount: randomData()
      }
    ];

    // 处理假数据(根据哪个字段分颜色,哪个字段就改成value)
    var newMyData = mydata.map((item) => {
      // console.log(item);
      return {
        name: item.name,
        value: item.operateTime,
        orderAmount: item.orderAmount
      }
    })
    // console.log(newMyData);

    var optionMap = {
      backgroundColor: '#FFFFFF',
      title: {
        text: '机器人运营大数据',
        subtext: '',
        x: 'center'
      },
      tooltip: {
        trigger: 'item',
        enterable: true, // 是否可以移到提示框上
        // tooltip的初始位置
        // position,
        // alwaysShowContent: true, // 是否一直显示tooltip
        hideDelay: 100, // tooltip隐藏的延迟(alwaysShowContent: true 时无效)
        triggerOn: "click", // 点击地图后显示tooltip

        // 鼠标悬停在地图上时的省机器人信息
        formatter: function (params) { //自行定义formatter格式
          // console.log("formatter params:", params);
          if (!!params.data) {
            return `
            <div class="province_robot_info">
              <div class="pri_head">
                <span>${params.name}</span>
                <span id="btn_xiangqing" class="xiangqing">详情<i class="iconfont icon-xiangqing"></i></span>
              </div>
              <span>运营时长: ${params.data.value}小时</span>
              <span>订单金额: ${params.data.orderAmount}元</span>
            </div>
            `
          } else {
            return
          }
        },

        // show: true, //不显示提示标签
        // formatter: '{b}', //提示标签格式
        // backgroundColor: "#ff7f50", //提示标签背景颜色
        // textStyle: {
        //   color: "#fff"
        // } //提示标签字体颜色

      },

      //左侧小导航图标
      visualMap: {
        show: true,
        x: 'left',
        y: 'center',
        splitList: [{
            start: 200,
            end: 300
          },
          {
            start: 100,
            end: 200
          }, {
            start: 0,
            end: 100
          },

        ],
        color: ['#FF9985', '#FFE5DB', '#FFFFFF'],
      },
      // 写上了没效果,所以注释
      // geo: {
      //   map: 'some_svg'
      // },
      //配置属性
      series: [{
        name: '数据',
        type: 'map',
        mapType: 'china',
        symbolSize: 14,
        roam: true,
        selectedMode: "single", // 选中效果固化,字符串取值可选'single','multiple','single'单选,'multiple'多选
        label: {
          normal: {
            // formatter: '{b}',
            show: true //省份名称  
          },
          emphasis: {
            show: false
          }
        },
        itemStyle: {
          emphasis: { // 鼠标悬停选中样式
            borderWidth: 0,
            // borderColor: '#fff',
            areaColor, // 选中后的地图颜色
            label: {
              show: true,
              textStyle: {
                // color: '#fff'
              }
            }
          }
        },
        data: newMyData //数据
      }]
    };
    //使用制定的配置项和数据显示图表
    myChart.setOption(optionMap);

    // 初始tooltip显示
    // myChart.dispatchAction({
    //   type: 'showTip',
    //   seriesIndex: 0,
    //   dataIndex: 0,
    // })

    // 点击全局Echarts触发
    myChart.getZr().on('click', function () {
      // 如果isClickMap为true才执行(当你点击了地图后才能触发以下逻辑)
      if (isClickMap) {
        isClickMap = false
        myChart.setOption(optionMap) // 因为Echarts是用canvas绘制出来的,所以在这里进行重绘时就可以实现点击空白(非地图)区域取消选中
      }
    })

    // 地图点击事件
    myChart.on("click", function (params) {
      isClickMap = true
      // tooltip 详情点击事件
      var btnXQEve = document.getElementById("btn_xiangqing")
      // console.log(btnXQEve);
      btnXQEve.addEventListener("click", function () {
        console.log("点击详情打开机器人运营统计页面");
      })
    })

    // 图表自适应
    window.addEventListener('resize', function () {
      myChart.resize()
    })
  </script>
</body>

</html>

这么多你都看下来了,给个三连再走呗🍗~

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 28
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码小余の博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值