web实现html页面思维导图效果

xiaoxiao2021-02-27  157

index.html内容:

<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>Web思维导图</title> <link rel="stylesheet" href="css/prism.css"> <link rel="stylesheet" href="css/common.css"> </head> <body> <h3> Web思维导图,梳理Hacker知识点为例: </h3> <div id="drawing" class="drawing"> </div> <div class="modal" id="modal"> <div class="modal-bg"> <div class="modal-content"> <div class="modal-cell"> <pre class="modal-code"> <code class="language-html"></code> </pre> </div> </div> <div class="modal-close"> </div> </div> <div class="modal-mask"></div> </div> <iframe class="code_iframe" id="html_code" src="bs_introduction/code_container.html"></iframe> <script src="js/d3_flex_tree.js"></script> <script src="js/mind_mapping.js"></script> <script src="js/prism.js"></script> </body> </html>

CSS文件夹

common.css:

body{ height: 100%; margin: 0; overflow: hidden; } .clear-fix:before,.clear-fix:after{ display: table; content: ''; clear: both; } .code_iframe{ display: none; } .drawing{ visibility: hidden; font-weight: bold; border: 1px solid #ccc; animation: drawingframe; animation-duration: 1s; animation-timing-function: linear; animation-delay: 1s; -webkit-animation: drawingframe 1s linear 1s; } @keyframes drawingframe { from {opacity: 0;} to {opacity: 1;} } @-webkit-keyframes drawingframe { from {opacity: 0;} to {opacity: 1;} } .node g{ cursor: pointer; } .node circle { fill: #fff; stroke: steelblue; stroke-width: 1.5px; } .node line{ fill: #fff; stroke: steelblue; stroke-width: 1.5px; } .link { fill: none; stroke: #ccc; stroke-width: 1.5px; } .modal{ display: none; position: fixed; z-index: 9999; top: 0; bottom: 0; left: 0; right: 0; text-align: left; } .modal-mask{ position: fixed; top: 0; bottom: 0; left: 0; right: 0; background-color: black; opacity: 0.5; } .modal-bg{ position: fixed; top: 0; bottom: 0; left: 0; right: 0; z-index: 9999; } .modal-content{ display: table; position: relative; height: 100%; width: 100%; } .modal-cell{ display: table-cell; vertical-align: middle; text-align: center; } .modal-cell img{ max-height: 95%; } .modal-code{ display: none; margin: 0 auto !important; } .modal-close{ display: inline-block; position: absolute; top: 20px; right: 20px; width: 48px; height: 48px; background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABYlBMVEUAAABUbnpUbnpUbnpUbnpUbnpMZG9MZG9MZG9MZG9MZG9UbnpUbnpUbnpUbnpUbnpUbnpUbnpMZG9MZG9MZG9MZG9MZG9MZG9MZG9UbnpUbnpUbnpUbnpUbnpUbnpUbnpUbnpMZG9MZG9MZG9MZG9MZG9MZG9MZG9MZG9UbnpUbnpUbnpUbnpUbnpUbnpMZG9MZG9MZG9MZG9MZG9MZG9UbnpUbnpUbnpUbnpUbnpUbnpUbnpMZG9MZG9MZG9MZG9MZG9MZG9MZG9UbnpUbnpUbnpUbnpMZG9MZG9MZG9MZG9UbnpUbnpUbnpMZG9MZG9MZG9UbnpMZG9UbnpWcHxKYm1MZG9UbnpUbnlMZG9MZG9UbnpTbHhNZXBMZG9UbnpUbnpUbnpUbnpTbHhNZXBMZG9MZG9MZG9MZG9UbnpUbnpUbnpUbnpUbnpMZG9MZG9MZG9MZG9MZG9TbHhNZXD///9kx6K7AAAAc3RSTlMAAAAAAAAAAAAAAAAAAAsGAAAAAAYLAAAAAAAao3gGAAAAAAZ4oxoAAACr//Z3BQV39v+rAAD///V3BQAABXf1//8A///1d3f1//8A/wAAAHcFBXf1e3v1//r6/3f19XcABXv6///6ewUAJoszcwAAAAFiS0dEdahqmPsAAAAHdElNRQfeDAoPOSkJx4hxAAABVUlEQVRIx2NgGAWDDDAyMbOwYgqzsXNwcmFTz83Dy8cvIIguLCQsIiomLoGpXpJHSlpGVk5eAVVYUUlZRVVNXVwDQ4Mmr7SWto6unjyKHUJK+gaGRsZqYiYYGkz5ZLTNzC0srayRdAjZ2NrZOzgaqYo6YWhg4ZfVMXd2cXWzQrhKUcnW3cPTy8FQRYQdQwOrt5yuhYuPr6sl3FVA99h5+Pl72hsoB7Bh+lpQXs/S1dfHBe4qsHs8/f087PSVhLCFq4K8lZurC9xVUPd4erjbKilijzlBaytLuKvg7rGztRFiwAGQXBUYRMA9aK4KDgkNI+AeVFeFR0RGEXIPiquiY2LjCLoH7qr4hMSk5JTUtPQMAu6B2pGZlZ2TW1ySl19QWETQfDI0kOokUj1NarCSGnGkJg1SEx+pyZvUDERyFiW5ECC5mCG5ICO5qCS5MCa9uB8FAwkA1tqHz8dmcxMAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTYtMDktMTdUMTU6MjE6MjUrMDg6MDBOsysLAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE0LTEyLTEwVDE1OjU3OjQxKzA4OjAwNdJKeAAAAE10RVh0c29mdHdhcmUASW1hZ2VNYWdpY2sgNy4wLjEtNiBRMTYgeDg2XzY0IDIwMTYtMDktMTcgaHR0cDovL3d3dy5pbWFnZW1hZ2ljay5vcmfd2aVOAAAAGHRFWHRUaHVtYjo6RG9jdW1lbnQ6OlBhZ2VzADGn/7svAAAAGHRFWHRUaHVtYjo6SW1hZ2U6OkhlaWdodAAxMjhDfEGAAAAAF3RFWHRUaHVtYjo6SW1hZ2U6OldpZHRoADEyONCNEd0AAAAZdEVYdFRodW1iOjpNaW1ldHlwZQBpbWFnZS9wbmc/slZOAAAAF3RFWHRUaHVtYjo6TVRpbWUAMTQxODE5ODI2MfKdw1kAAAAQdEVYdFRodW1iOjpTaXplADk0NEK36UZEAAAAX3RFWHRUaHVtYjo6VVJJAGZpbGU6Ly8vaG9tZS93d3dyb290L3NpdGUvd3d3LmVhc3lpY29uLm5ldC9jZG4taW1nLmVhc3lpY29uLmNuL3NyYy8xMTgxNy8xMTgxNzU3LnBuZ7UlySMAAAAASUVORK5CYII="); } tspan{ font-size: 14px; } text{ dominant-baseline: middle; }

prism.css:

code[class*="language-"], pre[class*="language-"] { color: black; background: none; text-shadow: 0 1px white; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; text-align: left; white-space: pre; word-spacing: normal; word-break: normal; word-wrap: normal; line-height: 1.5; -moz-tab-size: 4; -o-tab-size: 4; tab-size: 4; -webkit-hyphens: none; -moz-hyphens: none; -ms-hyphens: none; hyphens: none; } pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { text-shadow: none; background: #b3d4fc; } pre[class*="language-"]::selection, pre[class*="language-"] ::selection, code[class*="language-"]::selection, code[class*="language-"] ::selection { text-shadow: none; background: #b3d4fc; } @media print { code[class*="language-"], pre[class*="language-"] { text-shadow: none; } } /* Code blocks */ pre[class*="language-"] { padding: 1em; margin: .5em 0; overflow: auto; } :not(pre) > code[class*="language-"], pre[class*="language-"] { background: #f5f2f0; } /* Inline code */ :not(pre) > code[class*="language-"] { padding: .1em; border-radius: .3em; white-space: normal; } .token.comment, .token.prolog, .token.doctype, .token.cdata { color: slategray; } .token.punctuation { color: #999; } .namespace { opacity: .7; } .token.property, .token.tag, .token.boolean, .token.number, .token.constant, .token.symbol, .token.deleted { color: #905; } .token.selector, .token.attr-name, .token.string, .token.char, .token.builtin, .token.inserted { color: #690; } .token.operator, .token.entity, .token.url, .language-css .token.string, .style .token.string { color: #a67f59; background: hsla(0, 0%, 100%, .5); } .token.atrule, .token.attr-value, .token.keyword { color: #07a; } .token.function { color: #DD4A68; } .token.regex, .token.important, .token.variable { color: #e90; } .token.important, .token.bold { font-weight: bold; } .token.italic { font-style: italic; } .token.entity { cursor: help; }

mind_mapping.js代码:

var engine, duration = 750; var margin = { top: 20, right: 120, bottom: 20, left: 120 }, width = 960 - margin.right - margin.left, height = 800 - margin.top - margin.bottom; d3.json('bs_introduction/bs_introduction.json', function (err, tree) { engine = d3.layout.tree().setNodeSizes(true); // sizing engine.nodeSize(function (t) { return [t.x_size, t.y_size]; }); // gap engine.spacing(function (a, b) { return a.parent == b.parent ? 5 : engine.rootXSize(); }); tree.x0 = height / 2; tree.y0 = 0; function collapse(d) { if (d.children) { d._children = d.children; d._children.forEach(collapse); d.children = null; } } var $iframe_doc = document.getElementById('html_code').contentWindow.document; var $modal = d3.select('#modal'), $modal_cell = $modal.select('.modal-cell'), $modal_pre = $modal.select('.modal-code'), $modal_code = $modal_pre.select('code'); $modal.on("click.mask", function(){ if(d3.event.target.className !== 'modal-cell'){ return false; } $modal.style('display', 'none'); $modal.selectAll('img').style('display', 'none'); $modal_pre.style('display', 'none') }); var client_width = document.documentElement.clientWidth, client_height = document.documentElement.clientHeight; var svg = d3.select("#drawing").append('svg').attr("width", client_width).attr("height", client_height); var svg_g = svg.append("g"); svg.call(d3.behavior.zoom().scaleExtent([0.5,3]).on("zoom", redraw)); update(tree); tree.children.forEach(collapse); update(tree, function(){ setTimeout(function(){ d3.select("#drawing").style({'visibility': "visible"}); d3.selectAll(".node").each(function(d, i){ i > 0 && (d3.select(this).select(".vertical-line").style('display', 'block')); }); },1000); }); function update(source, callback){ var nodes = d3.layout.hierarchy()(tree); var last_id = 0; var node = svg_g.selectAll(".node") .data(nodes, function (d) { return d.id || (d.id = ++last_id); }); var nodeEnter = node.enter().append("g") .attr("class", "node") .attr("transform", function (d) { var x_size = source.x_size ? source.x_size : 0; return "translate(" + source.y0 + "," + (source.x0 - x_size / 2) + ")"; }); //.on("click", click); var text_elements = nodeEnter.append("text") .attr({ id: function (d) { return d.id; }, fill: 'black', dy: "0.35em" }).each(function(d){ parseText(this, d); }); engine.nodeSize(function (d) { var ele = document.getElementById(d.id), ele_size = ele.getBBox(); return [ele_size["height"] + 30, ele_size["width"] + 14]; }); nodes = engine.nodes(tree); function node_extents(n) { return [n.x - n.x_size / 2, n.y, n.x + n.x_size / 2, n.y + n.y_size]; } var root_extents = node_extents(nodes[0]); var xmin = root_extents[0], ymin = root_extents[1], xmax = root_extents[2], ymax = root_extents[3], area_sum = (xmax - xmin) * (ymax - ymin), x_size_min = nodes[0].x_size, y_size_min = nodes[0].y_size; nodes.slice(1).forEach(function (n) { var ne = node_extents(n); xmin = Math.min(xmin, ne[0]); ymin = Math.min(ymin, ne[1]); xmax = Math.max(xmax, ne[2]); ymax = Math.max(ymax, ne[3]); area_sum += (ne[2] - ne[0]) * (ne[3] - ne[1]); x_size_min = Math.min(x_size_min, n.x_size); y_size_min = Math.min(y_size_min, n.y_size); }); var scale = 1; function svg_x(node_y) { return (node_y - ymin) * scale; } function svg_y(node_x) { return (node_x - xmin) * scale; } var nodebox_right_margin = Math.min(x_size_min * scale, 10), nodebox_vertical_margin = Math.min(y_size_min * scale, 3); function rand() { return 80 + Math.floor(Math.random() * 100); } var filler = function () { return "fill-opacity: 0; stroke:rgb(" + rand() + "," + rand() + "," + rand() + ")" }; node.transition() .duration(duration) .attr("transform", function (d) { if(d.parent && d.parent.y0 && d.parent.y_size){ d.y = d.parent.y0 + d.parent.y_size + 100; } else { d.y = d.depth * 180; } return "translate(" + svg_x(d.y) + "," + (svg_y(d.x)-(d.x_size * scale - nodebox_vertical_margin) / 2) + ")"; }); nodeEnter.append("rect") .attr({ x: 0, rx: 6, ry: 6, width: function (d) { return d.y_size * scale - nodebox_right_margin; }, height: function (d) { return d.x_size * scale - nodebox_vertical_margin; }, style: function(d){ return d.filler = filler(); } }) .attr('next', function(d){ if(d.children || d._children){ var $g = d3.select(this.parentNode).append('g').attr({ transform: 'translate(' + (d.y_size - 6) + ',' + (d.x_size/2 - 5) + ')' }).on("click", click); $g.append('circle').attr({ r: '7', cx: 3.5, cy: 3.5, style: 'stroke:' + d.filler }); $g.append('line').attr({ x1: 0, y1: 3.5, x2: 7, y2: 3.5, style: 'stroke:' + d.filler }); var $vertical_line = $g.append('line').attr({ x1: 3.5, y1: 0, x2: 3.5, y2: 7, style: 'stroke:' + d.filler }).classed('vertical-line', true); if(d._children){ $vertical_line.style('display', 'block'); } else { $vertical_line.style('display', 'none'); } return true } return false }); node.exit().transition() .duration(duration) .attr("transform", function (d) { return "translate(" + (source.y) + "," + (svg_y(source.x)-(source.x_size * scale - nodebox_vertical_margin)/2) + ")"; }) .remove(); var diagonal = d3.svg.diagonal() .source(function (d, i) { var s = d.source; return { x: s.x, y: s.y + s.y_size - nodebox_right_margin / scale }; }) .projection(function (d) { return [svg_x(d.y), svg_y(d.x)]; }) ; var enter_diagonal = d3.svg.diagonal() .source(function (d, i) { var s = d.source; return { x: s.x, y: s.y + s.y_size - nodebox_right_margin / scale }; }) .projection(function (d) { return [d.y, d.x]; }); var links = engine.links(nodes); var link = svg_g.selectAll("path.link") .data(links, function (d) { return d.target.id; }); link.enter().insert("path", "g") .attr("class", "link") .attr("d", function (d) { var o = { x: source.x0, y: source.y0, y_size: source.y_size }; return enter_diagonal({ source: o, target: o }); }); link.transition() .duration(duration) .attr("d", diagonal); link.exit().transition() .duration(duration) .attr("d", function (d) { var o = { x: source.x, y: source.y, y_size: source.y_size }; return diagonal({ source: o, target: o }); }) .remove(); nodes.forEach(function (d) { d.x0 = svg_y(d.x); d.y0 = svg_x(d.y); }); callback && callback(); } function redraw() { svg_g.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")"); } function click(d) { if (d.children) { d3.select(this).select('.vertical-line').style('display', 'block'); d._children = d.children; d.children = null; } else { d3.select(this).select('.vertical-line').style('display', 'none'); d.children = d._children; d._children = null; } update(d); } function parseText(text_tag, d){ var $text = d3.select(text_tag), content = d.content; if(typeof content === 'string'){ if(/^(\.\/)?img\//.test(content)){ var img_id = content.replace(/[\/\.]/g, ''); if($modal_cell.select('#' + img_id)[0][0] === null){ $modal_cell.append('img').attr('id', img_id).attr('src', content).attr('style', 'display:none'); } $text.append('tspan').attr({x: '2', dy: '1.5em', path: content}).text('点击查看图片'); d3.select(text_tag.parentNode).attr('img_id', img_id).on("click.show", function(){ $modal.select('#' + d3.select(this).attr('img_id')).attr("style", "display:inline-block"); $modal.attr("style", "display: block"); }); } else { var len = 0, split_str = '', reg = /[^\x00-\xff]/; var split_arr = content.split(''), split_arr_len = split_arr.length - 1; split_arr.forEach(function(val, i){ if(reg.test(val)){ len += 2; } else { len += 1; } split_str += val; if(len >= 30 || i >= split_arr_len){ $text.append('tspan').attr({x: '2', dy: '1.5em'}).text(split_str); len = 0; split_str = ''; } }); } } else { if(content.type === 'html_code'){ $modal_code.attr('class', 'language-html'); } else if(content.type === 'js_code'){ $modal_code.attr('class', 'language-javascript'); } $text.append('tspan').attr({x: '2', dy: '1.5em'}).text('点击查看代码'); d3.select(text_tag.parentNode).attr('code_id', content.id).on("click.show", function(){ var code = $iframe_doc.getElementById(d3.select(this).attr('code_id')).innerHTML; $modal_code.text(code); $modal_pre.style('display', 'inline-block'); Prism.highlightAll(); $modal.style('display', 'block'); }); } } });

bs_introduction.json

{ "content":"如何学习黑客", "children": [ { "content":"预备知识" , "children": [ {"content":"HTML & CSS" }, {"content":"JavaScript" }, {"content":"Linux" }, {"content":"SQL" } ] }, { "content":"安装" , "children": [ { "content":"记事本软件", "children": [ {"content":"VIM"}, {"content":"EditPlus"}, {"content":"Sublime Text"} ] }, { "content":"服务器软件", "children": [ {"content":"Apache Http Server"}, {"content":"Tomcat"}, {"content":"IIS"} ] }, {"content":"下载NMAP"}, {"content":"下载WIRESHARK"} ] }, { "content":"入门", "children": [ { "content":"入侵", "children": [ {"content":"select"}, {"content":"selectAll"} ] }, { "content":"sql注入", "children": [ {"content":"shell"}, {"content":"data"} ] }, {"content":"跨站脚本"}, { "content":"简单图形", "children": [ {"content":"柱形图"}, {"content":"折线图"}, {"content":"散点图"} ] }, {"content":"比例尺"}, {"content":"生成器"}, {"content":"过渡"} ] }, { "content":"进阶" , "children": [ { "content":"社会工程学的应用", "children": [ {"content":"饼状图"}, {"content":"树状图"}, {"content":"矩阵树图"} ] }, {"content":"缓冲区溢出攻击"} ] } ] }

运行结果如图:


代码下载链接

转载请注明原文地址: https://www.6miu.com/read-9668.html

最新回复(0)