admin管理员组

文章数量:1290976

Here is my code. I am trying to connect/draw a path between center and different nodes. Now I want to make a different colored stroke for a different path. I have created an array of color that for which path what will be stroke color. But I can't make the stroke in a different color.

var lineFunction = d3.svg.line()
                     .x(function(d) { return d.x;})
                     .y(function(d) { return d.y;})
                     .interpolate("linear");
var lineGraph = vis.append("g")
                  .append("path")
                  .attr("d", lineFunction(CenterList))
                  .attr("stroke", function(d, i) { return ColorArr[i]; } )
                  .attr("stroke-width", 5)
                  .attr("fill", "none")
                  .attr("id", "viz");

ColorArr=black, black, red, red, black, black, black, red, black, red;

Here is my code. I am trying to connect/draw a path between center and different nodes. Now I want to make a different colored stroke for a different path. I have created an array of color that for which path what will be stroke color. But I can't make the stroke in a different color.

var lineFunction = d3.svg.line()
                     .x(function(d) { return d.x;})
                     .y(function(d) { return d.y;})
                     .interpolate("linear");
var lineGraph = vis.append("g")
                  .append("path")
                  .attr("d", lineFunction(CenterList))
                  .attr("stroke", function(d, i) { return ColorArr[i]; } )
                  .attr("stroke-width", 5)
                  .attr("fill", "none")
                  .attr("id", "viz");

ColorArr=black, black, red, red, black, black, black, red, black, red;
Share Improve this question edited Feb 28, 2016 at 13:26 Peter Mortensen 31.6k22 gold badges110 silver badges133 bronze badges asked Jan 19, 2014 at 16:44 curiousguycuriousguy 3,2628 gold badges42 silver badges76 bronze badges 3
  • 4 The "lines" created by the line function are actually just a single SVG <path> element, which can only have a single stroke colour. If you want each section of the line to have a different colour, then you need to make them each separate SVG <line> elements. – AmeliaBR Commented Jan 19, 2014 at 17:20
  • Ok @AmeliaBR Thanks a lot for clearing the concept , I am also guessing the same. Can you outline the changes I supposed to made to the code. – curiousguy Commented Jan 19, 2014 at 17:29
  • @Dibyendu Dutta, now you see how important is to write very clear questions: Amelia an I interpreted it in very different ways.... – VividD Commented Jan 20, 2014 at 0:15
Add a ment  | 

2 Answers 2

Reset to default 5

To style different line segments differently, they have to be separate line elements instead of all part of one path.

However, drawing a line graph as a series of line elements plicates the code. For every point, you not only need to know the data at that point, you also need to the data for the previous or next point (the start or end of the line).

I had written up a (more plicated) example of making a line graph this way for a previous SO question, so I was able to quickly adapt it for you.

Here's the fiddle: http://fiddle.jshell/4xZwb/3/

For that example, I used an "each" call to group all the calculations:

var lines = svg.append("g").attr("class", "plot").selectAll("line");
        //define a d3 selection consisting of <line> elements
        //that are grouped within g.plot

    lines = lines.data(data);  
        //tell the selection to make room for every point in the data array

    lines.enter().append("line");
        //add one <line> element for every data point

    lines.each(function(d,i){
        //for each line in the selection, this function will be called
        //with d equal to the data point and i equal to the index
        //and "this" equal to the <line> element

        var value = d;
        //y-value for current point 
        //(we're just using the raw number from the array,
        //normally it would be something like d.y or d[1] )

        //find next point
        var next = i+1; //x-position (just using index #)
        var nextValue = data[i+1]; //y-position

        if (isNaN(nextValue)){
            // there is no next value,
            // so repeat this point as the end of line
            //(line will have zero length, but the marker will show up)
            next = i;
            nextValue = value;
        }

        d3.select(this) //select this particular <line> element
                        //so that we can use d3 methods

            //set coordinates:
            .attr( 
                {x1: xScale(i),
                 y1: yScale(value),
                 x2: xScale(next),
                 y2: yScale(nextValue)}
                )

            //Set styles for this individual line segment
            //e.g., based on whether value is increasing
            //or decreasing, we can set stroke colour red or black
            .style("stroke", ( (value > nextValue) ?
                              "red" :
                              "black" )
                  );
    });//end of "each" call

However, you could also set them individually, like in this version:

lines = lines.data(data);

lines.enter().append("line");

lines.attr("x1", function(d,i){return xScale(i);})
.attr("x2", function(d,i){
    return xScale( (i+1 == data.length)?i:i+1);
})
.attr("y1", function(d,i){return yScale(d);})
.attr("y2", function(d,i){
    return yScale( (i+1 == data.length)?
                  d:data[i+1]);
})
.style("stroke", function(d,i){
    return ( (d > data[i+1]) ?
             "red" : "black" )
    });

http://fiddle.jshell/4xZwb/4/

Take a look at following three jsFiddles. The key idea of the solution is as @AmeliaBR said. Study thoroughly the link implementation in these three graphs (it's fairly simple). I extracted the most important parts of the code.

Red only

.link_dashed {
    fill: none;
    stroke: #ff0000;
    stroke-width: 1.5px;
    stroke-dasharray: 0,20,20,30,10,10,10;
}

Black only

.link_dashed {
    fill: none;
    stroke: #000000;
    stroke-width: 1.5px;
    stroke-dasharray: 20,20,30,10,10,10,0;
}

Red and Black

.link_dashed {
    fill: none;
    stroke: #ff0000;
    stroke-width: 1.5px;
    stroke-dasharray: 0,20,20,30,10,10,10;
}
.link_dashed2 {
    fill: none;
    stroke: #000000;
    stroke-width: 1.5px;
    stroke-dasharray: 20,20,30,10,10,10,0;
}

本文标签: