From f7cbdfa509647dd51fee2bbea9d56a891ed92768 Mon Sep 17 00:00:00 2001 From: Phodal Huang Date: Wed, 3 Mar 2021 21:07:46 +0800 Subject: [PATCH] feat(codeflower): make it works --- web/public/js/graph/cloc/code-flower.js | 240 +++++++++++++++--------- 1 file changed, 156 insertions(+), 84 deletions(-) diff --git a/web/public/js/graph/cloc/code-flower.js b/web/public/js/graph/cloc/code-flower.js index 7e5e45ed..18bf57d5 100644 --- a/web/public/js/graph/cloc/code-flower.js +++ b/web/public/js/graph/cloc/code-flower.js @@ -1,102 +1,174 @@ function renderCodeFlower(data, selector) { data = {"name":"root","children":[{"name":"src","children":[{"name":"Faker","children":[{"name":"Provider","children":[{"name":"sk_SK","children":[{"name":"Address.php","size":337,"language":"PHP"},{"name":"Person.php","size":129,"language":"PHP"},{"name":"Company.php","size":49,"language":"PHP"},{"name":"Internet.php","size":22,"language":"PHP"},{"name":"PhoneNumber.php","size":13,"language":"PHP"}],"size":550},{"name":"ua_UA","children":[{"name":"Address.php","size":319,"language":"PHP"},{"name":"Transliteration.php","size":47,"language":"PHP"},{"name":"Person.php","size":39,"language":"PHP"},{"name":"Company.php","size":35,"language":"PHP"},{"name":"Internet.php","size":22,"language":"PHP"},{"name":"PhoneNumber.php","size":22,"language":"PHP"}],"size":484},{"name":"da_DK","children":[{"name":"Address.php","size":179,"language":"PHP"},{"name":"Person.php","size":145,"language":"PHP"},{"name":"Company.php","size":34,"language":"PHP"},{"name":"Internet.php","size":33,"language":"PHP"},{"name":"PhoneNumber.php","size":13,"language":"PHP"}],"size":404},{"name":"de_DE","children":[{"name":"Person.php","size":172,"language":"PHP"},{"name":"Address.php","size":73,"language":"PHP"},{"name":"Internet.php","size":27,"language":"PHP"},{"name":"PhoneNumber.php","size":18,"language":"PHP"},{"name":"Company.php","size":12,"language":"PHP"}],"size":302},{"name":"de_AT","children":[{"name":"Person.php","size":170,"language":"PHP"},{"name":"Address.php","size":87,"language":"PHP"}],"size":257},{"name":"Lorem.php","size":138,"language":"PHP"},{"name":"ru_RU","children":[{"name":"Address.php","size":132,"language":"PHP"},{"name":"Person.php","size":74,"language":"PHP"},{"name":"Internet.php","size":19,"language":"PHP"},{"name":"PhoneNumber.php","size":12,"language":"PHP"}],"size":237},{"name":"fr_FR","children":[{"name":"Company.php","size":117,"language":"PHP"},{"name":"Address.php","size":93,"language":"PHP"},{"name":"PhoneNumber.php","size":39,"language":"PHP"},{"name":"Person.php","size":30,"language":"PHP"},{"name":"Internet.php","size":27,"language":"PHP"}],"size":306},{"name":"pt_BR","children":[{"name":"Address.php","size":110,"language":"PHP"},{"name":"Person.php","size":88,"language":"PHP"},{"name":"Company.php","size":51,"language":"PHP"},{"name":"PhoneNumber.php","size":29,"language":"PHP"}],"size":278},{"name":"bg_BG","children":[{"name":"Person.php","size":107,"language":"PHP"},{"name":"Internet.php","size":21,"language":"PHP"},{"name":"PhoneNumber.php","size":18,"language":"PHP"}],"size":146},{"name":"nl_NL","children":[{"name":"Person.php","size":87,"language":"PHP"},{"name":"Address.php","size":83,"language":"PHP"},{"name":"PhoneNumber.php","size":32,"language":"PHP"},{"name":"Company.php","size":12,"language":"PHP"},{"name":"Internet.php","size":8,"language":"PHP"}],"size":222},{"name":"UserAgent.php","size":86,"language":"PHP"},{"name":"DateTime.php","size":85,"language":"PHP"},{"name":"Internet.php","size":85,"language":"PHP"},{"name":"cs_CZ","children":[{"name":"Person.php","size":83,"language":"PHP"},{"name":"Internet.php","size":22,"language":"PHP"},{"name":"PhoneNumber.php","size":12,"language":"PHP"}],"size":117},{"name":"nl_BE","children":[{"name":"Address.php","size":82,"language":"PHP"},{"name":"Internet.php","size":27,"language":"PHP"},{"name":"PhoneNumber.php","size":18,"language":"PHP"},{"name":"Person.php","size":11,"language":"PHP"},{"name":"Company.php","size":10,"language":"PHP"}],"size":148},{"name":"it_IT","children":[{"name":"Address.php","size":80,"language":"PHP"},{"name":"Person.php","size":69,"language":"PHP"},{"name":"Company.php","size":50,"language":"PHP"},{"name":"PhoneNumber.php","size":19,"language":"PHP"},{"name":"Internet.php","size":8,"language":"PHP"}],"size":226},{"name":"es_ES","children":[{"name":"Address.php","size":79,"language":"PHP"},{"name":"Company.php","size":61,"language":"PHP"},{"name":"Person.php","size":31,"language":"PHP"},{"name":"PhoneNumber.php","size":27,"language":"PHP"}],"size":198},{"name":"en_US","children":[{"name":"Address.php","size":79,"language":"PHP"},{"name":"Person.php","size":79,"language":"PHP"},{"name":"Company.php","size":49,"language":"PHP"},{"name":"PhoneNumber.php","size":31,"language":"PHP"}],"size":238},{"name":"Base.php","size":78,"language":"PHP"},{"name":"es_AR","children":[{"name":"Address.php","size":77,"language":"PHP"},{"name":"Person.php","size":74,"language":"PHP"},{"name":"Company.php","size":51,"language":"PHP"},{"name":"PhoneNumber.php","size":40,"language":"PHP"}],"size":242},{"name":"en_GB","children":[{"name":"Address.php","size":73,"language":"PHP"},{"name":"PhoneNumber.php","size":17,"language":"PHP"},{"name":"Internet.php","size":8,"language":"PHP"}],"size":98},{"name":"fi_FI","children":[{"name":"Address.php","size":71,"language":"PHP"},{"name":"Person.php","size":66,"language":"PHP"},{"name":"Company.php","size":49,"language":"PHP"},{"name":"PhoneNumber.php","size":18,"language":"PHP"},{"name":"Internet.php","size":8,"language":"PHP"}],"size":212},{"name":"Address.php","size":70,"language":"PHP"},{"name":"pl_PL","children":[{"name":"Person.php","size":45,"language":"PHP"},{"name":"Internet.php","size":22,"language":"PHP"},{"name":"PhoneNumber.php","size":12,"language":"PHP"}],"size":79},{"name":"sr_Cyrl_RS","children":[{"name":"Address.php","size":40,"language":"PHP"},{"name":"Person.php","size":14,"language":"PHP"}],"size":54},{"name":"sr_Latn_RS","children":[{"name":"Address.php","size":40,"language":"PHP"},{"name":"Person.php","size":14,"language":"PHP"}],"size":54},{"name":"sr_RS","children":[{"name":"Address.php","size":40,"language":"PHP"},{"name":"Person.php","size":14,"language":"PHP"}],"size":54},{"name":"Miscellaneous.php","size":35,"language":"PHP"},{"name":"tr_TR","children":[{"name":"Person.php","size":32,"language":"PHP"},{"name":"PhoneNumber.php","size":9,"language":"PHP"},{"name":"Internet.php","size":6,"language":"PHP"}],"size":47},{"name":"Uuid.php","size":30,"language":"PHP"},{"name":"Person.php","size":23,"language":"PHP"},{"name":"Company.php","size":18,"language":"PHP"},{"name":"PhoneNumber.php","size":10,"language":"PHP"}],"size":5611},{"name":"ORM","children":[{"name":"Propel","children":[{"name":"EntityPopulator.php","size":136,"language":"PHP"},{"name":"ColumnTypeGuesser.php","size":63,"language":"PHP"},{"name":"Populator.php","size":58,"language":"PHP"}],"size":257},{"name":"Doctrine","children":[{"name":"EntityPopulator.php","size":132,"language":"PHP"},{"name":"Populator.php","size":52,"language":"PHP"},{"name":"ColumnTypeGuesser.php","size":42,"language":"PHP"}],"size":226},{"name":"Mandango","children":[{"name":"EntityPopulator.php","size":80,"language":"PHP"},{"name":"Populator.php","size":39,"language":"PHP"},{"name":"ColumnTypeGuesser.php","size":30,"language":"PHP"}],"size":149}],"size":632},{"name":"Guesser","children":[{"name":"Name.php","size":57,"language":"PHP"}],"size":57},{"name":"Generator.php","size":52,"language":"PHP"},{"name":"Documentor.php","size":49,"language":"PHP"},{"name":"Factory.php","size":37,"language":"PHP"}],"size":6438},{"name":"autoload.php","size":17,"language":"PHP"}],"size":6455},{"name":"test","children":[{"name":"Faker","children":[{"name":"GeneratorTest.php","size":106,"language":"PHP"},{"name":"Provider","children":[{"name":"BaseTest.php","size":101,"language":"PHP"},{"name":"LoremTest.php","size":81,"language":"PHP"},{"name":"fr_FR","children":[{"name":"CompanyTest.php","size":68,"language":"PHP"}],"size":68},{"name":"UserAgentTest.php","size":30,"language":"PHP"},{"name":"PersonTest.php","size":21,"language":"PHP"},{"name":"UuidTest.php","size":21,"language":"PHP"},{"name":"LocalizationTest.php","size":14,"language":"PHP"}],"size":336},{"name":"PHPUnit","children":[{"name":"Framework","children":[{"name":"Constraint","children":[{"name":"IsValidSirenSiret.php","size":24,"language":"PHP"},{"name":"IsValidSiren.php","size":11,"language":"PHP"},{"name":"IsValidSiret.php","size":11,"language":"PHP"}],"size":46}],"size":46}],"size":46}],"size":488},{"name":"test.php","size":37,"language":"PHP"},{"name":"documentor.php","size":11,"language":"PHP"}],"size":536},{"name":".travis.yml","size":3,"language":"YAML"}],"size":6994} - let w = GraphConfig.width; - let h = GraphConfig.height; - let testdata = flatten(data); - console.log(testdata); - - let treemap = d3.tree() - .size([w, h]); - let nodes = d3.hierarchy(data); - const links = nodes.links(nodes); - - nodes = treemap(nodes); - - d3.select(selector).selectAll("svg").remove(); - const svg = d3.select(selector).append("svg").attr("viewBox", [0, 0, w, h]); - - const simulation = d3.forceSimulation(nodes) - // .force("link", d3.forceLink(links).id(d => {d.id})) - .force("charge", d3.forceManyBody()) - .force("center", d3.forceCenter(w / 2, h / 2)); - - const scale = d3.scaleOrdinal(d3.schemeCategory10); - let color = d => scale(d.group); - - const link = svg.append("g") - .attr("stroke", "#999") - .attr("stroke-opacity", 0.6) - .selectAll("line") - .data(links) - .join("line") - .attr("stroke-width", d => Math.sqrt(d.value)); - - const node = svg.append("g") - .attr("stroke", "#fff") - .attr("stroke-width", 1.5) - .selectAll("circle") - .data(nodes) - .join("circle") - .attr("r", 5) - .attr("fill", color) - .call(drag(simulation)) - - node.append("title") - .text(d => d.id); - - simulation.on("tick", () => { - link - .attr("x1", d => d.source.x) - .attr("y1", d => d.source.y) - .attr("x2", d => d.target.x) - .attr("y2", d => d.target.y); - - node - .attr("cx", d => d.x) - .attr("cy", d => d.y); - }); - - function drag() { - function dragstarted(event) { - if (!event.active) simulation.alphaTarget(0.3).restart(); - event.subject.fx = event.subject.x; - event.subject.fy = event.subject.y; - } + let width = GraphConfig.width; + let height = GraphConfig.height; + let i = 0; + let node, link; + + const root = d3.hierarchy(data); + + const svg = d3.select(selector).append('svg') + .attr("viewBox", [0, 0, width, height]) + .call(d3.zoom().scaleExtent([1, 8]).on('zoom', zoomed)) + .append('g') + .attr('transform', 'translate(40,0)'); + + const simulation = d3.forceSimulation() + .force('link', d3.forceLink().id(function (d) { + return d.id; + })) + .force('charge', d3.forceManyBody().strength(-15).distanceMax(300)) + .force('center', d3.forceCenter(width / 2, height / 4)) + .on('tick', ticked) + + function update() { + const nodes = flatten(root) + const links = root.links() + + link = svg + .selectAll('.link') + .data(links, function (d) { + return d.target.id + }) + + link.exit().remove() + + const linkEnter = link + .enter() + .append('line') + .attr('class', 'link') + .style('stroke', '#000') + .style('opacity', '0.2') + .style('stroke-width', 2) + + link = linkEnter.merge(link) + + node = svg + .selectAll('.node') + .data(nodes, function (d) { + return d.id + }) + + node.exit().remove() + + const nodeEnter = node + .enter() + .append('g') + .attr('class', 'node') + .attr('stroke', '#666') + .attr('stroke-width', 2) + .style('fill', color) + .style('opacity', 1) + .on('click', clicked) + .call(d3.drag() + .on('start', dragstarted) + .on('drag', dragged) + .on('end', dragended)) + + nodeEnter.append('circle') + .attr("r", function (d) { + return Math.sqrt(d.data.size) / 10 || 4.5; + }) + .style('text-anchor', function (d) { + return d.children ? 'end' : 'start'; + }) + .text(function (d) { + return d.data.name + }) + + node = nodeEnter.merge(node) + simulation.nodes(nodes) + simulation.force('link').links(links) + } - function dragged(event) { - event.subject.fx = event.x; - event.subject.fy = event.y; - } + update(); + + function sizeContain(num) { + num = num > 1000 ? num / 1000 : num / 100 + if (num < 4) num = 4 + return num + } - function dragended(event) { - if (!event.active) simulation.alphaTarget(0); - event.subject.fx = null; - event.subject.fy = null; + function color(d) { + return d._children ? "#51A1DC" // collapsed package + : d.children ? "#51A1DC" // expanded package + : "#F94B4C"; // leaf node + } + + function radius(d) { + return d._children ? 8 + : d.children ? 8 + : 4 + } + + function ticked() { + link + .attr('x1', function (d) { + return d.source.x; + }) + .attr('y1', function (d) { + return d.source.y; + }) + .attr('x2', function (d) { + return d.target.x; + }) + .attr('y2', function (d) { + return d.target.y; + }) + + node + .attr('transform', function (d) { + return `translate(${d.x}, ${d.y})` + }) + } + + function clicked(event, d) { + console.log(d); + if (!event.defaultPrevented) { + if (d.children) { + d._children = d.children; + d.children = null; + } else { + d.children = d._children; + d._children = null; + } + update() } + } - return d3.drag() - .on("start", dragstarted) - .on("drag", dragged) - .on("end", dragended); + function dragstarted(event) { + if (!event.active) simulation.alphaTarget(0.3).restart(); + event.subject.fx = event.subject.x; + event.subject.fy = event.subject.y; + } + function dragged(event) { + event.subject.fx = event.x; + event.subject.fy = event.y; + } + + function dragended(event) { + if (!event.active) simulation.alphaTarget(0); + event.subject.fx = null; + event.subject.fy = null; } function flatten(root) { - let nodes = [], i = 0; + const nodes = [] function recurse(node) { - if (node.children) { - node.size = node.children.reduce(function(p, v) { - return p + recurse(v); - }, 0); - } + if (node.children) node.children.forEach(recurse) if (!node.id) node.id = ++i; - nodes.push(node); - return node.size; + else ++i; + nodes.push(node) } - root.size = recurse(root); - return nodes; + recurse(root) + return nodes + } + + function zoomed(event) { + svg.attr('transform', event.transform) } }