Echarts:实现拖拽效果

  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>

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

猜你喜欢

转载自www.cnblogs.com/youyouluo/p/11625157.html