说实话,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 这一项。
如果你有更好的方法,希望能给我留个地址!谢谢!