Is it possible to use d3.svg.symbol along with svg

2019-06-07 12:15发布

Currently I am using markers to plot arrow in between paths.

var def = viz.append("svg:defs")
    .selectAll(".traffic")
    .data(["green", "yellow", "red"]) ;// grey 

    def.enter().append("svg:marker")
    .attr("id", String)
    .attr("class","traffic")
    .attr("viewBox", "0 0 8 10")
    .append("svg:polyline")
    .attr("points","0,0 8,5 0,10 1,5")
    .attr("fill", String)
    ;

and my path will call the markers like

viz.selectAll("path").attr("marker-mid", "url(#red)");

Is is possible to use d3.svg.symbol() instead of marker or along with marker ?

标签: svg d3.js
1条回答
看我几分像从前
2楼-- · 2019-06-07 12:31

The d3.svg.symbol() object is used to generate the string for the "d" attribute of a <path>. So you change your marker to contain a path instead of a polyline and replace the "points" attribute with a "d" attribute and use the symbol function to calculate the attribute value.

The only other complication is to make sure that the symbol fits neatly within your marker. The symbols are sized by area with a default size of 64 square units, I found I had to make the viewBox 14 units on each side to get them to fit without cropping. (If you find the symbols are too small, set the markerWidth and markerHeight attributes on the <marker> element; the default is 3, aka three times the line width.) The symbols are designed to be centered at (0,0) within their coordinate system, so the viewBox should also be centered around zero.

You also have to be careful with styling markers, since the graphics inherit styles from the line they are attached to, not from the <marker> element.

Fiddle: http://fiddle.jshell.net/5hgSa/1/

var symbolGenerator = d3.svg.symbol()
        .type( function(d) {
             //sample function, not sure if you wanted them all the same symbol or not!
            var coloursToSymbols = {
                red:"cross",
                yellow:"square",
                green:"diamond"
            };
            return coloursToSymbols[d];
        });

var def = viz.append("svg:defs")
    .selectAll(".traffic")
    .data(["green", "yellow", "red"]) ;

def.enter().append("svg:marker")
    .attr("id", String)
    .attr("class","traffic")
    .attr("viewBox", "-7 -7 14 14")
    .append("svg:path")
    .attr("d", symbolGenerator)
    .style("fill", String) //use style, not attribute, to override the CSS on the path
    ;
查看更多
登录 后发表回答