chart.html 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. <!DOCTYPE html>
  2. <html lang="zh-CN" style="height: 100%">
  3. <head>
  4. <meta charset="utf-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>chart</title>
  7. </head>
  8. <style>
  9. *{
  10. margin: 0;
  11. padding: 0;
  12. box-sizing: border-box;
  13. }
  14. </style>
  15. <body style="height: 100%; margin: 0">
  16. <div id="container" style="height: 100%"></div>
  17. <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  18. <script type="text/javascript" src="https://cdn.staticfile.org/echarts/5.4.2/echarts.min.js"></script>
  19. <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  20. <script type="text/javascript">
  21. function randomColor() {
  22. return '#' + Math.floor(
  23. (
  24. Math.random() * (1 - 0.3) + 0.3
  25. ) * 0xffffff
  26. ).toString(16)
  27. }
  28. const rawInfo = [
  29. {
  30. name: '开埠通商',
  31. color: randomColor(),
  32. corpList: [
  33. // {
  34. // companyName: "正泰橡皮物品制造厂",
  35. // createTime: "2023-08-03 14:21:45",
  36. // creatorId: null,
  37. // creatorName: "",
  38. // description: "创办正泰橡皮物品制造厂,首创“回力”商标。",
  39. // dirCode: "",
  40. // display: null,
  41. // fileIds: "",
  42. // id: 10,
  43. // name: "刘永康",
  44. // sort: null,
  45. // stage: "开埠通商",
  46. // story: "",
  47. // updateTime: "2023-08-03 14:21:45",
  48. // }
  49. ],
  50. id: 'time-0'
  51. },
  52. {
  53. name: '曲折发展',
  54. color: randomColor(),
  55. corpList: [],
  56. id: 'time-1'
  57. },
  58. {
  59. name: '步履维艰',
  60. color: randomColor(),
  61. corpList: [],
  62. id: 'time-2'
  63. },
  64. {
  65. name: '筚路蓝缕',
  66. color: randomColor(),
  67. corpList: [],
  68. id: 'time-3'
  69. },
  70. {
  71. name: '改革开放',
  72. color: randomColor(),
  73. corpList: [],
  74. id: 'time-4'
  75. },
  76. {
  77. name: '战略负重',
  78. color: randomColor(),
  79. corpList: [],
  80. id: 'time-5'
  81. },
  82. {
  83. name: '创新驱动',
  84. color: randomColor(),
  85. corpList: [],
  86. id: 'time-6'
  87. },
  88. {
  89. name: '追梦未来',
  90. color: randomColor(),
  91. corpList: [],
  92. id: 'time-7'
  93. },
  94. ]
  95. const nodesForRender = [
  96. {
  97. name: "历史回顾",
  98. level: 0,
  99. category: null,
  100. symbolSize: 100,
  101. itemStyle: {
  102. color: {
  103. type: "radial",
  104. x: 0.5,
  105. y: 0.5,
  106. r: 0.5,
  107. colorStops: [
  108. {
  109. offset: 0,
  110. color: "#00c7ef"
  111. },
  112. {
  113. offset: 0.8,
  114. color: "#00c7ef"
  115. },
  116. {
  117. offset: 1,
  118. color: "rgba(0, 0, 0, 0.3)"
  119. }
  120. ],
  121. global: false
  122. },
  123. shadowColor: "rgba(255, 255, 255, 0.5)",
  124. shadowBlur: 10
  125. },
  126. label: {
  127. position: 'inside',
  128. show: true,
  129. color: '#fff',
  130. fontSize: '18px',
  131. }
  132. },
  133. ]
  134. const edgesForRender = []
  135. Promise.allSettled(rawInfo.map((timeInfoItem) => {
  136. return axios({
  137. method: 'post',
  138. url: `https://sit-shgybwg.4dage.com/api/show/history/pageList`,
  139. headers: {
  140. "Content-Type": "application/json",
  141. },
  142. data: {
  143. stage: timeInfoItem.name
  144. },
  145. }).then((res) => {
  146. return res.data.data.records
  147. }).then((res) => {
  148. timeInfoItem.corpList = res
  149. })
  150. })).then((res) => {
  151. for (const timeInfoItem of rawInfo) {
  152. nodesForRender.push({
  153. name: timeInfoItem.name,
  154. level: 1,
  155. category: timeInfoItem.name,
  156. symbolSize: 50,
  157. itemStyle: {
  158. color: timeInfoItem.color,
  159. shadowColor: "rgba(255, 255, 255, 0.5)",
  160. shadowBlur: 10
  161. },
  162. label: {
  163. position: 'right',
  164. show: true,
  165. color: '#fff',
  166. fontSize: '16px',
  167. }
  168. })
  169. edgesForRender.push({
  170. category: null,
  171. lineStyle: {
  172. normal: {
  173. color: timeInfoItem.color,
  174. },
  175. },
  176. source: '历史回顾',
  177. target: timeInfoItem.name,
  178. })
  179. for (const corpItem of timeInfoItem.corpList) {
  180. nodesForRender.push({
  181. name: corpItem.name,
  182. level: 2,
  183. idForSend: corpItem.id,
  184. category: timeInfoItem.name,
  185. symbolSize: 10,
  186. itemStyle: {
  187. borderColor: timeInfoItem.color,
  188. color: 'transparent',
  189. shadowColor: "rgba(255, 255, 255, 0.5)",
  190. shadowBlur: 10
  191. },
  192. select: {
  193. itemStyle: {
  194. borderColor: timeInfoItem.color,
  195. color: timeInfoItem.color,
  196. },
  197. },
  198. label: {
  199. position: 'right',
  200. show: true,
  201. color: '#fff',
  202. fontSize: '14px',
  203. }
  204. })
  205. edgesForRender.push({
  206. category: timeInfoItem.name,
  207. lineStyle: {
  208. normal: {
  209. color: timeInfoItem.color,
  210. },
  211. },
  212. source: timeInfoItem.name,
  213. target: corpItem.name,
  214. })
  215. }
  216. }
  217. console.log(nodesForRender);
  218. console.log(edgesForRender);
  219. showAll()
  220. })
  221. let myChart = null
  222. var dom = document.getElementById('container');
  223. myChart = echarts.init(dom, null, {
  224. renderer: 'canvas',
  225. useDirtyRect: false
  226. });
  227. function showAll() {
  228. return showChart()
  229. }
  230. function changeTime(timeIdx) {
  231. if (Number.isInteger(timeIdx) && timeIdx >= 0) {
  232. return showChart(timeIdx)
  233. } else {
  234. console.error('[page using echart] changeTime: invalid param!', timeIdx);
  235. }
  236. }
  237. let nodesForRenderTemp = null
  238. let edgesForRenderTemp = null
  239. function showChart(timeIdx) {
  240. if (timeIdx !== undefined) {
  241. nodesForRenderTemp = nodesForRender.filter((item) => {
  242. return item.category === rawInfo[timeIdx].name
  243. })
  244. edgesForRenderTemp = edgesForRender.filter((item) => {
  245. return item.category === rawInfo[timeIdx].name
  246. })
  247. } else {
  248. nodesForRenderTemp = null
  249. edgesForRenderTemp = null
  250. }
  251. myChart.clear()
  252. myChart.setOption({
  253. animationDurationUpdate: 1500,
  254. animationEasingUpdate: 'quinticInOut',
  255. series: [
  256. {
  257. type: 'graph',
  258. layout: 'force',
  259. // 力引导布局是模拟弹簧电荷模型在每两个节点之间添加一个斥力,每条边的两个节点之间添加一个引力
  260. force: {
  261. // initLayout: 'circular', // 进行力引导布局前的初始化布局,初始化布局会影响到力引导的效果。默认不进行任何布局,使用节点中提供的 x, y 作为节点的位置。如果不存在的话会随机生成一个位置。也可以选择使用环形布局 'circular'。
  262. // repulsion: 100, // 节点之间的斥力因子。傻逼文档把edgeLength当数组用的用法写到这上边了。
  263. repulsion: 300, // 节点之间的斥力因子。傻逼文档把edgeLength当数组用的用法写到这上边了。
  264. // gravity: 0.1, // 节点受到的向中心的引力因子。该值越大节点越往中心点靠拢。
  265. // edgeLength: [50, 400], // 把各个边的两个节点之间的距离归一化到这个范围内。与repulsion共同作用。
  266. edgeLength: 100, // 把各个边的两个节点之间的距离归一化到这个范围内。与repulsion共同作用。
  267. layoutAnimation: true,
  268. friction: 0.5, // 这个参数能减缓节点的移动速度。取值范围 0 到 1。但是仍然是个试验性的参数,参见 #11024。
  269. },
  270. data: timeIdx === undefined ? nodesForRender : nodesForRenderTemp,
  271. // 或者叫edges
  272. links: timeIdx === undefined ? edgesForRender : edgesForRenderTemp,
  273. // 单选or多选or不可选
  274. selectedMode: 'single',
  275. // 选中时的图形样式
  276. select: {
  277. itemStyle: {
  278. shadowBlur: 30,
  279. shadowColor: 'rgba(255, 255, 125, 0.7)',
  280. },
  281. label: {
  282. fontWeight: 'bold',
  283. },
  284. },
  285. // hover时的图形样式
  286. emphasis: {
  287. scale: false,
  288. },
  289. // hover时只照常显示有联系的那些节点和边,其余的暗色显示。
  290. focusNodeAdjacency: true,
  291. // 图表是否可以移动、缩放
  292. roam: true,
  293. scaleLimit: {
  294. min: 0.5, //最小的缩放值
  295. max: 3, //最大的缩放值
  296. },
  297. draggable: true,
  298. lineStyle: {
  299. normal: {
  300. width: 1.5,
  301. curveness: 0,
  302. type: "solid"
  303. }
  304. },
  305. edgeSymbol: ["circle", "arrow"],
  306. edgeSymbolSize: [4, 8],
  307. }
  308. ]
  309. }, true)
  310. }
  311. // 用户选中节点后,向父窗口post message
  312. function onSelect(params) {
  313. if (params.dataType !== 'node') {
  314. return
  315. }
  316. window.parent.postMessage({
  317. msg: `node-selected`,
  318. nodeLevel: nodesForRenderTemp ? nodesForRenderTemp[params.dataIndexInside].level : nodesForRender[params.dataIndexInside].level,
  319. nodeStageName: nodesForRenderTemp ? nodesForRenderTemp[params.dataIndexInside].category : nodesForRender[params.dataIndexInside].category,
  320. nodeStageIdx: rawInfo.findIndex((item) => {
  321. return item.name === (nodesForRenderTemp ? nodesForRenderTemp[params.dataIndexInside].category : nodesForRender[params.dataIndexInside].category)
  322. }),
  323. nodeId: nodesForRenderTemp ? nodesForRenderTemp[params.dataIndexInside].idForSend : nodesForRender[params.dataIndexInside].idForSend,
  324. }, '*')
  325. }
  326. myChart.on('select', onSelect)
  327. window.addEventListener('resize', myChart.resize);
  328. </script>
  329. </body>
  330. </html>