簡體   English   中英

使用d3.js為svg圖表創建標記

[英]Creating Markers for svg chart using d3.js

我的小提琴例子

我正在使用以下代碼根據此示例創建標記。 如何使子節點指向父節點而不是父節點指向子節點?

vis.append("defs").selectAll("marker")
.data(force.links())
.enter().append("marker")
.attr("id", function(d) { console.log(d); return d.source.id; })
.attr("viewBox", "0 -5 10 10")
.attr("refX", 7)
.attr("refY", -1)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("path")
.attr("d", "M0,-5L10,0L0,5");

force.link數據綁定到標記似乎是不正確的。 我發現示例中存在重復的ID和標記:

<defs>
      <marker id="53" viewBox="0 -5 10 10" refX="7" refY="-1" markerWidth="6" markerHeight="6" orient="auto"><path d="M0,-5L10,0L0,5"></path></marker>
      <marker id="53" viewBox="0 -5 10 10" refX="7" refY="-1" markerWidth="6" markerHeight="6" orient="auto"><path d="M0,-5L10,0L0,5"></path></marker>
      <marker id="53" viewBox="0 -5 10 10" refX="7" refY="-1" markerWidth="6" markerHeight="6" orient="auto"><path d="M0,-5L10,0L0,5"></path></marker>
       ....................

完整代碼:

var w = 960,
    h = 500,
    node,
    path,
    root, nodes, links;

var force, vis;
var LoadData = true;

function update() {
    if (force) force.stop();
    nodes = flatten(root);
    links = d3.layout.tree().links(nodes);

    force.nodes(nodes)
        .links(links)
        .linkDistance(120)
        .charge(-500)
        .start();

    vis.append("defs").selectAll("marker")
    .data(force.links())
    .enter().append("marker")
    .attr("id", function(d) { console.log(d); return d.source.id; })
    .attr("viewBox", "0 -5 10 10")
    .attr("refX", 7)
    .attr("refY", -1)
    .attr("markerWidth", 6)
    .attr("markerHeight", 6)
    .attr("orient", "auto")
    .append("path")
    .attr("d", "M0,-5L10,0L0,5");

    path = vis.selectAll("path.link");
    path = path.data(force.links());
    path.exit().remove();
    path.enter().append("svg:path")
        .attr("class", "link")
        .attr("marker-end",function(d){ 
          return "url(#"+ d.source.id + ")";
        });
    vis.selectAll(".node .simpleDiv").remove();

    node = vis.selectAll(".node");
    node = node.data(force.nodes());
    node.exit().remove();
    node.enter().append("g")
        .attr("class", "node")
        .on("click", click)
        .call(force.drag);

    node.append("foreignObject")
        .attr("class", "simpleDiv")
        .attr("width", function (d) {
        var f = document.createElement("span");
        f.id = "hiddenText";
        f.style.display = 'hidden';
        f.style.padding = '0px';
        f.innerHTML = d.name;
        document.body.appendChild(f);
        textWidth = f.offsetWidth;
        var f1 = document.getElementById('hiddenText');
        f1.parentNode.removeChild(f1);
        return textWidth + 50;
    })
        .attr("overflow", "visible")
        .attr("height", 40)
        .append("xhtml:div").attr("class", "mainDiv").style("cursor", hoverStyle)
        .html(function (d) {
        var htmlString = "";
            htmlString += "<div class='userImage' style='border-color:" + color(d) + "'><img src='' width='30' height='30'></div>";
            htmlString += "<div class='content' style='color:" + color(d) + ";'>" + d.name + "</div>";
            htmlString += "<div style='clear:both;'></div>";
        return htmlString;
    });
}

function tick() {
    path.attr("d", function (d) {

        var dx = d.target.x - d.source.x,
            dy = d.target.y - d.source.y,
            dr = Math.sqrt(dx * dx + dy * dy);
        return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
    });

    node.attr("transform", function (d) {
        return "translate(" + (d.x - 15) + "," + (d.y - 15) + ")";
    });

}

function color(d) {
    return d._children ? "#3182bd" : d.children ? "#2044D2" : "#fd8d3c";
}

function hoverStyle(d) {
    return d._children ? "pointer" : d.children ? "pointer" : "default";
}
// Toggle children on click.
function click(d) {
    if (d.children) {
        d._children = d.children;
        d.children = null;
    } else {
        d.children = d._children;
        d._children = null;
    }
    update();
}

var findNode = function (node) {
    for (var i in force.nodes()) {
        if (force.nodes()[i] === node) return true
    };
    return false;
}

    function flatten(root) {
        var nodes = [],
            i = 0;

        function recurse(node) {
            if (node.children) node.children.forEach(recurse);
            if (!node.id) node.id = ++i;
            nodes.push(node);
        }

        recurse(root);
        return nodes;
    }

    function loadImage() {
       if (LoadData) {
            root = 
{ "brand":"32","id":"53","name":"AAA","parent_id":"0","children":
    [
        {"brand":"16","id":"536","name":"BBB","parent_id":"53"},         
        {"brand":"16","id":"547","name":"CCC","parent_id":"53"},
        {"brand":"16","id":"537","name":"EEE","parent_id":"53"},
        {"brand":"16","id":"538","name":"WWW","parent_id":"53"},
        {"brand":"14","id":"213","name":"KKK","parent_id":"53"},
        {"brand":"16","id":"540","name":"BBB","parent_id":"53"}
    ]
};
          force = d3.layout.force()
                .on("tick", tick)
                .size([w, h]);
          vis = d3.select("#chart").append("svg:svg")
                .attr("width", w)
                .attr("height", h);
            update();
            LoadData = false;
         }

    }

marker-end更改為marker-start 這會將標記放置在路徑的起點,在您的情況下,這將使線從子項指向父項。 您需要稍微弄亂路徑功能,因為當前移動箭頭會將它們全部置於父圓內彼此重疊。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM