经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » Echarts » 查看文章
vue中echarts关系图动态增删节点以及连线方式
来源:jb51  时间:2022/8/1 11:08:54  对本文有异议

echarts关系图动态增删节点及连线

首先,echarts的关系图有个非常坑的地方,就是节点的id必须连续,否则增删之后节点无法连接!

下面是简单的演示实现,实际要用动态增删的话,要复杂的多得多。

我是用的关系图是力引导图

更新后不会重新渲染,只是动态增加的效果

  1. //假设你已经渲染了关系图
  2. test() {
  3. let option = this.chart.getOption() //获取option配置项
  4. //START增加节点,假设根据id连线
  5. // option.series[0].data.push({name: '测试节点', category: 1, id: 6, des: '测试描述'})
  6. // option.series[0].links.push({source: 0, target: 6, name: '测试连线'})
  7. //END
  8. //删除节点START
  9. let data = option.series[0].data //获取节点数据
  10. let link = option.series[0].links //获取边的数据
  11. let flag = -1
  12. for(let i = 0; i<data.length;i++){//假设删除id为1的节点
  13. if (data[i].id===1){
  14. data.splice(i,1)
  15. link.splice(i-1,1)
  16. flag = i
  17. break
  18. }
  19. }
  20. for(let i = flag; i<data.length;i++){
  21. data[i].id--
  22. if (i!==data.length){
  23. link[i-1].target--
  24. }
  25. }
  26. //删除节点END
  27. //更新关系图
  28. this.chart.setOption(option)
  29. },

echarts关系图vue完整代码

vue 使用echarts 实现关系图,效果如下:

说明: 关系图可以有两种,一种是指定坐标x,y。 另外一种就是通过设置series属性

  1. layout: "force",
  2. force: {
  3. repulsion: [-2, 100], //节点之间的斥力因子。支持数组表达斥力范围,值越大斥力越大。
  4. gravity: 0.03, //节点受到的向中心的引力因子。该值越大节点越往中心点靠拢。
  5. edgeLength: [20, 200], //边的两个节点之间的距离,这个距离也会受 repulsion:[10, 50]值越小则长度越长
  6. layoutAnimation: false,
  7. },

vue全部代码如下

  1. <template>
  2. ? <div class="uni-chart-container">
  3. ? ? <div class="uni-bar-charts" :id="id"></div>
  4. ? </div>
  5. </template>
  1. <script>
  2. import echarts from "echarts";
  3. import resize from "../mixins/resize";
  4. export default {
  5. ? name: "uniGraph",
  6. ? mixins: [resize],
  7. ? components: {},
  8. ? data() {
  9. ? ? return {
  10. ? ? ? options: {
  11. ? ? ? ? title: {
  12. ? ? ? ? ? text: "",
  13. ? ? ? ? },
  14. ? ? ? ? series: [],
  15. ? ? ? },
  16. ? ? ? barData: [],
  17. ? ? ? myChart: null,
  18. ? ? ? seriesName: "",
  19. ? ? };
  20. ? },
  21. ? props: {
  22. ? ? id: {
  23. ? ? ? type: String,
  24. ? ? ? require: true,
  25. ? ? },
  26. ? ? sortMethod: {
  27. ? ? ? type: String,
  28. ? ? ? default: "desc",
  29. ? ? },
  30. ? ? title: {
  31. ? ? ? type: String,
  32. ? ? },
  33. ? ? optionsSetup: {
  34. ? ? ? type: Object,
  35. ? ? ? default: () => {
  36. ? ? ? ? return {};
  37. ? ? ? },
  38. ? ? },
  39. ? ? isVertical: {
  40. ? ? ? type: Boolean,
  41. ? ? ? default: true,
  42. ? ? },
  43. ? ? chartsData: {
  44. ? ? ? type: Object,
  45. ? ? ? default: function () {
  46. ? ? ? ? return {
  47. ? ? ? ? ? nodes: [
  48. ? ? ? ? ? ? {
  49. ? ? ? ? ? ? ? name: "李志强",
  50. ? ? ? ? ? ? ? category: 0,
  51. ? ? ? ? ? ? ? symbolSize: 30,
  52. ? ? ? ? ? ? ? value: ["确诊"],
  53. ? ? ? ? ? ? ? color: "#F10F0F",
  54. ? ? ? ? ? ? },
  55. ? ? ? ? ? ? {
  56. ? ? ? ? ? ? ? name: "张亮",
  57. ? ? ? ? ? ? ? category: 2,
  58. ? ? ? ? ? ? ? symbolSize: 30,
  59. ? ? ? ? ? ? ? value: ["密接"],
  60. ? ? ? ? ? ? ? color: "#FFC001",
  61. ? ? ? ? ? ? },
  62. ? ? ? ? ? ? {
  63. ? ? ? ? ? ? ? name: "王飞",
  64. ? ? ? ? ? ? ? category: 1,
  65. ? ? ? ? ? ? ? symbolSize: 30,
  66. ? ? ? ? ? ? ? value: ["次密接"],
  67. ? ? ? ? ? ? ? color: "#1D84C6",
  68. ? ? ? ? ? ? },
  69. ? ? ? ? ? ? {
  70. ? ? ? ? ? ? ? name: "王丽",
  71. ? ? ? ? ? ? ? category: 2,
  72. ? ? ? ? ? ? ? symbolSize: 30,
  73. ? ? ? ? ? ? ? value: ["密接"],
  74. ? ? ? ? ? ? ? color: "#FFC001",
  75. ? ? ? ? ? ? },
  76. ? ? ? ? ? ? {
  77. ? ? ? ? ? ? ? name: "符华",
  78. ? ? ? ? ? ? ? category: 1,
  79. ? ? ? ? ? ? ? symbolSize: 30,
  80. ? ? ? ? ? ? ? value: ["次密接"],
  81. ? ? ? ? ? ? ? color: "#1D84C6",
  82. ? ? ? ? ? ? },
  83. ? ? ? ? ? ? {
  84. ? ? ? ? ? ? ? name: "钱峰",
  85. ? ? ? ? ? ? ? category: 1,
  86. ? ? ? ? ? ? ? symbolSize: 30,
  87. ? ? ? ? ? ? ? value: ["次密接"],
  88. ? ? ? ? ? ? ? color: "#1D84C6",
  89. ? ? ? ? ? ? },
  90. ? ? ? ? ? ? {
  91. ? ? ? ? ? ? ? name: "吴梦",
  92. ? ? ? ? ? ? ? category: 1,
  93. ? ? ? ? ? ? ? symbolSize: 30,
  94. ? ? ? ? ? ? ? color: "#1D84C6",
  95. ? ? ? ? ? ? ? value: ["次密接"],
  96. ? ? ? ? ? ? },
  97. ? ? ? ? ? ? {
  98. ? ? ? ? ? ? ? name: "杨月",
  99. ? ? ? ? ? ? ? category: 1,
  100. ? ? ? ? ? ? ? symbolSize: 30,
  101. ? ? ? ? ? ? ? color: "#1D84C6",
  102. ? ? ? ? ? ? ? value: ["次密接"],
  103. ? ? ? ? ? ? },
  104. ? ? ? ? ? ],
  105. ? ? ? ? ? links: [
  106. ? ? ? ? ? ? {
  107. ? ? ? ? ? ? ? source: "李志强",
  108. ? ? ? ? ? ? ? target: "张亮",
  109. ? ? ? ? ? ? ? linkTip: "聚餐",
  110. ? ? ? ? ? ? },
  111. ? ? ? ? ? ? {
  112. ? ? ? ? ? ? ? source: "张亮",
  113. ? ? ? ? ? ? ? target: "王飞",
  114. ? ? ? ? ? ? ? linkTip: "出现在同一场所",
  115. ? ? ? ? ? ? },
  116. ? ? ? ? ? ? {
  117. ? ? ? ? ? ? ? source: "李志强",
  118. ? ? ? ? ? ? ? target: "王丽",
  119. ? ? ? ? ? ? ? linkTip: "出现在同一场所",
  120. ? ? ? ? ? ? },
  121. ? ? ? ? ? ? {
  122. ? ? ? ? ? ? ? source: "张亮",
  123. ? ? ? ? ? ? ? target: "钱峰",
  124. ? ? ? ? ? ? ? linkTip: "聚餐",
  125. ? ? ? ? ? ? },
  126. ? ? ? ? ? ? {
  127. ? ? ? ? ? ? ? source: "张亮",
  128. ? ? ? ? ? ? ? target: "符华",
  129. ? ? ? ? ? ? ? linkTip: "家庭聚集",
  130. ? ? ? ? ? ? },
  131. ? ? ? ? ? ? {
  132. ? ? ? ? ? ? ? source: "张亮",
  133. ? ? ? ? ? ? ? target: "杨月",
  134. ? ? ? ? ? ? ? linkTip: "出现在同一场所",
  135. ? ? ? ? ? ? },
  136. ? ? ? ? ? ? {
  137. ? ? ? ? ? ? ? source: "张亮",
  138. ? ? ? ? ? ? ? target: "吴梦",
  139. ? ? ? ? ? ? ? linkTip: "出现在同一场所",
  140. ? ? ? ? ? ? },
  141. ? ? ? ? ? ],
  142. ? ? ? ? ? categories: [
  143. ? ? ? ? ? ? {
  144. ? ? ? ? ? ? ? name: "确诊",
  145. ? ? ? ? ? ? },
  146. ? ? ? ? ? ? {
  147. ? ? ? ? ? ? ? name: "次密接",
  148. ? ? ? ? ? ? },
  149. ? ? ? ? ? ? {
  150. ? ? ? ? ? ? ? name: "密接",
  151. ? ? ? ? ? ? },
  152. ? ? ? ? ? ],
  153. ? ? ? ? };
  154. ? ? ? },
  155. ? ? },
  156. ? ? customColor: {
  157. ? ? ? type: Array,
  158. ? ? ? default: function () {
  159. ? ? ? ? return ["#1890FF"];
  160. ? ? ? },
  161. ? ? },
  162. ? ? // 展示前5条 可传5
  163. ? ? maxL: {
  164. ? ? ? default: "auto",
  165. ? ? },
  166. ? ? codeStatus: {
  167. ? ? ? type: Array,
  168. ? ? },
  169. ? },
  170. ? watch: {
  171. ? ? chartsData: {
  172. ? ? ? deep: true,
  173. ? ? ? immediate: true,
  174. ? ? ? handler: function (v) {
  175. ? ? ? ? let _this = this;
  176. ? ? ? ? this.$nextTick(function () {
  177. ? ? ? ? ? _this.init();
  178. ? ? ? ? });
  179. ? ? ? },
  180. ? ? },
  181. ? },
  182. ? beforeDestroy() {
  183. ? ? if (!this.myChart) {
  184. ? ? ? return;
  185. ? ? }
  186. ? ? this.myChart.dispose();
  187. ? ? this.myChart = null;
  188. ? },
  189. ? methods: {
  190. ? ? init() {
  191. ? ? ? //构建3d饼状图
  192. ? ? ? if (this.myChart) this.myChart.dispose();
  193. ? ? ? this.myChart = echarts.init(document.getElementById(this.id));
  194. ? ? ? this.editorOptions(this.chartsData);
  195. ? ? ? // 传入数据生成 option
  196. ? ? ? this.myChart.setOption(this.options);
  197. ? ? },
  198. ? ? editorOptions(val) {
  199. ? ? ? let series = this.getSeries(val);
  200. ? ? ? var options = {
  201. ? ? ? ? tooltip: {
  202. ? ? ? ? ? // formatter: (e) => {
  203. ? ? ? ? ? // ? console.log(e);
  204. ? ? ? ? ? // ? return e.name + e.data.value;
  205. ? ? ? ? ? // },
  206. ? ? ? ? },
  207. ? ? ? ? animationDuration: 1500,
  208. ? ? ? ? animationEasingUpdate: "quinticInOut",
  209. ? ? ? ? color: this.customColor,
  210. ? ? ? ? grid: this.setOptionsMargin(),
  211. ? ? ? ? series: series,
  212. ? ? ? };
  213. ? ? ? this.options = options;
  214. ? ? },
  215. ? ? getSeries(newData) {
  216. ? ? ? const series = [];
  217. ? ? ? series.push({
  218. ? ? ? ? name: "关系图谱",
  219. ? ? ? ? type: "graph",
  220. ? ? ? ? hoverAnimation: true,
  221. ? ? ? ? layout: "force",
  222. ? ? ? ? force: {
  223. ? ? ? ? ? repulsion: [-2, 100], //节点之间的斥力因子。支持数组表达斥力范围,值越大斥力越大。
  224. ? ? ? ? ? gravity: 0.03, //节点受到的向中心的引力因子。该值越大节点越往中心点靠拢。
  225. ? ? ? ? ? edgeLength: [20, 200], //边的两个节点之间的距离,这个距离也会受 repulsion:[10, 50]值越小则长度越长
  226. ? ? ? ? ? layoutAnimation: false,
  227. ? ? ? ? },
  228. ? ? ? ? nodeScaleRatio: 0.6,
  229. ? ? ? ? draggable: true,
  230. ? ? ? ? roam: false, //鼠标缩放和平移
  231. ? ? ? ? symbol: "circle",
  232. ? ? ? ? edgeSymbol: ["circle", "arrow"],
  233. ? ? ? ? data: newData.nodes,
  234. ? ? ? ? links: newData.links,
  235. ? ? ? ? categories: newData.categories,
  236. ? ? ? ? cursor: "pointer",
  237. ? ? ? ? focusNodeAdjacency: true,
  238. ? ? ? ? scaleLimit: {
  239. ? ? ? ? ? //所属组件的z分层,z值小的图形会被z值大的图形覆盖
  240. ? ? ? ? ? min: 0, //最小的缩放值
  241. ? ? ? ? ? max: 9, //最大的缩放值
  242. ? ? ? ? },
  243. ? ? ? ? edgeLabel: {
  244. ? ? ? ? ? //连接线上文字
  245. ? ? ? ? ? normal: {
  246. ? ? ? ? ? ? show: true,
  247. ? ? ? ? ? ? textStyle: {
  248. ? ? ? ? ? ? ? fontSize: 10,
  249. ? ? ? ? ? ? },
  250. ? ? ? ? ? ? formatter: (e) => {
  251. ? ? ? ? ? ? ? return e.name;
  252. ? ? ? ? ? ? },
  253. ? ? ? ? ? },
  254. ? ? ? ? },
  255. ? ? ? ? label: {
  256. ? ? ? ? ? normal: {
  257. ? ? ? ? ? ? show: true,
  258. ? ? ? ? ? },
  259. ? ? ? ? },
  260. ? ? ? ? lineStyle: {
  261. ? ? ? ? ? normal: {
  262. ? ? ? ? ? ? width: 1.5,
  263. ? ? ? ? ? ? curveness: 0,
  264. ? ? ? ? ? ? type: "solid",
  265. ? ? ? ? ? },
  266. ? ? ? ? },
  267. ? ? ? });
  268. ? ? ? return series;
  269. ? ? },
  270. ? ? // 边距设置
  271. ? ? setOptionsMargin() {
  272. ? ? ? const optionsSetup = this.optionsSetup;
  273. ? ? ? const grid = {
  274. ? ? ? ? left: optionsSetup.marginLeft,
  275. ? ? ? ? right: optionsSetup.marginRight,
  276. ? ? ? ? bottom: optionsSetup.marginBottom,
  277. ? ? ? ? top: optionsSetup.marginTop,
  278. ? ? ? ? containLabel: true,
  279. ? ? ? };
  280. ? ? ? return grid;
  281. ? ? },
  282. ? },
  283. };
  284. </script>
  1. <style lang="scss">
  2. .uni-chart-container,
  3. .uni-bar-charts {
  4. ? width: 100%;
  5. ? height: 100%;
  6. }
  7. </style>

resize文件如下:debounce可以自行实现

  1. import {
  2. debounce
  3. } from "@/utils/utils.js";
  4. export default {
  5. data() {
  6. return {};
  7. },
  8. mounted() {
  9. this.initListener();
  10. },
  11. beforeDestroy() {
  12. this.destroyListener();
  13. },
  14. deactivated() {
  15. this.destroyListener();
  16. },
  17. methods: {
  18. initListener() {
  19. window.addEventListener("resize", debounce(this.resize, 100));
  20. },
  21. destroyListener() {
  22. window.removeEventListener("resize", this.resize);
  23. },
  24. resize() {
  25. const {
  26. myChart
  27. } = this;
  28. myChart && myChart.resize();
  29. },
  30. },
  31. };

以上为个人经验,希望能给大家一个参考,也希望大家多多支持w3xue。 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号