可视化—gojs 超多超实用经验分享(一)
可视化的库非常多,如:echarts、highcharts、antv 系列、d3、gojs.....
按照可自定义绘图的程度排序: gojs、d3js > antv > echarts 、highcharts
(相关资料图)
如果需求简单,不需要自定义图元素,那么 echarts 、highcharts 看中哪个 demo 效果就选用哪个库。
如果有一定程度需要自定义图元素,那么可以看 antv g2/g6 demo 是否能满足需求,可自定义大部分图元素。
如果上面的都不能解决你的需求,那么就是高可定制的,可以考虑 d3js、gojs,还是先去看 demo,看哪个更接近你的需求就采用哪个。
gojs 是一个用于构建交互式可视化图的 js 库,使用可自定义的模板和布局构建复杂节点、链接和组,从而构建出简单到复杂的各类图,如流程图、脑图、组织图、甘特图等。而且提供了许多用于用户交互的高级功能,例如拖放、复制和粘贴、就地文本编辑......
本文是关于如何使用可视化库 gojs 的介绍及使用时的小技巧。gojs 的高可自定义性,非常适合需求复杂的图交互。
绘制基本流程简单介绍,
引入库,可以下载,也可以引入 cdn 地址html 文件创建画布容器,并设置宽高创建实例,定义布局,样式,交互,属性,事件等绑定节点和连线数据,渲染图表先绘制出基本的实例,让后续的学习,有个大致的轮廓
> <script lang="ts" setup> import go from "@/assets/js/go"; import { onMounted } from "vue"; let diagram: any = null; const $ = go.GraphObject.make; onMounted(() => { init(); }); function init() { // 创建diagram实例, diagram = $(go.Diagram, "myDiagramDiv"); // 分组模板 diagram.groupTemplate = $(go.Group, "Auto", { /* options 后期主要学习部分 */ }); // 连线模板 diagram.linkTemplate = $(go.Link, { /* options 后期主要学习部分 */ }); // 节点模板 diagram.nodeTemplate = $(go.Node, "Auto", { /* options 后期主要学习部分 */ }); // 绘制节点模板 追加新的 自定义的模板类型 diagram.nodeTemplateMap.add(); diagram.layout = $(go.LayeredDigraphLayout, { direction: 0, // 布局方向,0 水平 90 垂直 layerSpacing: 120, // 节点间隔 isOngoing: false, }); var nodeDataArray = []; // 节点集合 var linkDataArray = []; // 分组集合 diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray); }</script>
1. 设置分组模板,默认样式,统一最小宽度,展开收起状态监听// 分组模板diagram.groupTemplate = $( go.Group, "Auto", { layout: $(go.LayeredDigraphLayout, { direction: 0, columnSpacing: 5 }), isSubGraphExpanded: false, // 默认展开 true 、折叠false. subGraphExpandedChanged: function (group) {}, // 功能 小 ## 4 }, $( go.Shape, "RoundedRectangle", // 分组形状,圆角矩形 { parameter1: 5, opacity: 0.7, minSize: new go.Size(120, NaN) }, // 圆角 透明度 统一最小宽度 new go.Binding("fill", "color"), // 绑定填充色,如果是固定颜色,可以直接在上述对象中,填写对应的属性,如 fill:"#ccc" new go.Binding("stroke", "color") // 绑定描边色,同上 ), $( go.Panel, "Vertical", { defaultAlignment: go.Spot.Left, margin: 4 }, $( go.Panel, "Horizontal", { defaultAlignment: go.Spot.Top, margin: 4, padding: new go.Margin(5, 5, 5, 2) }, // 设置收缩按钮,用于展开折叠子图 +/- $("SubGraphExpanderButton", { padding: new go.Margin(0, 5, 0, 0) }), $( go.TextBlock, { font: "bold 12px Sans-Serif", stroke: "white" }, new go.Binding("text", "", (node) => node.key + `(${node.children})`) // 分组名称+成员个数: name(children) ) ), // 分组展开后的 面板占位 $( go.Placeholder, { background: "white" }, new go.Binding("padding", "", function (node) { // 每组背景色和边距 return node.children ? new go.Margin(10, 10) : new go.Margin(0, 10); }) ) ));
2. 分组名称显示成员个数: 分组名称+成员个数: name(children)$( go.TextBlock, { font: "bold 12px Sans-Serif", stroke: "white" }, new go.Binding("text", "", (node) => node.key + `(${node.children})`) // 分组名称+成员个数: name(children));
3. 分组成员为空时,不显示 placeholder 占位留白// 分组展开后的 面板占位$( go.Placeholder, { background: "white" }, new go.Binding("padding", "", function (node) { // 每组背景色和边距 return node.children ? new go.Margin(10, 10) : new go.Margin(0, 10); }));
4. 分组第一次展开请求获取成员接口,监听展开收起状态 subGraphExpandedChanged:fnsubGraphExpandedChanged: function (group) { // 子图展开或收起的状态 group.isSubGraphExpanded var groupData = group.part.data; // 获取分组 数据 if (!groupData.isRequested) { // 设置一个标识位,标明该分组数据是否 有请求过接口, // 未请求过,可以编写请求接口代码,或者添加已知节点代码, groupData.isRequested = true; diagram.model.addNodeData({ key: "任意要显示的node节点名称", group: groupData.key, color: groupData.color, icon: groupData.icon, }); // diagram.model.addLinkData({ from: "", to: "" }) // 新增节点 有连线关系则添加连线对象 diagram.animationManager.stopAnimation(); // 取消动画 } // 请求过 就直接 展开或收起分组 isOngoing 属性true会自动布局,但是会影响用户拖拽效果,因此分组自行布局后,需要在改为false diagram.layout.isOngoing = true; setTimeout(() => { diagram.layout.isOngoing = false; });}
5. 设置节点模板// 节点模板diagram.nodeTemplate = $( go.Node, "Auto", { mouseEnter: mouseEnter, mouseLeave: mouseLeave, click: nodeclick, }, $( go.Shape, "Rectangle", { strokeWidth: 1, stroke: "white", fill: "white" }, new go.Binding("stroke", "isHighlighted", (sel) => (sel ? "#1E90FF" : "white")).ofObject(), // 鼠标选中高亮样式 new go.Binding("strokeWidth", "isHighlighted", (sel) => (sel ? 3 : 1)).ofObject() ), $( go.Panel, "Horizontal", { width: 280, padding: new go.Margin(5, 5, 5, 2) }, $( go.TextBlock, // 设置 icon { font: "bold 12px Sans-Serif", stroke: "white", width: 24, textAlign: "center" }, new go.Binding("text", "icon"), // 绑定icon 图表文案 new go.Binding("background", "color") // 绑定 背景色 ), $( go.TextBlock, { margin: 5, width: 240, font: "15px Verdana", stroke: "#444", maxSize: new go.Size(260, NaN), maxLines: 1, overflow: go.TextBlock.OverflowEllipsis, // maxSize maxLines overflow 属性联合使用,用于文案截断 显示... name: "TEXT", // 命名随意,用于后期 鼠标状态事件,节点成员的获取 }, new go.Binding("text", "key") ), { toolTip: $( // 鼠标悬浮显示全部文案 ,默认触发时间比较长,可以通过属性来修改 "ToolTip", $(go.TextBlock, { margin: 4 }, new go.Binding("text", "key")) ), } ));
6. 设置节点的 icon,此处以文字为例$( go.TextBlock, // 设置 icon { font: "bold 12px Sans-Serif", stroke: "white", width: 24, textAlign: "center" }, new go.Binding("text", "icon"), // 绑定icon 图表文案 new go.Binding("background", "color") // 绑定 背景色),
7. 文案太长截取显示...,鼠标悬浮显示全部{ toolTip: $( // 鼠标悬浮显示全部文案 ,默认触发时间比较长,可以通过属性来修改 "ToolTip", $(go.TextBlock, { margin: 4 }, new go.Binding("text", "key")) );}
8. 设置鼠标移入、移出状态,点击节点高亮相关联节点function mouseEnter(e, obj) { var text = obj.findObject("TEXT"); text.stroke = "#1E90FF";}function mouseLeave(e, obj) { var text = obj.findObject("TEXT"); text.stroke = "#444";}function nodeclick(e, node) { var diagram = node.diagram; diagram.clearHighlighteds(); node.findNodesConnected().each(function (l) { l.isHighlighted = true; }); node.linksConnected.each(function (n) { n.isHighlighted = true; });}
9. 动态追加节点diagram.model.addNodeData({ key: "任意要显示的node节点名称", group: "分组名", color: "节点背景颜色", icon: "icon文字",});
10. 节点众多需要不同表现样式时,可定义不同的节点模板仅有一种不同形式时,可使用 diagram.nodeTemplateMap.add(node)
调用不同的节点模板多种不同模板时,是封装一个方法,生成模板,在调用diagram.nodeTemplateMap.set(typename, node)
11. 每个节点前后追加 input/output spot 的两种方式方法一:该方法需要重点关注的方法是 makePort
,函数调用位置及返回值
var nodeDataArray = [{ key: "A", category: "Start", text: "节点设置左右连接点" }];var linkDataArray = [ { from: "A", to: "B", frompid: "1", topid: "1" }, // createPort方法 portId { from: "B", to: "C", frompid: "2", topid: "2" },];diagram.model.linkFromPortIdProperty = "frompid"; // 连接点对应名称diagram.model.linkToPortIdProperty = "topid";diagram.nodeTemplateMap.add( "Start", // nodeDataArray 中的 category $( go.Node, "Auto", { width: 260, height: 80 }, $(go.Shape, "Rectangle", { fill: "white", stroke: "white", strokeWidth: 1 }), $( go.Panel, "Vertical", { padding: new go.Margin(5, 5, 5, 2) }, $( go.TextBlock, "节点设置左右连接点", // 1. 节点文本也可以直接写在这 { font: "18px Sans-Serif", stroke: "#444", textAlign: "center" }, new go.Binding("text") // 2.文本也可以通过绑定 nodeDataArray 中的 text, 或者其他任意字段 ) ), $( go.Panel, "Vertical", { alignment: go.Spot.Left, alignmentFocus: new go.Spot(0, 0.5, 8, 0), }, makePort(2, 3).inSpotList // 需要返回一个数组,表示 2个 入边连接点 ), $( go.Panel, "Vertical", { alignment: go.Spot.Right, alignmentFocus: new go.Spot(1, 0.5, -8, 0), }, makePort(2, 3).outSpotList // 需要返回一个数组,表示 3个 出边连接点 ) ));function makePort(inCount, outCount) { let inSpot = inCount; let outSpot = outCount; let inSpotList: any = []; let outSpotList: any = []; for (let i = 1; i <= inSpot; i++) { inSpotList.push(createPort(i, "Left")); } for (let i = 1; i <= outSpot; i++) { outSpotList.push(createPort(i, "Right")); } function createPort(portId, pos) { var port = $(go.Shape, "Rectangle", { fill: "gray", stroke: null, desiredSize: new go.Size(8, 8), portId: String(portId), // 该属性比较重要,用于给每一个连接点 命名, toMaxLinks: 3, cursor: "pointer", }); var panel = $(go.Panel, "Horizontal", { margin: new go.Margin(2, 0) }); port.fromSpot = go.Spot[pos]; port.fromLinkable = true; panel.alignment = go.Spot["Top" + pos]; panel.add(port); return panel; } return { inSpotList, outSpotList };}
方法二:该方法需要重点关注的方法itemArray
,在数据中分别定义了 leftArray
和rightArray
,用于循环显示子元素
diagram.nodeTemplate = $( go.Node, "Table", $( go.Panel, "Horizontal", { row: 1, column: 2 }, $( go.TextBlock, // 资产名称 { margin: 5, width: 240, font: "15px Verdana", stroke: "#444", } ) ), $(go.Panel, "Vertical", new go.Binding("itemArray", "leftArray"), { // 节点 左侧 入边连接点 循环显示 row: 1, column: 0, itemTemplate: $( go.Panel, { _side: "left", fromSpot: go.Spot.Left, toSpot: go.Spot.Left, cursor: "pointer", }, new go.Binding("portId", "portId"), $( go.Shape, "Rectangle", { stroke: null, strokeWidth: 1, desiredSize: new go.Size(8, 8), margin: new go.Margin(1, 5, 1, 0), }, new go.Binding("fill", "portColor") ) ), }), $(go.Panel, "Vertical", new go.Binding("itemArray", "rightArray"), { // 节点 右侧 出边连接点 循环显示 row: 1, column: 3, itemTemplate: $( go.Panel, { _side: "right", fromSpot: go.Spot.Right, toSpot: go.Spot.Right, cursor: "pointer", }, new go.Binding("portId", "portId"), $( go.Shape, "Rectangle", { stroke: null, strokeWidth: 0, desiredSize: new go.Size(8, 8), margin: new go.Margin(1, 0), }, new go.Binding("fill", "portColor") ) ), }));var nodeDataArray = [ { key: "A", rightArray: [{ portColor: "#33B12C", portId: "left0" }], rightArray: [{ portColor: "#33B12C", portId: "right0" }] }, { key: "B", rightArray: [{ portColor: "#F29941", portId: "left0" }], rightArray: [{ portColor: "#F29941", portId: "right0" }] }, { key: "C", rightArray: [{ portColor: "#11C67B", portId: "left0" }], rightArray: [{ portColor: "#11C67B", portId: "right0" }] },];var linkDataArray = [ { from: "A", to: "B", frompid: "right0", topid: "left0" }, { from: "B", to: "C", frompid: "right0", topid: "left0" },];diagram.model.linkFromPortIdProperty = "frompid"; // 连接点对应名称diagram.model.linkToPortIdProperty = "topid";
12. 设置连线模板,箭头样式,连线上添加关系文字// 连线模板diagram.linkTemplate = $( go.Link, { routing: go.Link.Orthogonal, corner: 25, relinkableFrom: true, relinkableTo: true, }, $(go.Shape, { isPanelMain: true, stroke: "transparent" }), $(go.Shape, { isPanelMain: true, stroke: "#ccc", strokeWidth: 2 }, new go.Binding("stroke", "color"), new go.Binding("strokeWidth", "strokeWidth")), $( go.Shape, { toArrow: "standard", strokeWidth: 1, fill: "#ccc" }, // 箭头 new go.Binding("stroke", "color"), new go.Binding("fill", "color") ), $( go.Panel, "Auto", // 连线上的文字 $(go.Shape, { fill: "white", stroke: "white" }), $(go.TextBlock, { stroke: "#ff6600", visible: false }, new go.Binding("text", "linkText"), new go.Binding("visible", "linkText", (a) => (a ? true : false)), new go.Binding("stroke", "isHighlighted", (sel) => (sel ? "#1E90FF" : "#ff6600")).ofObject()) ));
13. 动态追加连线 addLinkData()diagram.model.addLinkData({ from: "节点key", to: "节点key", color: "线的颜色", linkText: "连线上的文字" }); // 不指定连接点,直接连diagram.model.addLinkData({ from: "节点key", to: "节点key", color: "线的颜色", linkText: "连线上的文字", frompid: "right0", topid: "left0" }); // 设置入边和出边的连接点var nodeDataArray = [ { key: "A", rightArray: [{ portColor: "#33B12C", portId: "left0" }], rightArray: [{ portColor: "#33B12C", portId: "right0" }] }, { key: "B", rightArray: [{ portColor: "#F29941", portId: "left0" }], rightArray: [{ portColor: "#F29941", portId: "right0" }] }, { key: "C", rightArray: [{ portColor: "#11C67B", portId: "left0" }], rightArray: [{ portColor: "#11C67B", portId: "right0" }] },];var linkDataArray = [ { from: "A", to: "B", frompid: "right0", topid: "left0" }, { from: "B", to: "C", frompid: "right0", topid: "left0" },];diagram.model.linkFromPortIdProperty = "frompid"; // 连接点对应名称diagram.model.linkToPortIdProperty = "topid";
14. 点击节点使其相关联节点与连线及文字高亮显示function nodeclick(e, node) { var diagram = node.diagram; diagram.clearHighlighteds(); node.findNodesConnected().each(function (l) { l.isHighlighted = true; }); node.linksConnected.each(function (n) { n.isHighlighted = true; });}
15. 点击画布清空当前高亮状态元素diagram.click = function (e) { e.diagram.commit(function (d) { d.clearHighlighteds(); }, "no highlighteds");};
16. 删除连线的方法删除一条:diagram.model.removeLinkData(linkData);
,这个方法,我试了几个都没有成功,可能是linkData
获取的不对,又由于我是要全部删除,因此使用了 diagram.model.removeLinkDataCollection
方法,进行批量删除,但是在实际过程中发现,调用这个方法只能删除一半,(也不知道是什么原因,如果有耐心的有缘人,读到此处并解决了问题,欢迎留言帮我解惑),但是呢办法总比困难多,写一个 while 循环就可以搞定了
while (diagram.model.linkDataArray.length) { diagram.model.removeLinkDataCollection(diagram.model.linkDataArray);}
17. 动态根据需求 展开和收起某一个或全部的分组展开或收起某一个分组:
// groupKey 在 nodeDataArray节点列表中的, 分组节点的 Key值diagram.findNodeForKey(groupKey).isSubGraphExpanded = true; // 展开diagram.findNodeForKey(groupKey).isSubGraphExpanded = false; // 收起
展开或收起全部分组:这个功能我用在了,在每次展开某种特定条件的分组时,先关闭之前所有的分组,在进行新一轮的展开操作
function graphExpandCollaps() { const { nodeDataArray } = diagram.model; nodeDataArray.forEach((v) => { if (v.isGroup) { diagram.findNodeForKey(v.groupName).isSubGraphExpanded = false; // 分组全部收起 } });}
18. 关闭画布重新渲染时的动画diagram.animationManager.stopAnimation(); // 取消动画
19. 画布无限拖拽功能画布固定宽度和高度之后,对拖拽功能很不友好,当内容比较多时,容易拖拽不动,再则在使用 mac 浏览器时,会触发浏览器的前进后退事件。设置画布可以无限滚动后,解决
diagram.scrollMode = go.Diagram.InfiniteScroll;
20. 图禁止复制,禁止删除,开启鼠标滚轮缩放,toolTip 触发 hoverDelay 初始定位diagram = $(go.Diagram, "myDiagramDiv", { "toolManager.hoverDelay": 200, // toolTip触发 "toolManager.mouseWheelBehavior": go.ToolManager.WheelZoom, // 开启鼠标滚轮缩放 // initialContentAlignment: go.Spot.Center, // 居中:第一次 不好使 // contentAlignment: go.Spot.Center, // 可以居中,但是居中之后不可以拖动 initialPosition: new go.Point(-150, -300), // 初始坐标 allowCopy: false, // 禁止复制 allowDelete: false, // 禁止删除 scale: 1, // 缩放会恢复默认值 diagram.scale = 1 minScale: 0.4, // 缩小 diagram.scale -= 0.1 maxScale: 1.4, // 放大 diagram.scale += 0.1});
21. 消除水印在其他文章中看到要删除一个函数的方法,但是由于 gojs 是压缩过的,每个版本的变量都不一样,因此查到另外一个方式,亲测有效,全文搜索 String.fromCharCode(a.charCodeAt(g)^b[(b[c]+b[d])%256])
,大家再搜索时,需要注意一个空格,不然可能会导致搜索不到结果。
在 for 循环的后面 加上一个 判断, 需要跟画布上水印的文字进行比对一下,我觉得其实写一个条件语句,应该就可以命中了。
if (f.indexOf("GoJS 2.2 evaluation") > -1 || f.indexOf("(c) 1998-2022 Northwoods Software") > -1 || f.indexOf("Not for distribution or production use") > -1 || f.indexOf("gojs.net") > -1) { return "";} else { return f;}
更多分享 详见下一篇博文gojs 超多超实用经验分享(二)
标签:
可视化—gojs 超多超实用经验分享(一)
2023-05-04
要闻速递:雁塔区高新路小学在省市区级信息素养提升活动中荣获佳绩
2023-05-04
去中国生活的作文(精选5篇)|天天快资讯
2023-05-04
税务师免试申请条件_职称计算机免试条件
2023-05-04
华为重申保持创新:1年投入1615亿研发费
2023-05-04
武汉人口系列13:2010-2021年21-35岁青年户籍人口数量和增量对比 每日热门
2023-05-04
亚太地区排名第一!IMF展望报告:中国将为亚洲经济活力提供主要动力|每日动态
2023-05-04
“五一”假期,中国交通显实力
2023-05-04
黑龙江省七台河市市场监管局新兴分局开展燃气具和电动车专项检查 焦点
2023-05-04
环球今头条!正方案(关于正方案介绍)
2023-05-04
要闻速递:雁塔区高新路小学在省市区级信息素养提升活动中荣获佳绩
去中国生活的作文(精选5篇)|天天快资讯
税务师免试申请条件_职称计算机免试条件
华为重申保持创新:1年投入1615亿研发费
武汉人口系列13:2010-2021年21-35岁青年户籍人口数量和增量对比 每日热门
亚太地区排名第一!IMF展望报告:中国将为亚洲经济活力提供主要动力|每日动态
“五一”假期,中国交通显实力
黑龙江省七台河市市场监管局新兴分局开展燃气具和电动车专项检查 焦点
环球今头条!正方案(关于正方案介绍)
思瑞浦(688536):日K线呈现-“乌云盖顶”形态 后市看空(05-04)
恶心梅西,大巴黎也真够恶心的
快资讯:国内首个“海上风电+海洋牧场+海水制氢”融合项目风机首吊成功!
当前通讯!韩日首脑会谈前夕先借吉祥物升温:虎宗与熊本熊被任命为亲善大使
当前信息:江南奕帆:融资净偿还52.17万元,融资余额3077.4万元(04-28)
快资讯丨加快农业强省建设“设计河南”是关键一招
“五一”假期,纪委连续突击抓现行,披露重要信号
巴西警方搜查前总统博索纳罗住所
即时看!2023上海车展:捷尼赛思G90 财阀大佬座驾灵不灵?
人生路不熟成五一档票房冠军,究竟是怎么一回事? 环球热资讯
天天热点!女王的公主命漫画在线阅读_女王的公主gl小说
SSR分子标记的原理
世界要闻:云南保山5.2级地震致3人轻伤 房屋受损
世界今日讯!小脑共济失调怎么治疗_共济失调的症状有哪些
上海“五一”期间线上线下消费589.4亿元 每日消息
世界视讯!法国球手安托万罗兹纳赢得了他的第二个欧巡赛冠军
焦点简讯:如何拥有极致性能体验?以一台手机为例,大致需要掌握2个方面
环球关注:中国育儿成本全球第二高?报告称抚养一个孩子到大学毕业需要62万
电能实业(00006.HK)5月3日收盘涨0.33%,主力资金净流入144.08万港元
花千骨分集剧情_大家一起来看看吧-动态
- 快乐小主妇的99堂生活课
- 港股异动 | 蔚来-SW(09866)跌超5% 4月交付新车6658辆 环比下降35.8%-世界资讯
- 今日更新香附化瘀贴是什么功效 香的好处是什么附化瘀贴
- 全球快看点丨美向边境派遣1500名士兵,移民限制措施将撤销恐迎移民潮
- 石景山古城街道五一开展文明游园主题宣传活动 天天微速讯
- 谎称自己有特殊渠道买苹果手机!女子为维持面子,诈骗1300万!
- 世界信息:美联储5月加息25个基点的概率为85.4%
- 今日最新!《一拳超人》新组织出现,或揭开龙卷身世,龙级怪人竟被人控制
- 安徽省发布山洪灾害气象预警_天天看热讯
- 世界视点!顺优吸油茶喝瘦了吗_顺优吸油茶
- 美国3月工厂订单月率为0.9% 预期1.1%
- scsi设备是什么_scsi设备_热点聚焦
- 快报:东北的连桥是什么意思 东北人的连桥是啥意思
- 天天新动态:“呵护美丽滨城 畅享绿色健康”学校企业志愿者们联合开展“爱国卫生月”活动
- 继承者们国语版普通话第一集 继承者们国语版普通话|世界独家
- 春日发光 你我充电|商会组织秘书处成员进行业务能力提升的分享会
- 孔雀为躲游客拔毛被滑车碾死 园方:被很多游客拔毛受惊 看点
- 【世界报资讯】女子携家人翻栅栏插队遭集体抗议 这样也行?
- 大语言模型中的涌现现象是不是伪科学?
- 今日播报!假面骑士Geats:景和剧场版觉醒恶魔人格,难道剧中要黑化升级吗?
- 孔雀为躲游客拔毛被滑车碾死详细内容
- 每日视点!年轻夫妇偶然抢购三居室的家
- 袋装蛤蜊肉怎么做好吃 蛤蜊肉怎么做好吃
- 听,劳动的旋律
- 8的英文_8 d
- volkswagen什么意思(volkswagen怎么读)
- 三花智控(002050.SZ):公司阀、泵、换热器以及相关组件类产品都可以使用在液冷热管理领域
- Woj:沃恩重组篮网教练组 与科科什科夫&斯普利特分道扬镳
- 德国外交部:被驱逐的德国外交官已离开俄罗斯
- 世界实时:正向领导力
- 【环球报资讯】《CSGO2》游戏发售时间介绍[多图]
- 苹果腐烂病病斑_关于苹果腐烂病病斑的简介_全球速递
- 天天最新:盗贼换武器宏接背刺宏_盗贼换武器宏
- “回家的感觉真好” 为了这件事,特朗普突访苏格兰 世界今头条
- “五一”假期第三天全国道路交通总体平稳有序
- 全球即时:红色旅游景区成为出行首选 辽宁丹东抗美援朝纪念馆迎来大批游客
- 五一假期前两日,宝安重点景区接待游客全线飙涨!
- 环球热文:突发!国内掌机圈又有新品牌入场啦!- AMD6800U / 7840U / RK3588《国产掌机周报》
- “港车北上”6月1日起接受申请,李家超感谢中央及广东省政府支持
- 世界即时看!职工自编自导自演 “五一”主题晚会精彩纷呈
- 【天天播资讯】2023第二十届中国西藏登山大会开幕
- 《火山的女儿》情感结局怎么触发?情感结局触发方法|环球快讯
- 影之诗卡牌DIY工具-安卓APP版
- 全国机电安装工程在宁举办观摩活动_头条
- 当前热文:仿盛大传奇2.0z 100仿盛大传奇
- 世界今热点:人民网评:“五个一百”,记录每一个正能量瞬间
- 世界新消息丨一梨三“吃”的奥秘 ——石家庄晋州市发展乡村产业壮大县域经济的新探索
- 做水果沙拉都需要什么水果_做水果沙拉都需要什么材料|今日热文
- 中国最不讲“人情”的城市:聚餐默认AA制,结婚从不主动讨红包 当前独家
- 天天热议:“史上最挤”五一档,有马丽、白百何、王一博…却没带火电影院?