效果如下图所示:

一、文件目录结构:

二、绘制png的鱼头、鱼尾图片

fish_head.png:      fish_tail.png:     

三、下载js文件

jquery、jtopo请到官网下载。

四、编写鱼骨图核心文件:MakFishBone.js

let MakFishBone = (function (window) {let MakFishBone = function (canvas, options) {return new MakFishBone.fn.init(canvas, options)}MakFishBone.fn = MakFishBone.prototype = {constructor: MakFishBone,init: function (canvas, options) {this.canvas = canvaslet dpr = window.devicePixelRatio || 1canvas.width = parseInt(canvas.style.width) * dprcanvas.height = parseInt(canvas.style.height) * dprthis.ctx = canvas.getContext('2d')let defaultConfig = {/*json数据*/data: null,/*是否可以拖动,默认是true */dragable: true,/*是否显示工具条 */showToolbar: true,/* debug模式 */debug: true,//交错显示stagger: true,//背景sceneBackgroundImage: null,//单击节段回调clickNodeCallback: null}this.cfg = $.extend(defaultConfig, options)let stage = new JTopo.Stage(canvas)this.stage = stage//显示工具栏showJTopoToobar(stage)this.scene = new JTopo.Scene(stage)},getFishBoneNode: function (position, text) {let jNode = new JTopo.Node(text || '')jNode.shadow = false// jNode.showSelected = false;jNode.dragable = falseif (position) {jNode.setLocation(position.x, position.y)}jNode.setSize(0, 0)if (this.cfg.debug) {jNode.setSize(1, 1)}return jNode},getNodeTextRect: function (node, text) {this.ctx.font = node.fontlet textArray = text.split('\n')let maxLength = 0maxText = textArray[0]for (let i = 0; i < textArray.length; i++) {let rowwidth = this.ctx.measureText(textArray[i]).widthif (rowwidth > maxLength) {maxLength = rowwidthmaxText = textArray[i]}}let lineHeight = this.ctx.measureText('田').widthreturn {width: maxLength,height: lineHeight * textArray.length,lineHeight: lineHeight}},//格式化文本节点值getFormatText: function (text) {//每行文本字符数let textNumberRow = 11let tmptext = ''if (text) {for (let i = 0; i < text.length; i++) {if (i > 0 && i % textNumberRow == 0) {tmptext += '\n'}tmptext += text[i]}}return tmptext},getNewTextNode: function (PntA, text, PntZ, depth) {let tmptextif (depth == 1) {tmptext = text} else {tmptext = this.getFormatText(text)}let nodeText = new JTopo.TextNode(tmptext || '')nodeText.shadow = false//nodeText.showSelected = false;nodeText.dragable = falsenodeText.fontColor = '40,40,40'nodeText.font = '12px 微软雅黑'nodeText.paint = function (a) {a.beginPath()a.font = this.fonta.strokeStyle = 'rgba(' + this.fontColor + ', ' + this.alpha + ')'a.fillStyle = 'rgba(' + this.fontColor + ', ' + this.alpha + ')'let textArray = this.text.split('\n')let maxLength = 0maxText = textArray[0]for (let i = 0; i < textArray.length; i++) {let rowwidth = a.measureText(textArray[i]).widthif (rowwidth > maxLength) {maxLength = rowwidthmaxText = textArray[i]}}this.width = maxLengthlet lineHeight = a.measureText('田').widththis.height = lineHeight * textArray.lengthlet x = -this.width / 2let y = -this.height / 2 + lineHeightfor (let j = 0; j < textArray.length; j++) {a.fillText(textArray[j], x, y)y += lineHeight}a.closePath()}let size = this.getNodeTextRect(nodeText, tmptext)nodeText.textSize = sizelet tx = 0, ty = 0//设置中骨文本节点坐标if (depth == 1) {tx = PntZ.x + 15, ty = PntZ.y - 15} else {tx = PntA.x, ty = PntA.y}if (PntA.y == PntZ.y) {//横线tx -= size.widthty -= size.lineHeight / 2} else {//斜线tx -= size.width / 2ty -= size.height}nodeText.setLocation(tx, ty)this.scene.add(nodeText)let nodeA = this.getFishBoneNode(PntA)let nodeZ = this.getFishBoneNode(PntZ)if (depth == 0) {//获取鱼骨图,设置根节点x,y坐标let img = new Image()img.src = '/static/image/fish_head.png'//图片加载完成之后执行img.onload = function () {nodeA.y = nodeA.y - img.height / 2nodeZ.y = nodeZ.y - img.height / 2nodeA.setImage('/static/image/fish_tail.png', true)nodeZ.setImage('/static/image/fish_head.png', true)}}this.scene.add(nodeA)this.scene.add(nodeZ)nodeZ.assPnt = nodeAnodeA.assPnt = nodeZlet link = new JTopo.Link(nodeA, nodeZ, '')link.bundleOffset = 60 // 折线拐角处的长度link.bundleGap = 20 // 线条之间的间隔link.textOffsetY = 3 // 文本偏移量(向下3个像素)if (depth == 0) {link.lineWidth = 6 // 线宽link.strokeColor = '8,147,117'} else {link.lineWidth = 2 // 线宽link.strokeColor = '100,149,237'}this.scene.add(link)return {nodeA: nodeA, nodeZ: nodeZ, link: link, text: nodeText}},resetX: function (node, x) {node.nodes.nodeA.x += xnode.nodes.nodeZ.x += xnode.nodes.text.x += xif (node.children) {for (let i = 0; i < node.children.length; i++) {this.resetX(node.children[i], x)}}},resetY: function (node, x, y) {node.nodes.nodeA.x += xnode.nodes.nodeA.y += ynode.nodes.nodeZ.x += xnode.nodes.nodeZ.y += ynode.nodes.text.x += xnode.nodes.text.y += yif (node.children) {for (let i = 0; i < node.children.length; i++) {this.resetY(node.children[i], x, y)}}},//水平翻转HorizontalFlip: function (node) {node.nodes.nodeA.x = -node.nodes.nodeA.xnode.nodes.nodeZ.x = -node.nodes.nodeZ.xnode.nodes.text.x = node.nodes.nodeA.xif (node.children) {for (let i = 0; i < node.children.length; i++) {this.HorizontalFlip(node.children[i])}}},//垂直翻转VerticalFlip: function (node) {let sizeif (node.name) {let tmptext = this.getFormatText(node.name)size = this.getNodeTextRect(node, tmptext)}node.nodes.nodeA.y = -node.nodes.nodeA.ynode.nodes.nodeZ.y = -node.nodes.nodeZ.ynode.nodes.text.y = -node.nodes.text.y + (size ? -size.height : 0)if (node.children) {for (let i = 0; i < node.children.length; i++) {this.VerticalFlip(node.children[i])}}},//根据节点level值画节点drawLevel: function (depth) {if (depth < 0) {return}let clevels = this.flatData.filter(x => x.level == depth)//depth最小为0,偶数为横线,奇数为斜线let isHorizontal = (depth % 2) === 0for (let i = 0; i < clevels.length; i++) {let arow = clevels[i]let lineLength = 100//筛选子节点let chilnodes = []let tnodes = []for (let k = 0; k < this.AllTmpNode.length; k++) {if (this.AllTmpNode[k].path.indexOf(arow.path + '_') === 0) {chilnodes.push(this.AllTmpNode[k])} else {tnodes.push(this.AllTmpNode[k])}}this.AllTmpNode = tnodes//固定间隔let fixedInterval = 40if (isHorizontal) {//横线//先计算子节点宽度(分斜线左边部分,和斜线右边部分let width_left = []let width_right = []let widthtotal = 0for (let j = 0; j < chilnodes.length; j++) {let subnode = chilnodes[j]if (subnode.children) {if (subnode.children.length === 0) {//没有子节点(固定间隔)width_left.push(fixedInterval), width_right.push(fixedInterval)} else if (subnode.children.length === 1) {//1个子节点(半幅width_left.push(Math.abs(subnode.children[0].nodes.nodeA.x))width_right.push(0)} else {//多个子节点let xleft = subnode.children[0].nodes.nodeA.xlet xright = subnode.children[0].nodes.nodeA.xfor (let k = 1; k < subnode.children.length; k++) {let growNode = subnode.children[k].nodes.nodeAif (growNode.x < xleft) {xleft = growNode.x}if (growNode.x > xright) {xright = growNode.x}}width_left.push(Math.abs(xleft)), width_right.push(Math.abs(xright))}widthtotal += width_left[j] + width_right[j]}}lineLength += widthtotal//计算斜线的基础位置(0,0)作为目标点let PntA = {x: -lineLength, y: 0}let PntZ = {x: 0, y: 0}arow.lineLength = lineLength//返回4个节点arow.nodes = this.getNewTextNode(PntA, arow.name, PntZ, depth)this.AllTmpNode.push(arow)//把它的子节点全部放到当前节点上let newX = PntA.xfor (let j = 0; j < chilnodes.length; j++) {let subnode = chilnodes[j]newX += width_left[j]this.resetX(subnode, newX)newX += width_right[j]}if (i % 2 != 0) {//右边(水平翻转整颗树)this.HorizontalFlip(arow)}} else {//斜线//先计算子节点的高度(子节点的高度,上半部分和下半部分分开计算let height_up = []let height_down = []let heighttotal = 0for (let j = 0; j < chilnodes.length; j++) {let subnode = chilnodes[j]if (subnode.children) {if (subnode.children.length === 0) {//没有子节点(固定间隔)height_up.push(fixedInterval), height_down.push(fixedInterval)} else if (subnode.children.length === 1) {//1个子节点(半幅height_up.push(subnode.children[0].lineLength)height_down.push(0)} else {//多个子节点let yTop = subnode.children[0].nodes.nodeA.ylet yBottom = subnode.children[0].nodes.nodeA.yfor (let k = 1; k < subnode.children.length; k++) {let growNode = subnode.children[k].nodes.nodeAif (growNode.y < yTop) {yTop = growNode.y}if (growNode.y > yBottom) {yBottom = growNode.y}}height_up.push(Math.abs(yTop)), height_down.push(Math.abs(yBottom))}heighttotal += height_up[j] + height_down[j]}}lineLength += heighttotal//计算斜线的基础位置(0,0)作为目标点let PntA = {x: -lineLength / 2, y: -lineLength}let PntZ = {x: 0, y: 0}arow.lineLength = lineLength//返回4个节点arow.nodes = this.getNewTextNode(PntA, arow.name, PntZ, depth)this.AllTmpNode.push(arow)//把它的子节点全部放到当前节点上let newX = PntA.xlet newY = PntA.yfor (let j = 0; j < chilnodes.length; j++) {newY += height_up[j]newX += height_up[j] / 2this.resetY(chilnodes[j], newX, newY)newY += height_down[j]newX += height_down[j] / 2}if (i % 2 != 0) {//右上斜(垂直翻转整颗树)this.VerticalFlip(arow)}}}//子元素花完了,画根元素this.drawLevel(depth - 1)},start: function () {let flatData = []let maxdepth = 0function dofloatdata (d, path, depth) {d.level = depthd.path = pathflatData.push(d)if (depth > maxdepth) {maxdepth = depth}if (d.children) {for (let i = 0; i < d.children.length; i++) {dofloatdata(d.children[i], path + '_' + i, depth + 1)}}}dofloatdata(this.cfg.data, '0', 0)this.flatData = flatDataif (this.cfg.debug) {console.log('maxdepth:' + maxdepth)console.log(flatData)}this.AllTmpNode = []this.drawLevel(maxdepth)this.movePntS((this.cfg.data.lineLength + this.canvas.width) / 2, this.canvas.height / 2)//居中显示this.stage.centerAndZoom()},movePntS: function (x, y) {for (let i = 0; i < this.scene.childs.length; i++) {let a = this.scene.childs[i]a.x += xa.y += y}},}MakFishBone.fn.init.prototype = MakFishBone.fnreturn MakFishBone
})(window)

五、jtopo工具栏toolbar.js

// 页面工具栏
function showJTopoToobar(stage){var toobarDiv = $('<div class="jtopo_toolbar">').html(''+'<input type="radio" name="modeRadio" value="normal" checked id="r1"/>'+'<label for="r1"> 默认</label>'+'&nbsp;<input type="radio" name="modeRadio" value="select" id="r2"/><label for="r2"> 框选</label>'+'&nbsp;<input type="radio" name="modeRadio" value="edit" id="r4"/><label for="r4"> 加线</label>'+'&nbsp;&nbsp;<input type="button" id="centerButton" value="居中显示"/>'+'<input type="button" id="fullScreenButton" value="全屏显示"/>'+'<input type="button" id="zoomOutButton" value=" 放 大 " />'+'<input type="button" id="zoomInButton" value=" 缩 小 " />'+'&nbsp;&nbsp;<input type="checkbox" id="zoomCheckbox"/><label for="zoomCheckbox">鼠标缩放</label>'+'&nbsp;&nbsp;<input type="text" id="findText" style="width: 100px;" value="" onkeydown="enterPressHandler(event)">'+ '<input type="button" id="findButton" value=" 查 询 ">'+'&nbsp;&nbsp;<input type="button" id="exportButton" value="导出PNG">');$('#content').prepend(toobarDiv);// 工具栏按钮处理$("input[name='modeRadio']").click(function(){stage.mode = $("input[name='modeRadio']:checked").val();});$('#centerButton').click(function(){stage.centerAndZoom(); //缩放并居中显示});$('#zoomOutButton').click(function(){stage.zoomOut();});$('#zoomInButton').click(function(){stage.zoomIn();});$('#cloneButton').click(function(){stage.saveImageInfo();});$('#exportButton').click(function() {stage.saveImageInfo();});$('#printButton').click(function() {stage.saveImageInfo();});$('#zoomCheckbox').click(function(){if($('#zoomCheckbox').is(':checked')){stage.wheelZoom = 1.2; // 设置鼠标缩放比例}else{stage.wheelZoom = null; // 取消鼠标缩放比例}});$('#fullScreenButton').click(function(){runPrefixMethod(stage.canvas, "RequestFullScreen")});window.enterPressHandler = function (event){if(event.keyCode == 13 || event.which == 13){$('#findButton').click();}};// 查询$('#findButton').click(function(){var text = $('#findText').val().trim();//var nodes = stage.find('node[text="'+text+'"]');var scene = stage.childs[0];var nodes = scene.childs.filter(function(e){return e instanceof JTopo.Node;});nodes = nodes.filter(function(e){if(e.text == null) return false;return e.text.indexOf(text) != -1;});if(nodes.length > 0){var node = nodes[0];node.selected = true;var location = node.getCenterLocation();// 查询到的节点居中显示stage.setCenter(location.x, location.y);function nodeFlash(node, n){if(n == 0) {node.selected = false;return;};node.selected = !node.selected;setTimeout(function(){nodeFlash(node, n-1);}, 300);}// 闪烁几下nodeFlash(node, 6);}});
}var runPrefixMethod = function(element, method) {var usablePrefixMethod;["webkit", "moz", "ms", "o", ""].forEach(function(prefix) {if (usablePrefixMethod) return;if (prefix === "") {// 无前缀,方法首字母小写method = method.slice(0,1).toLowerCase() + method.slice(1);}var typePrefixMethod = typeof element[prefix + method];if (typePrefixMethod + "" !== "undefined") {if (typePrefixMethod === "function") {usablePrefixMethod = element[prefix + method]();} else {usablePrefixMethod = element[prefix + method];}}}
);return usablePrefixMethod;
};

六、index.html引入js

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><script src="/static/lib/jtopo-0.4.8-min.js"></script><script src="/static/lib/MakFishBone.js"></script><script src="/static/lib/jquery-3.3.1.js"></script><script src="/static/lib/toolbar.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html><style>body {margin: 0px;padding: 0px}
</style>

七、组件封装:src\components\Jtopo.vue

<template><div id="content" ref="content" style="width:100%"><canvas id="canvas" ref="canvas" :style="{width:canvasW, height:canvasH}"></canvas></div>
</template><script>export default {name: 'Jtopo',data () {return {canvasW: '0px',canvasH: '0px'}},props: {fishboneData: {type: Object,default () {return {name: '',children: null}}}},mounted () {//设置canvas宽高let contentW = this.$refs.content.offsetWidththis.canvasW = contentW + 'px'let bodyH = document.body.offsetHeight - 40this.canvasH = bodyH + 'px'},created () {setTimeout(() => {this.initTopo()}, 1000)},watch: {fishboneData (newVal, oldVal) {if (newVal.children && newVal.children.length > 0) {this.initTopo()}}},methods: {initTopo () {let canvas = this.$refs.canvasif (this.fishboneData) {let mfb = new MakFishBone(canvas, {data: this.fishboneData})mfb.start()}}}}
</script>
<style scoped>>>> .jtopo_toolbar {height: 35px;line-height: 35px;background-color: rgb(216, 231, 242);}
</style>

八、测试页面

<template><div><Jtopo :fishboneData="fishboneData"/></div>
</template><script>import Jtopo from '../../components/Jtopo'export default {data () {return {fishboneData: null}},name: 'Fishbone',components: {Jtopo},created () {this.fishboneData = {'children': [{'children': [{'children': [{'children': [], 'name': '睡眠中迷糊', fontColor: '', lineColor: '', link: ''},{'children': [], 'name': '意识不清', fontColor: '', lineColor: '', link: ''},{'children': [], 'name': '精神异常', fontColor: '', lineColor: '', link: ''},], 'name': '精神因素', fontColor: '', lineColor: '', link: 'http://www.baidu.com'},{'children': [{'children': [], 'name': '舒适度改变', fontColor: '', lineColor: '', link: ''},{'children': [], 'name': '其它', fontColor: '', lineColor: '', link: ''}], 'name': '依从性差', fontColor: '', lineColor: '', link: ''},{'children': [{'children': [], 'name': '自身理解', fontColor: '', lineColor: '', link: ''},{'children': [], 'name': '护士指导', fontColor: '', lineColor: '', link: ''}], 'name': '知识缺乏', fontColor: '', lineColor: '', link: ''},], 'name': '病人', fontColor: '', lineColor: '', link: ''},{'children': [{'children': [{'children': [], 'name': '缺乏安全意识', fontColor: '', lineColor: '', link: ''},{'children': [], 'name': '自身知识不足', fontColor: '', lineColor: '', link: ''}], 'name': '安全告知不到位', fontColor: '', lineColor: '', link: ''},{'children': [{'children': [], 'name': '工作责任心不强', fontColor: '', lineColor: '', link: ''},{'children': [], 'name': '分级护理落实差', fontColor: '', lineColor: '', link: ''}], 'name': '未及时发现安全隐患', fontColor: '', lineColor: '', link: ''},{'children': [{'children': [], 'name': '医生固定', fontColor: '', lineColor: '', link: ''}], 'name': '违反管道护理常规', fontColor: '', lineColor: '', link: ''},{'children': [{'children': [], 'name': '分级护理交接班制度执行差', fontColor: '', lineColor: '', link: ''},{'children': [], 'name': '医护沟通不足', fontColor: '', lineColor: '', link: ''},{'children': [], 'name': '特殊病人、重点环节风险评估不足', fontColor: '', lineColor: '', link: ''}], 'name': '约束措施、无力、不当', fontColor: '', lineColor: '', link: ''}], 'name': '医生护士', fontColor: '', lineColor: '', link: ''},{'children': [{'children': [], 'name': '粗心大意', fontColor: '', lineColor: '', link: ''},{'children': [{'children': [], 'name': '对保护性约束', fontColor: '', lineColor: '', link: ''},{'children': [], 'name': '对自行拔管可能带来的危害不清', fontColor: '', lineColor: '', link: ''}], 'name': '家属随意终止约束', fontColor: '', lineColor: '', link: ''}], 'name': '家属', fontColor: '', lineColor: '', link: ''},{'children': [{'children': [{'children': [], 'name': '未沟通', fontColor: '', lineColor: '', link: ''}], 'name': '质量问题', fontColor: '', lineColor: '', link: ''},{'children': [], 'name': '培训不足', fontColor: '', lineColor: '', link: ''},{'children': [{'children': [], 'name': '护士长', fontColor: '', lineColor: '', link: ''}], 'name': '监管不足', fontColor: '', lineColor: '', link: ''},{'children': [], 'name': '护士人力不足', fontColor: '', lineColor: '', link: ''}], 'id': '1004', 'fid': '1', 'name': '管理', fontColor: '', lineColor: '', link: ''}], 'name': '管道脱落', fontColor: '', lineColor: '', link: ''}},}
</script>

vue、jtopo绘制鱼骨图相关推荐

  1. vue+gojs 绘制鱼骨图(因果图)

    最近查找js相关的鱼骨图组件,找了半天都没有合适的,自己参考gojs官网demo简单的实现了下,效果如下. 废话少说,直接上代码. 引入gojs npm install gojs --save 整合到 ...

  2. Vue + gojs 绘制鱼骨图

    效果图: 引入gojs npm install gojs --save 在git地址拉下代码 ,地图组件地址是 src\components\fishboneDiagram git地址 开源不易 多多 ...

  3. 利用思维导图软件绘制鱼骨图怎样做

    思维导图的类型有哪些? 圆圈图 主要用于把一个主题展开来,联想或描述细节.小圈圈是主题,而外面的大圈圈里放的是和这个主题有关的细节或特征 气泡图 由很多泡泡组成,中间一个主题泡泡描述核心主题,周围的属 ...

  4. 绘制鱼骨图,卡壳了,找到了别人的文章,先好好学习理论知识。

    鱼骨图的三种类型 A.整理问题型鱼骨图(各要素与特性值间不存在原因关系,而是结构构成关系) B.原因型鱼骨图(鱼头在右,特性值通常以"为什么--"来写) C.对策型鱼骨图(鱼头在左 ...

  5. XMind是怎么绘制鱼骨图

    鱼骨图因常常被用于问题的分析以及解决方法,所以又被称为因果图.鱼骨图一直是XMind思维导图软件的拿手好戏之一,一直被模仿从未被超越.让我们一起通过本篇文章,探讨XMind鱼骨图的秘密吧. 当你打开X ...

  6. 如何用XMind绘制鱼骨图

    鱼骨图因常常被用于问题的分析以及解决方法,所以又被称为因果图.鱼骨图一直是XMind思维导图软件的拿手好戏之一,一直被模仿从未被超越.让我们一起通过本篇文章,探讨XMind鱼骨图的秘密吧. 当你打开X ...

  7. VUE+Cesium绘制迁徙图结合echarts实现

    一.编写EchartsLayer类实现注入到window对象,实现类如下: import * as Cesium from 'cesium/Cesium' import * as echarts fr ...

  8. vue + canvas绘制背景图、矩形

    最近有需求做图片人脸识别,在系统上传图片后,后台返回坐标将识别到的人脸画上矩形. 效果图如下: 实现过程: 1.利用绘制canvas实例 //html <canvas id='imgCanvas ...

  9. linux画鱼骨图插件,鱼骨图绘制方法:超实用的鱼骨图制作软件

    鱼骨图又叫石川图或因果图,它可以帮助你分析一个问题的所有可能原因.说到绘制鱼骨图的工具,有人用办公常用的Word,也有人用Visio.本文将为您推荐一款无需任何绘图功底,也可以轻松上手的鱼骨图绘制软件 ...

最新文章

  1. 广东省哈工大(深圳)赛区赛事活动安排
  2. InnoDB和MyISAM引擎的效率比较
  3. 您没有权限来打开应用程序_苹果建议:除非应用程序无响应,否则不要滑动强制退出...
  4. springboot日志自定义路径无效及出现org.springframework.boot.context.properties.bind.BindException错误
  5. Linux下装完mysql后默认密码是多少
  6. 使用Flowable.generate()生成可感知背压的流– RxJava常见问题解答
  7. 支付宝手机h5网页支付不再提供「继续浏览器付款」按钮了吗
  8. php5.5.* mysqlnd驱动安装
  9. Python返回多个值
  10. 特征级融合_多知识图谱的融合算法探索
  11. Tensorflow:dataset数据读取
  12. eclipseini设置使用的jdk_设置 Maven 对应的JDK 版本
  13. github 如何添加项目代码
  14. HTML页面模板代码
  15. 南京师范大学地理科学学院 汪永进教授等在Nature杂志上发表论文
  16. Mybatis面向接口编程
  17. [翻译]IAdaptable是什么?
  18. ZJNU 2314-Sleepy Cow Herding
  19. 0402/0603/0805/1206封装尺寸
  20. Textstudio 应用程序无法正常启动0xc000007b

热门文章

  1. 人工智能学习笔记 感知器算法的设计实现 感知器准则实现多类分类
  2. oracle触发器判断空值,oracle触发器加条件判断、dblink
  3. 天龙客户端大致的结构划分和功能描述
  4. 物联网云平台系统源码
  5. 一个财主的故事-----从银行复利认识无理数e
  6. html模板下载之“门户网站html模板页面下载”——html模板下载合集(持续更新中)
  7. 如何在matlab中建立水箱模型_在MATLAB中实现水箱液位控制系统的设计
  8. 免费轻量级网页播放器f4player, flv, f4v, mp4, stream, live stream, subscribed CDN
  9. 天津理工计算机学院调剂,2019年硕士研究生调剂通知
  10. 深信服自动上网认证(go源码)