index.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. function anonymous() {
  2. const urlAll = window.location.href
  3. if (!urlAll.includes('?id=')) return alert('参数错误')
  4. const id = urlAll.split('?id=')[1]
  5. const obj = cardNames.find(v => v.id == id)
  6. if (!obj) return alert('参数错误')
  7. let dom = document.getElementById('container')
  8. let myChart = echarts.init(dom, null, {
  9. renderer: 'canvas',
  10. useDirtyRect: false
  11. })
  12. let option
  13. const data1 = []
  14. const data2 = []
  15. if (obj.son) {
  16. const ids = []
  17. obj.son.forEach((c1, i) => {
  18. c1.forEach(c2 => {
  19. data2.push({
  20. source: c2.source + '',
  21. target: c2.target + '',
  22. value: c2.value
  23. })
  24. if (!ids.map(a => a.id).includes(c2.source + '')) {
  25. ids.push({
  26. id: c2.source + '',
  27. symbolSize: 200 - (i + 1) * 50,
  28. tit: i === obj.son.length - 1,
  29. value: c2.value
  30. })
  31. }
  32. if (!ids.map(a => a.id).includes(c2.target + '')) {
  33. ids.push({
  34. id: c2.target + '',
  35. symbolSize: 200 - (i + 1) * 50,
  36. tit: i === obj.son.length - 1,
  37. value: c2.value
  38. })
  39. }
  40. })
  41. })
  42. ids.forEach(v => {
  43. const isCenter = id == v.id
  44. const centerX = window.innerWidth / 2 // 中心坐标x
  45. const centerY = window.innerHeight / 2 // 中心坐标y
  46. const obj = cardNames.find(c => c.id == v.id)
  47. data1.push({
  48. fixed: isCenter, // 固定中心节点位置
  49. x: isCenter ? centerX : null, // 设置中心节点坐标
  50. y: isCenter ? centerY : null,
  51. // category: id == v.id ? '中心' : '',
  52. symbolSize: id == v.id ? 200 : v.symbolSize,
  53. id: v.id,
  54. name: obj.name,
  55. symbol: `image://../../three/assets/out/${v.id}.png`
  56. // tit:v.tit
  57. })
  58. })
  59. }
  60. option = {
  61. tooltip: {
  62. show: true, // 默认显示
  63. showContent: true, // 是否显示提示框浮层
  64. trigger: 'item', // 触发类型,默认数据项触发
  65. triggerOn: 'mousemove', // 提示触发条件,mousemove鼠标移至触发,还有click点击触发
  66. alwaysShowContent: false, // 默认离开提示框区域隐藏,true为一直显示
  67. showDelay: 100, // 浮层显示的延迟,单位为 ms,默认没有延迟,也不建议设置。在 triggerOn 为 'mousemove' 时有效。
  68. hideDelay: 2000, // 浮层隐藏的延迟,单位为 ms,在 alwaysShowContent 为 true 的时候无效。
  69. enterable: false, // 鼠标是否可进入提示框浮层中,默认为false,如需详情内交互,如添加链接,按钮,可设置为 true。
  70. position: 'right', // 提示框浮层的位置,默认不设置时位置会跟随鼠标的位置。只在 trigger 为'item'的时候有效。
  71. confine: true, // 是否将 tooltip 框限制在图表的区域内。
  72. // 外层的 dom 被设置为 'overflow: hidden',或者移动端窄屏,导致 tooltip 超出外界被截断时,此配置比较有用。
  73. transitionDuration: 0.2, // 提示框浮层的移动动画过渡时间,单位是秒,设置为 0 的时候会紧跟着鼠标移动。
  74. formatter: function (params) {
  75. // 判断当前节点是否为第三级节点
  76. // 假设层级信息可以通过 params.data.tit 获取,或者通过其他逻辑判断
  77. if (params.data.tit) {
  78. // 如果是第三级节点,返回自定义的悬浮框内容
  79. return params.name
  80. } else {
  81. // 如果不是第三级节点,返回默认的悬浮框内容或不显示
  82. return '' // 不显示悬浮框
  83. }
  84. },
  85. // 自定义提示框的样式
  86. borderColor: '#896a43',
  87. backgroundColor: 'rgba(0,0,0,0.5)',
  88. textStyle: {
  89. color: '#dfd5c5',
  90. fontFamily: 'sk'
  91. },
  92. blur: {
  93. itemStyle: {
  94. opacity: 0.2 // 非突出节点的透明度
  95. },
  96. label: {
  97. show: false // 非突出节点隐藏标签
  98. }
  99. }
  100. },
  101. series: [
  102. {
  103. type: 'graph', // 关系图
  104. symbolKeepAspect: true, // 保持图片宽高比
  105. // name: "Name:", // 系列名称,用于tooltip的显示,legend 的图例筛选,在 setOption 更新数据和配置项时用于指定对应的系列。
  106. layout: 'force', // 图的布局,类型为力导图,'circular' 采用环形布局,见示例 Les Miserables
  107. legendHoverLink: true, // 是否启用图例 hover(悬停) 时的联动高亮。
  108. hoverAnimation: false, // 是否开启鼠标悬停节点的显示动画
  109. coordinateSystem: null, // 坐标系可选
  110. // xAxisIndex: 0, // x轴坐标 有多种坐标系轴坐标选项
  111. // yAxisIndex: 0, // y轴坐标
  112. force: {
  113. // 力引导图基本配置
  114. // initLayout: 'circular',
  115. // initLayout: , // 力引导的初始化布局,默认使用xy轴的标点
  116. repulsion: 600, //节点之间的斥力因子。支持数组表达斥力范围,值越大斥力越大。
  117. gravity: 0.01, //节点受到的向中心的引力因子。该值越大节点越往中心点靠拢。
  118. edgeLength: 240, //边的两个节点之间的距离,这个距离也会受 repulsion。[10, 50] 。值越小则长度越长
  119. layoutAnimation: true, // 因为力引导布局会在多次迭代后才会稳定,这个参数决定是否显示布局的迭代动画
  120. // 在浏览器端节点数据较多(>100)的时候不建议关闭,布局过程会造成浏览器假死。
  121. // 防止节点重叠
  122. friction: 0.8, // 增加摩擦力
  123. // 增加防止重叠的参数
  124. nodeOverlap: 20, // 防止节点重叠的参数
  125. // 优化布局迭代
  126. coolingFactor: 0.99, // 冷却因子,使布局逐渐稳定
  127. minMovement: 0.5, // 最小移动距离
  128. maxIteration: 2000 // 增加最大迭代次数
  129. },
  130. roam: true, // 是否开启鼠标缩放和平移漫游。默认不开启,true 为都开启。如果只想要开启缩放或者平移,可以设置成 'scale' 或者 'move'
  131. // zoom: 1,
  132. scaleLimit: {
  133. // 缩放限制,只在使用 force 布局时有效。
  134. min: 0.8 ? 0.8 : 0.5, // 最小缩放比例
  135. max: 3 // 最大缩放比例
  136. },
  137. nodeScaleRatio: 0.6, // 鼠标漫游缩放时节点的相应缩放比例,当设为0时节点不随着鼠标的缩放而缩放
  138. draggable: true, // 节点是否可拖拽,只在使用力引导布局的时候有用。
  139. focusNodeAdjacency: !window.isMobile ? true : false, // 是否在鼠标移到节点上的时候突出显示节点以及节点的边和邻接节点。
  140. emphasis: {
  141. itemStyle: {
  142. opacity: 1 // 突出节点的透明度
  143. }
  144. },
  145. blur: {
  146. itemStyle: {
  147. opacity: 0.3 // 非突出节点的透明度
  148. },
  149. lineStyle: {
  150. opacity: 0.3 // 非突出节点的透明度
  151. },
  152. label: {
  153. opacity: 0.3 // 非突出节点的透明度
  154. }
  155. },
  156. // symbol:'roundRect', // 关系图节点标记的图形。
  157. // ECharts 提供的标记类型包括:'circle'(圆形), 'rect'(矩形), 'roundRect'(圆角矩形),
  158. // 'triangle'(三角形), 'diamond'(菱形), 'pin'(大头针), 'arrow'(箭头)
  159. // 也可以通过 'image://url' 设置为图片,其中 url 为图片的链接。'path:// 这种方式可以任意改变颜色并且抗锯齿
  160. // symbolSize: 10 , // 也可以用数组分开表示宽和高,例如 [20, 10] 如果需要每个数据的图形大小不一样,
  161. // 可以设置为如下格式的回调函数:(value: Array|number, params: Object) => number|Array
  162. // symbolRotate:, // 关系图节点标记的旋转角度。注意在 markLine 中当 symbol 为 'arrow' 时会忽略 symbolRotate 强制设置为切线的角度。
  163. // symbolOffset:[0,0], // 关系图节点标记相对于原本位置的偏移。[0, '50%']
  164. edgeSymbol: ['circle', 'circle'], // 边两端的标记类型,可以是一个数组分别指定两端,也可以是单个统一指定。
  165. // 默认不显示标记,常见的可以设置为箭头,如下:edgeSymbol: ['circle', 'arrow']
  166. edgeSymbolSize: [0, 10], // 边两端的标记大小,可以是一个数组分别指定两端,也可以是单个统一指定。
  167. symbolSize: 120, // 关系图节点标记的大小,可以是一个数组分别指定两端,也可以是单个统一指定。
  168. itemStyle: {
  169. // ========图形样式,有 normal 和 emphasis 两个状态。
  170. // normal 是图形在默认状态下的样式;
  171. // emphasis 是图形在高亮状态下的样式,比如在鼠标悬浮或者图例联动高亮时。
  172. normal: {
  173. // 默认样式
  174. label: {
  175. show: true
  176. },
  177. borderType: 'solid', // 图形描边类型,默认为实线,支持 'solid'(实线), 'dashed'(虚线), 'dotted'(点线)。
  178. borderColor: '#fad166', // 设置图形边框为淡金色,透明度为0.4
  179. borderWidth: 2, // 图形的描边线宽。为 0 时无描边。
  180. opacity: 1 // 图形透明度。支持从 0 到 1 的数字,为 0 时不绘制该图形。默认0.5
  181. },
  182. emphasis: {
  183. // 高亮状态
  184. // lineStyle: {
  185. // width: 10,
  186. // },
  187. }
  188. },
  189. lineStyle: {
  190. // ========关系边的公用线条样式。
  191. normal: {
  192. color: '#fad166',
  193. width: '1', //线的粗细
  194. type: 'dashed', // 线的类型 'solid'(实线)'dashed'(虚线)'dotted'(点线)
  195. curveness: 0.3, // 线条的曲线程度,从0到1
  196. opacity: 0.5 // 图形透明度。支持从 0 到 1 的数字,为 0 时不绘制该图形。默认0.5
  197. },
  198. emphasis: {
  199. // 高亮状态
  200. }
  201. },
  202. label: {
  203. // ========结点图形上的文本标签
  204. normal: {
  205. show: true, // 是否显示标签。
  206. position: 'bottom', // 标签的位置。['50%', '50%'] [x,y]
  207. textStyle: {
  208. // 标签的字体样式
  209. color: '#fad166', // 字体颜色
  210. fontStyle: 'normal', // 文字字体的风格 'normal'标准 'italic'斜体 'oblique' 倾斜
  211. fontWeight: 'normal', // 'normal'标准,'bold'粗的,'bolder'更粗的,'lighter'更细的,或100 | 200 | 300 | 400...
  212. fontFamily: 'sk', // 文字的字体系列
  213. fontSize: 16
  214. }
  215. }
  216. },
  217. edgeLabel: {
  218. // ========连接线上的文本标签
  219. normal: {
  220. show: true, // 不显示连接线上的文字,如果显示只能显示结点的value值,而不是连接线的值
  221. // position: "middle", // 标签的位置。['50%', '50%'] [x,y]
  222. textStyle: {
  223. color: '#f4e6bf',
  224. fontSize: 16
  225. },
  226. formatter: '{c}'
  227. }
  228. },
  229. data: data1,
  230. // 设置连线edges的数据,
  231. links: data2, // 设置连线edges的数据
  232. // 添加节点布局优化
  233. circular: {
  234. rotateLabel: false
  235. },
  236. // 优化节点间距
  237. categories: [
  238. {
  239. name: '中心',
  240. itemStyle: {
  241. color: '#ff6b6b'
  242. }
  243. }
  244. ]
  245. }
  246. ]
  247. }
  248. if (myChart) {
  249. if (option && typeof option === 'object') {
  250. setTimeout(function () {
  251. myChart.setOption(option)
  252. }, 500)
  253. }
  254. } else {
  255. console.error('ECharts 初始化失败')
  256. }
  257. // 点击节点跳转链接
  258. myChart.on('click', function (params, e) {
  259. // if (params.componentType === "series" && params.dataType === "node") {
  260. // const nodeData = params.data;
  261. // openDetail(nodeData.idinfo, e);
  262. // }
  263. })
  264. window.addEventListener('resize', myChart.resize)
  265. }
  266. anonymous()