D3 curved marks in the center of the arc

I managed to create a labeled donut chart, as in the following script:

http://jsfiddle.net/MX7JC/9/

But now I'm trying to put a label in the middle of each arc and span them along the arc (draw a label to follow each arc). For this, I was thinking of placing svg:textalong svg:textPathwith a function d3.svg.line.radial.

Then I came across the following script:

http://jsfiddle.net/Wexcode/CrDUy/

However, it is difficult for me to relate var arcs(the one who has the actual data) from the previous script to var linefrom the last violin, since the last violin uses the function d3.rangeas data.

I have been making a trial error for several hours, but nothing works. Does anyone know how it d3.svg.line.radialworks with d3.svg.arc?

+3
source share
2 answers

The function d3.svg.line.radialcreates a series of cubic Bezier curves (not arcs) between several points in the array based on the input polar coordinates (radius and angle) for each point.

(The example you are referring to seems to have drawn a circle, but only because it splits the circle to many very spaced points - try using 5 points instead of 50, and you will see that the shape of the curve isn’t a real circle.)

d3.svg.arc , , innerRadius, externalRadius, startAngle endAngle.

, "12 " ( ). , .

, , . , , , , i, , startAngle endAngle .

, . , , :
http://jsfiddle.net/MX7JC/688/

: , .

. : http://jsfiddle.net/4VnHn/5/

, , , "" , . , 45 ( ) , .

. : http://jsfiddle.net/4VnHn/6/

, , switch : http://jsfiddle.net/MX7JC/689/

, , , 45 - , , , , .

, SVG. , . , , interpolate.

, , x, y. . , - , :

function arcInterpolator(r) {
    //creates a line interpolator function
    //which will draw an arc of radius `r`
    //between successive polar coordinate points on the line

    return function(points) { 
    //the function must return a path definition string
    //that can be appended after a "M" command

        var allCommands = [];

        var startAngle; //save the angle of the previous point
                        //in order to allow comparisons to determine
                        //if this is large arc or not, clockwise or not

        points.forEach(function(point, i) { 

            //the points passed in by the line generator
            //will be two-element arrays of the form [x,y]
            //we also need to know the angle:        
            var angle = Math.atan2(point[0], point[1]);
            //console.log("from", startAngle, "to", angle);

            var command;

            if (i) command = ["A", //draw an arc from the previous point to this point
                        r, //x-radius
                        r, //y-radius (same as x-radius for a circular arc)
                        0, //angle of ellipse (not relevant for circular arc)
                        +(Math.abs(angle - startAngle) > Math.PI), 
                           //large arc flag,
                           //1 if the angle change is greater than 180degrees
                           // (pi radians),
                           //0 otherwise
                       +(angle < startAngle), //sweep flag, draws the arc clockwise
                       point[0], //x-coordinate of new point
                       point[1] //y-coordinate of new point
                       ];

            else command = point; //i = 0, first point of curve

            startAngle = angle;

            allCommands.push( command.join(" ") ); 
                //convert to a string and add to the command list
        });

        return allCommands.join(" ");
    };
}

: http://jsfiddle.net/4VnHn/8/

, , , . , , , , 360 (, , , , ):

var curveFunction = d3.svg.line.radial()
        .interpolate( arcInterpolator(r-45) )
        .tension(0)
        .radius(r-45)
        .angle(function(d, i) {
            return Math.min(
                i? d.endAngle : d.startAngle,
                Math.PI*2
                );
        //if i is 1 (true), this is the end of the curve,
        //if i is 0 (false), this is the start of the curve
        });

: http://jsfiddle.net/MX7JC/690/

, :

  • ;
  • , .
    ( donut , - "textcurve-Agg-Intl" );
  • <textPath> ;
  • xlink:href # id
+8

. , .

d3 , .

: http://jsfiddle.net/4VnHn/10/

: http://jsfiddle.net/MX7JC/691/

Key code:

var textArc = d3.svg.arc().outerRadius(r-45); //to generate the arcs for the text

textCurves.attr("d",  function(d) {
    var pie = textArc(d); //get the path code for the entire pie piece

    var justArc = /[Mm][\d\.\-e,\s]+[Aa][\d\.\-e,\s]+/; 
        //regex that matches a move statement followed by an arc statement

    return justArc.exec(pie)[0]; 
        //execute regular expression and extract matched part of string
});

r-45 . [\d\.\-e,\s]+ , , , ('e'), , , . , .

+2
source

Source: https://habr.com/ru/post/1530515/


All Articles