D3中的SVG标记

时间:2015-09-29 19:12:10

标签: javascript d3.js

我试图弄清楚如何在D3中使用SVG标记,但我正在努力使它恰到好处。我有一个小提琴here

我正在制作一个有向图,我有链接和节点全部设置,标记在那里我无法让它们可靠地触摸每个节点圆的边缘。我认为它与路径不是来自每个节点的中心的原因有关,但我不知道为什么它们也是。任何更熟悉标记的人都可以弄清楚如何让它们看起来更干净吗?

<!DOCTYPE html>
<meta charset="utf-8">
<style>

    .Chip{
        fill: red;
        stroke: black;
        stroke-width: 2px;
    }
    .Abstraction{
        fill: orange;
        stroke: black;
        stroke-width: 2px;
    }
    .Properties{
        fill: lightgreen;
        stroke: black;
        stroke-width: 2px;
    }
    .Location{
        fill: yellow;
        stroke: black;
        stroke-width: 2px;
    }
    path.link {
      fill: none;
      stroke: #000;
      stroke-width: 3px;
      cursor: default;
    }

    #licensing {
      fill: green;
    }

    .link.licensing {
      stroke: green;
    }

    .link.resolved {
      stroke-dasharray: 0,2 1;
    }
    path.link.selected {
      stroke-dasharray: 10,2;
    }

    path.link.dragline {
      pointer-events: none;
    }

    path.link.hidden {
      stroke-width: 0;
    }

</style>
<body>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js?1.29.1"></script>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.geom.js?1.29.1"></script>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.layout.js?1.29.1"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script>

var width = 960, height = 500, colors = d3.scale.category10();
var svg = null, force = null;
var circle = null, path = null;
var nodes = null, links = null;
var nodesArray = null, linkArray = null;
var count = 0;
var element = "body"; var numEdges = 4, numNodes = 10;
var i = 0; var L = 60, r = 12, lineLimit = 10;
var d = 2 * r + L;
var R = (count - 1) * d;
var m = width / 2;
var X, Y, radius = 12;

var markerWidth = 6,
    markerHeight = 6,
    //refX = 2*radius,
    refY = 0,
    refX = radius + (markerWidth),
    drSub = radius + refY;

svg = d3.selectAll(element).append('svg').attr('width', width).attr('height', height);


svg.append('svg:defs').append('svg:marker')
    .attr("id", "arrow")
    .attr("viewBox", "0 -5 10 10")
    .attr("refX", refX)
    .attr("refY", refY)
    .attr("markerWidth", markerWidth)
    .attr("markerHeight", markerHeight)
    .attr("orient", "auto")
    .append("svg:path")
    .attr("d", "M0,-5 L10,0L0,5").attr('fill', "#000");

nodes = d3.range(numNodes).map(function () {
    X = m - (R / 2) + (i * d)-250;
    if(i > 5) Y = 2*(height) / 3;
    else Y = (height) / 3;
    ++i;
    return {
        x: X,
        y: Y,
        fx: X,
        fy: Y,
        id: i-1,
        reflexive: true,
        r: 12
    };           
});
var clone = nodes;
for (var i = 0; i < numNodes; ++i) {
    d3.select(element).append("h3").text("Node " + i + ": " + nodes[i].id);
}

i = 0;
links = d3.range(numEdges).map(function () {
    i++;
    return {
        //
        source: nodes[i],
        target: nodes[i+1],
        left: false,
        right: true,
        direct: true
    }
});

for (var i = 0; i < numEdges; ++i) {
    d3.select(element).append("h3").text("Source: " + links[i].source.id + " Target: " + links[i].target.id);
}
links.push({source: nodes[1], target: nodes[3], left: false, right: true, direct: false});
// add the links and the arrows
var path = svg.append("svg:g").selectAll("path").data(links).enter().append("svg:path").attr("class", "link").attr("d", function(d){return linkPath(d)}).attr('marker-end', 'url(#arrow)');


var circleGroup = svg.selectAll("g").data(nodes);
var groupEnter = circleGroup.enter().append("g").attr("transform", function (d) { 
    return "translate(" + [d.x, d.y] + ")"; }).style("cursor", "pointer");
var circle = groupEnter.append("circle").attr("cx", 0).attr("cy", -4).attr("r", radius).attr("class", function(d){return classSelector(d)});
var label = circleGroup.append("text").text(function (d) { return d.id; }).attr({ "alignment-baseline": "middle", "text-anchor": "middle" }).style("class", "id");

function linkPath(d){
    var str;
    if(d.direct == true){
        str = "M " +    d.source.x + ", " + d.source.y +  " L "+  (d.target.x) + ", " +  d.target.y;
    }
    else{
        var direction = -1;
        var distance = 50;
        var dy = direction * distance;
        var height = d.source.y + dy;
        var p1 = "M " + d.source.x + ", " + d.source.y;
        var p2 = " L "+ d.source.x + ", " + (height);
        var p3 = " L " + d.target.x + ", " + height;
        var p4 = " L " + d.target.x + ", " + (d.target.y);
        //M(source.x, source.y) + L(source.x, height) + L(target.x, height) + L(target.x, target.y);
        //p1 + p2 + p3 + p4
        str = p1 +  p2 + p3 + p4;
    }           
    console.log("Arc: " + d.source.id + " to " + d.target.id + ": " + str);
    return str;

}
function classSelector(d) {
    if (d.id < 5 ) {
        return "Chip";
    }
    else if (5 <= d.id  < 8) {
        return "Abstraction";
    }
    else{
        return "Location"
    }
}
</script>

0 个答案:

没有答案