Echarts:实现拖拽效果

Stella981
• 阅读 572
  1 <!DOCTYPE html>
  2 <html>
  3 <head>
  4   <meta charset="utf-8">
  5   <script src="./echarts.js"></script>
  6 </head>
  7 <body>
  8   <div id="myChart" style="width: 800px; height: 600px;"></div>
  9 
 10 <script type="text/javascript">
 11   var chart = echarts.init(document.getElementById('myChart'));
 12 
 13   var originData = [
 14     {value: 335, name: '直接访问'},
 15     {value: 310, name: '邮件营销'},
 16     {value: 234, name: '联盟广告'},
 17     {value: 135, name: '视频广告'},
 18     {value: 1548, name: '搜索引擎'},
 19   ];
 20 
 21   var color = ['#4a6dbf', '#15b3bc', '#f37a18', '#83c775', ' #fcb552'];
 22 
 23   originData.forEach(function(list, i) {
 24     list.itemStyle = {
 25       color: color[i],
 26     };
 27   });
 28 
 29   var data = [].slice.call(originData)
 30 
 31   var option = {
 32     tooltip: {
 33     },
 34     toolbox: {
 35       feature: {
 36         myRestore: {
 37           show: true,
 38           title: '还原',
 39           icon: 'M3.8,33.4 M47,18.9h9.8V8.7 M56.3,20.1 C52.1,9,40.5,0.6,26.8,2.1C12.6,3.7,1.6,16.2,2.1,30.6 M13,41.1H3.1v10.2 M3.7,39.9c4.2,11.1,15.8,19.5,29.5,18 c14.2-1.6,25.2-14.1,24.7-28.5',
 40           onclick: refreshChart,
 41         },
 42       },
 43     },
 44     legend: {  // 图例
 45       icon: 'rect',
 46       data: [],
 47       itemWidth: 12,
 48       itemHeight: 12,
 49       bottom: 'bottom',
 50     },
 51     grid: {
 52       top: '5%',
 53       left: '5%',
 54       right: '5%',
 55       bottom: '40',
 56       containLabel: true,
 57     },
 58     xAxis: {
 59       type: 'category',
 60       boundaryGap: true,
 61       splitLine: {  // grid上每一条竖轴线
 62         show: true,
 63         interval: 'auto',
 64         lineStyle: {
 65           color: '#e8e8e8',
 66         },
 67       },
 68       axisLine: {  // x刻度上方的横轴线
 69         lineStyle: {
 70           color: '#e8e8e8',
 71         },
 72       },
 73       axisLabel: {  // x轴的刻度
 74         textStyle: {
 75           color: '#999',
 76         },
 77       },
 78       data: [],
 79     },
 80     yAxis: {
 81       type: 'value',
 82       boundaryGap: false,
 83       axisLine: {  // y刻度上方的横轴线
 84         lineStyle: {
 85           color: '#e8e8e8',
 86         },
 87       },
 88       splitLine: {  // grid上每一条竖轴线
 89         lineStyle: {
 90           color: '#e8e8e8',
 91         },
 92       },
 93       axisLabel: {  // y轴的刻度
 94         textStyle: {
 95           color: '#999',
 96         },
 97       },
 98     },
 99     series: [{
100       name: 'pie',
101       type: 'pie',
102       center: ['50%', '45%'],
103       radius: ['0', '45%'],
104       data: data,
105     }, {
106       name: '模拟一个pie容器',
107       type: 'pie',
108       center: ['50%', '45%'],
109       radius: ['0', '49%'],
110       cursor: 'default',
111       hoverAnimation: true,
112       hoverOffset: 2,
113       label: {
114         show: false,
115       },
116       labelLine: {
117         show: false,
118       },
119       tooltip: {
120         padding: 0,
121         formatter: function() {
122           return '';
123         },
124       },
125       z: 0,
126       data: [{
127         value: 0,
128         name: '容器',
129         itemStyle: {
130           color: '#000',
131           opacity: '.1',
132         },
133       }],
134     }],
135   };
136 
137   chart.setOption(option, true);
138 
139   var sector = null;  // 鼠标点击选中的扇形
140   var sectorIndex;  // 选中扇形在data中的index
141   var sx;  // 原型横坐标距离鼠标位置横坐标的偏移距离
142   var sy;  // 原型纵坐标距离鼠标位置纵坐标的偏移距离
143   var zr = chart.getZr();  // 生成一个zrender实例
144   var circleData = null;  // 记录鼠标选中的小圆点的数据
145   var circleEl = [];  // 保存生成的小圆点的数据,注意目前只有push,没有将废数据清除
146 
147   function refreshChart() {
148     data = [].slice.call(originData)
149     option.series = {
150       name: 'pie',
151       type: 'pie',
152       center: ['50%', '45%'],
153       radius: ['0', '45%'],
154       data: data,
155     };
156 
157     circleEl.forEach(function(list) {
158       zr.remove(list.el);
159     });
160     // zr.clear();  // clear会把整个chart画布清除
161     sector = null;
162     chart.setOption(option, true);
163   }
164 
165   // chart.on 绑定的事件只能在chart图形内部执行
166   // 利用chart绑定的事件会比zrender绑定的事件先执行的特点来判断小圆是否进入饼图范围
167   chart.on('mouseup', function(params) {
168     if (params.componentSubType === 'pie') {
169       // 圆
170       if (circleData) {
171         data.push(circleData.data);
172         chart.setOption({
173           series: {
174             data: data,
175           }
176         });
177         zr.remove(circleData.el);
178         circleData = null;
179       }
180 
181       // 扇形
182       if (sector) {
183         zr.remove(sector);
184         sector = null;
185       }
186     }
187   });
188 
189   zr.on('mousedown', function(e) {
190     // 如果出现:触发鼠标点击扇形事件,并且移动到echarts的DOM元素外,释放鼠标点击,
191     // 再移动到饼图内,点击鼠标,则会再次触发一个鼠标点击和释放事件,这时候,上一个选中的扇形不会被正确的移除
192     // 所以在mosuedown多一个对sector的判定
193     if (e.target && sector) {
194       zr.remove(sector);
195       sector = null;
196     }
197     if (e.topTarget) {
198       // 这个是pie容器
199       if (e.target && e.target.seriesIndex === 1) {
200         return;
201       }
202 
203       // 发现一个圆
204       circleEl.forEach(function(list) {
205         if (list.id === e.topTarget.id) {
206           circleData = list;
207         }
208       });
209 
210       // 是一个扇形
211       if (!circleData && e.target && !e.target.__title) {
212         var target = e.target;
213         sectorIndex = target.dataIndex;
214         sector = new echarts.graphic.Sector({
215           shape: echarts.util.extend({}, target.shape),
216           style: {
217             fill: target.style.fill,
218             opacity: 0.5
219           },
220           silent: true,
221           z: 1000,
222         });
223 
224         sx = e.offsetX - target.shape.cx;
225         sy = e.offsetY - target.shape.cy;
226 
227         zr.add(sector);
228 
229       }
230     }
231   });
232 
233   zr.on('mousemove', function (e) {
234     if (circleData) {
235       circleData.el.setShape({
236         cx: e.offsetX,
237         cy: e.offsetY,
238       });
239     } else if (sector) {
240       sector.setShape({
241         cx: e.offsetX - sx,
242         cy: e.offsetY - sy,
243       });
244 
245       chart.dispatchAction({
246         type: 'showTip',
247         seriesIndex: 0,
248         dataIndex: sectorIndex,
249         position: [e.offsetX + 24, e.offsetY + 24],  // 加24是为了避免tip影响mouseup事件判定
250       });
251     }
252   });
253 
254   zr.on('mouseup', function(e) {
255     if (circleData) {
256       circleData = null;
257     } if (sector) {
258       var circle = new echarts.graphic.Circle({
259         shape: {
260           cx: e.offsetX,
261           cy: e.offsetY,
262           r: 10,
263         },
264         style: {
265           text: data[sectorIndex].name + ':' + data[sectorIndex].value,
266           textFill: sector.style.fill,
267           fill: sector.style.fill,
268           textOffset: [0, -20],
269         },
270         silent: true,
271         z: 1000,
272       });
273       zr.add(circle);
274       circleEl.push({
275         id: e.topTarget.id + 1,
276         el: circle,
277         data: data[sectorIndex],
278       });
279 
280       data.splice(sectorIndex, 1);
281       chart.setOption({
282         series: {
283           data: data,
284         }
285       });
286 
287       zr.remove(sector);
288       sector = null;
289     }
290   });
291 </script>
292 </body>
293 </html>

这个是一年前工作里用到,莫名翻了出来。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
2年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
2年前
java基础60 JavaScript字符串转换成数字(网页知识)
1、字符串转换成数字1<!doctypehtml2<html3<head4<metacharset"utf8"5<title字符串转换成数字练习</title6</head7<scripttype"text/javascrip
Stella981 Stella981
2年前
List的Select 和Select().tolist()
List<PersondelpnewList<Person{newPerson{Id1,Name"小明1",Age11,Sign0},newPerson{Id2,Name"小明2",Age12,
Stella981 Stella981
2年前
JavaScript DOM操作案例点击按钮显示图片
1<!DOCTYPEhtml2<htmllang"en"3<head4<metacharset"UTF8"5<title</title6</head7<body8<inputtype"button"v
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Js对象查找字符个数及出现的最多个数
1<!DOCTYPEhtml2<htmllang"en"3<head4<metacharset"UTF8"5<titleJs对象查找字符个数及出现的最多个数</title6</head7<body8
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这