<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="./echarts.js"></script>
</head>
<body>
<div id="myChart" style="width: 800px; height: 600px;"></div> <script type="text/javascript">
var chart = echarts.init(document.getElementById('myChart')); var originData = [
{value: 335, name: '直接访问'},
{value: 310, name: '邮件营销'},
{value: 234, name: '联盟广告'},
{value: 135, name: '视频广告'},
{value: 1548, name: '搜索引擎'},
]; var color = ['#4a6dbf', '#15b3bc', '#f37a18', '#83c775', ' #fcb552']; originData.forEach(function(list, i) {
list.itemStyle = {
color: color[i],
};
}); var data = [].slice.call(originData) var option = {
tooltip: {
},
toolbox: {
feature: {
myRestore: {
show: true,
title: '还原',
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',
onclick: refreshChart,
},
},
},
legend: { // 图例
icon: 'rect',
data: [],
itemWidth: 12,
itemHeight: 12,
bottom: 'bottom',
},
grid: {
top: '5%',
left: '5%',
right: '5%',
bottom: '40',
containLabel: true,
},
xAxis: {
type: 'category',
boundaryGap: true,
splitLine: { // grid上每一条竖轴线
show: true,
interval: 'auto',
lineStyle: {
color: '#e8e8e8',
},
},
axisLine: { // x刻度上方的横轴线
lineStyle: {
color: '#e8e8e8',
},
},
axisLabel: { // x轴的刻度
textStyle: {
color: '#999',
},
},
data: [],
},
yAxis: {
type: 'value',
boundaryGap: false,
axisLine: { // y刻度上方的横轴线
lineStyle: {
color: '#e8e8e8',
},
},
splitLine: { // grid上每一条竖轴线
lineStyle: {
color: '#e8e8e8',
},
},
axisLabel: { // y轴的刻度
textStyle: {
color: '#999',
},
},
},
series: [{
name: 'pie',
type: 'pie',
center: ['50%', '45%'],
radius: ['0', '45%'],
data: data,
}, {
name: '模拟一个pie容器',
type: 'pie',
center: ['50%', '45%'],
radius: ['0', '49%'],
cursor: 'default',
hoverAnimation: true,
hoverOffset: 2,
label: {
show: false,
},
labelLine: {
show: false,
},
tooltip: {
padding: 0,
formatter: function() {
return '';
},
},
z: 0,
data: [{
value: 0,
name: '容器',
itemStyle: {
color: '#000',
opacity: '.1',
},
}],
}],
}; chart.setOption(option, true); var sector = null; // 鼠标点击选中的扇形
var sectorIndex; // 选中扇形在data中的index
var sx; // 原型横坐标距离鼠标位置横坐标的偏移距离
var sy; // 原型纵坐标距离鼠标位置纵坐标的偏移距离
var zr = chart.getZr(); // 生成一个zrender实例
var circleData = null; // 记录鼠标选中的小圆点的数据
var circleEl = []; // 保存生成的小圆点的数据,注意目前只有push,没有将废数据清除 function refreshChart() {
data = [].slice.call(originData)
option.series = {
name: 'pie',
type: 'pie',
center: ['50%', '45%'],
radius: ['0', '45%'],
data: data,
}; circleEl.forEach(function(list) {
zr.remove(list.el);
});
// zr.clear(); // clear会把整个chart画布清除
sector = null;
chart.setOption(option, true);
} // chart.on 绑定的事件只能在chart图形内部执行
// 利用chart绑定的事件会比zrender绑定的事件先执行的特点来判断小圆是否进入饼图范围
chart.on('mouseup', function(params) {
if (params.componentSubType === 'pie') {
// 圆
if (circleData) {
data.push(circleData.data);
chart.setOption({
series: {
data: data,
}
});
zr.remove(circleData.el);
circleData = null;
} // 扇形
if (sector) {
zr.remove(sector);
sector = null;
}
}
}); zr.on('mousedown', function(e) {
// 如果出现:触发鼠标点击扇形事件,并且移动到echarts的DOM元素外,释放鼠标点击,
// 再移动到饼图内,点击鼠标,则会再次触发一个鼠标点击和释放事件,这时候,上一个选中的扇形不会被正确的移除
// 所以在mosuedown多一个对sector的判定
if (e.target && sector) {
zr.remove(sector);
sector = null;
}
if (e.topTarget) {
// 这个是pie容器
if (e.target && e.target.seriesIndex === 1) {
return;
} // 发现一个圆
circleEl.forEach(function(list) {
if (list.id === e.topTarget.id) {
circleData = list;
}
}); // 是一个扇形
if (!circleData && e.target && !e.target.__title) {
var target = e.target;
sectorIndex = target.dataIndex;
sector = new echarts.graphic.Sector({
shape: echarts.util.extend({}, target.shape),
style: {
fill: target.style.fill,
opacity: 0.5
},
silent: true,
z: 1000,
}); sx = e.offsetX - target.shape.cx;
sy = e.offsetY - target.shape.cy; zr.add(sector); }
}
}); zr.on('mousemove', function (e) {
if (circleData) {
circleData.el.setShape({
cx: e.offsetX,
cy: e.offsetY,
});
} else if (sector) {
sector.setShape({
cx: e.offsetX - sx,
cy: e.offsetY - sy,
}); chart.dispatchAction({
type: 'showTip',
seriesIndex: 0,
dataIndex: sectorIndex,
position: [e.offsetX + 24, e.offsetY + 24], // 加24是为了避免tip影响mouseup事件判定
});
}
}); zr.on('mouseup', function(e) {
if (circleData) {
circleData = null;
} if (sector) {
var circle = new echarts.graphic.Circle({
shape: {
cx: e.offsetX,
cy: e.offsetY,
r: 10,
},
style: {
text: data[sectorIndex].name + ':' + data[sectorIndex].value,
textFill: sector.style.fill,
fill: sector.style.fill,
textOffset: [0, -20],
},
silent: true,
z: 1000,
});
zr.add(circle);
circleEl.push({
id: e.topTarget.id + 1,
el: circle,
data: data[sectorIndex],
}); data.splice(sectorIndex, 1);
chart.setOption({
series: {
data: data,
}
}); zr.remove(sector);
sector = null;
}
});
</script>
</body>
</html>

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

Echarts:实现拖拽效果的更多相关文章

  1. jQuery的DOM操作实例(2)——拖拽效果&&拓展插件

    一.原生JavaScript编写拖拽效果 二.jQuery编写的拖拽效果 三.在jQuery中拓展一个拖拽插件

  2. React.js实现原生js拖拽效果及思考

    一.起因&思路 不知不觉,已经好几天没写博客了...近来除了研究React,还做了公司官网... 一直想写一个原生js拖拽效果,又加上近来学react学得比较嗨.所以就用react来实现这个拖 ...

  3. js拖拽效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. WinForm支持拖拽效果

    有一个MSDN客户提问在WinForm中如何实现拖拽效果——比如在WinForm中有一个Button,我要实现的效果是拖拽这个Button到目标位置后生成一个该控件的副本. 其实这个操作主要分成三步走 ...

  5. js div浮动层拖拽效果代码

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. JS实现漂亮的窗口拖拽效果(可改变大小、最大化、最小化、关闭)

    转自<JS实现漂亮的窗口拖拽效果(可改变大小.最大化.最小化.关闭)>:http://www.jb51.net/article/73157.htm   这篇文章主要介绍了JS实现漂亮的窗口 ...

  7. JQ实现3D拖拽效果

    <!DOCTYPE HTML> <html onselectstart='return false'> <head> <meta http-equiv=&qu ...

  8. 用JS实现版面拖拽效果

    类似于这样的一个版面,点击标题栏,实现拖拽效果. 添加onmousedown事件 通过获取鼠标的坐标(clientX,clientY)来改变面板的位置 注意:面板使用绝对定位方式,是以左上角为参考点, ...

  9. Swift2.0下UICollectionViews拖拽效果的实现

    文/过客又见过客(简书作者)原文链接:http://www.jianshu.com/p/569c65b12c8b著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 原文UICollecti ...

  10. ExtJS拖拽效果

    ExtJS拖拽效果 <html> <head> <title>hello</title> <meta http-equiv="conte ...

随机推荐

  1. 微信小程序实现下拉刷新上拉加载

    代码片段:https://developers.weixin.qq.com/s/K9VbWZmy7e8C

  2. Ubuntu 18.04 使用apt-get 华为源支持 arm64 鲲鹏处理器

    网上搜的源,什么阿里云163等等的,都不支持arm64 执行以下代码,使用华为源 wget -O /etc/apt/sources.list https://repo.huaweicloud.com/ ...

  3. mysql简单优化的一些总结

    mysql对cpu的利用特点: 5.1之前,多核支持较弱:5.1可利用4个核:5.5可利用24核:5.6可利用64个核:每个连接对应一个线程,每个并发query只能使用一个核 mysql对内存的利用特 ...

  4. python抽象基类

    抽象基类 抽象基类提了一种方式,用以组织对象的层次结构,做出关于所需方法的断言,以及实现其他一些功能 要定义抽象基类,需要使用abc模块,该模块定义了一个元类(ABCMeta) 和一组装饰器(@abs ...

  5. 剑指offer:从尾到头打印链表

    题目 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList. 解题思路 在不改变链表结构的前提下,因为单向链表本身的结构是从头到尾的,现在用从尾到头遍历打印,可以联想到“先进后出”, 因此我 ...

  6. linux系统编程之进程(五)

    今天继续学习系统编程,学习的主题还是进程,今天主要讨论的是守护进程相关的概念,开始进入正题: 什么是守护进程:       守护进程的创建步骤: 在描述它之前,首先得先了解两个概念:进程组.会话期: ...

  7. 微信小程序~性能

    (1)优化建议 setData setData 是小程序开发中使用最频繁的接口,也是最容易引发性能问题的接口.在介绍常见的错误用法前,先简单介绍一下 setData 背后的工作原理. 工作原理 小程序 ...

  8. BZOJ3277 串 和 BZOJ3473 字符串

    字符串 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串? 分析 参照自为风月马前卒和Candy?的题解. 广义后缀自动机不就是把很多串的SAM建到了一个S ...

  9. 软件测试过程中如何区分什么是功能bug,什么是需求bug,什么是设计bug?

    问题描述: 测试过程中如何区分什么是功能bug,什么是需求bug,什么是设计bug? 精彩答案: 会员 土土的豆豆: 本期问题其实主要是针对不同方面或纬度上对于bug的一个归类和定位. 个人认为,从软 ...

  10. Codeforces Round #604 (Div. 2) E. Beautiful Mirrors

    链接: https://codeforces.com/contest/1265/problem/E 题意: Creatnx has n mirrors, numbered from 1 to n. E ...