echarts在地图上画饼状图

说实话,echarts 有很多的功能真的很难去实现,而且实现了也不完美;就拿今天这个主题来说,我们有时候可能会有这样的需求:

一个大企业,在全球范围内都有项目,于是要求我们做一张表报能展示全球范围内各个城市的项目以及在该项目产能占比(饼状图)。

这样的结果就是要求我们把饼状图定位到经纬度中。

先把我写的例子拿出来,然后在说一下我的思路和对这个问题的看法:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>ECharts</title>
    <!-- 引入 echarts.js -->
    <script src="../../Scripts/echarts.min.js"></script>
    <script src="../../Scripts/world.js"></script>  
</head>
<body>
    <!-- 为ECharts准备一个具备大小(宽高)的Dom -->
    <div style="height:500px;overflow:hidden;">
        <div id="main" style="width:98%;height:500px; margin-top:20px;margin-left:20px; margin-right:20px;"></div>
        <div id="main2" style="width:98%;height:500px; margin-top:20px;margin-left:20px; margin-right:20px;float:left;"></div>
    </div>  
    <!--注意 main2 被隐藏了,不可用 display:none; 这样的样式,因为会影响到定位的精确。-->    
    <script type="text/javascript">
        // 基于准备好的dom,初始化echarts实例
        var myChart = echarts.init(document.getElementById('main'));        
        var myChart2 = echarts.init(document.getElementById('main2'));      
        var option = {                    
            title: {
                text: '例子',
                left: 'center',
                itemGap: 0,
                textStyle: {
                    color: '#eee'
                },
            },                 
            geo: {
                map: 'world',
                silent: false,
                geoIndex: 0,                
                roam: true
            },
            series: []
        }
        myChart2.setOption(option);//这里只是画了一个世界地图
        //detail为饼状图数据
        var detail = [
            {
                name: 'pie1',
                coord: [112, -23],
                data: [
                    { name: 'data1', value: 12 },
                    { name: 'data2', value: 22 },
                    { name: 'data3', value: 32 },
                    { name: 'data4', value: 42 }
                ]
            },
            {
                name: 'pie2',
                coord: [12, 15],
                data: [
                    { name: 'data1', value: 12 },
                    { name: 'data2', value: 22 },
                    { name: 'data3', value: 32 },
                    { name: 'data4', value: 42 }
                ]
            },
            {
                name: 'pie3',
                coord: [112, 0],
                data: [
                    { name: 'data1', value: 12 },
                    { name: 'data2', value: 22 },
                    { name: 'data3', value: 32 },
                    { name: 'data4', value: 42 }
                ]
            }
        ]
        //getDe()为饼状图数据处理函数
        function getDe() {
            var ser = [];
            for (var i = 0; i < detail.length; i++) {
                ser.push(
                    {
                        name: detail[i].name,
                        type: 'pie',                               
                        radius: '5%',
                        center: myChart2.convertToPixel({ geoIndex: 0 }, detail[i].coord),
                        data: detail[i].data,
                    }
                );                       
            }
            return ser;
        }                              
        var option = {                            
            title: {
                text: '例子',
                left: 'center',
                itemGap: 0,
                textStyle: {
                    color: '#eee'
                },
            },                 
            geo: {
                map: 'world',
                silent: false,
                geoIndex: 0,                
                roam: true
            },           
            series: getDe()
        }
        myChart.setOption(option);                                             
    </script>
</body>
</html>


因为只为实现效果,所以代码写得尽可能的简单,去掉了多余的效果,效果图如下:



可以看出来定位的效果就已经出来了,下面说一下思路。

1、想要将饼状图定位到世界地图上,得先要有世界地图;于是,要先画 geo 背景,这样才能得到经纬去定位。

2、查看饼状图的配置项,其中涉及到定位的就是这个 center 了,得尝试把经纬度转化为像素值。


3、查看 echarts API 发现有这样的 API  convertToPixel


OK!所有的东西都备齐了,下面是填坑的时候了。

坑我就不说了,直接说解决方法!

从上面的整体代码中可以看出:

1、绘制了两张图,

2、一张有数据,一张没有数据并被隐藏;

<div style="height:500px;overflow:hidden;">
        <div id="main" style="width:98%;height:500px; margin-top:20px;margin-left:20px; margin-right:20px;"></div>
        <div id="main2" style="width:98%;height:500px; margin-top:20px;margin-left:20px; margin-right:20px;float:left;"></div>
    </div>  
我将 main2 隐藏了,但是却在它上面布了 canvas,而且 main、main2 上所绘 canvas 的区别在于一个有数据一个没有数据,这是因为我需要用 main2 中的 geo 给 main 中的数据一个将经纬度转化为像素值的方法,也就是下面中的  myChart2.convertToPixel({ geoIndex: 0 }, detail[i].coord)

function getDe() {
            var ser = [];
            for (var i = 0; i < detail.length; i++) {
                ser.push(
                    {
                        name: detail[i].name,
                        type: 'pie',                               
                        radius: '5%',
                        center: myChart2.convertToPixel({ geoIndex: 0 }, detail[i].coord),
                        data: detail[i].data,
                    }
                );                       
            }
            return ser;
        } 

之所以这样做是因为  convertToPixel 只有在 canvas 绘制完成之后才能生效,也就是说  myChart2.convertToPixel({ geoIndex: 0 }, detail[i].coord) 只有在 myChart2.setOption(option) 之后才能接收到返回值!

最后,还是有问题的,这样定位并不支持放大缩小,希望以后 echarts 在 type:pie 中也能加上 coordinateSystem 这一项。

如果你有更好的方法,希望能给我留个地址!谢谢!



  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值