How to change line color in d3js according to axis value?

I want to change the color for this line chart if X> 100 I want it to turn "red"

Is there a way I can use a hatch color style condition based on the X value?

http://jsfiddle.net/iamjeannie/b445svob/1/ enter link description here

var lineData = [ { "x": 1,   "y": 5},  { "x": 20,  "y": 20},
                  { "x": 40,  "y": 10}, { "x": 60,  "y": 40},
                  { "x": 80,  "y": 5},  { "x": 100, "y": 60},
                { "x": 120,  "y": 15},  { "x": 140, "y": 40},
                { "x": 160,  "y": 25},  { "x": 180, "y": 20},
                { "x": 200,  "y": 15},  { "x": 220, "y": 80},
                { "x": 240,  "y": 35},  { "x": 260, "y": 60}
               ];

 //This is the accessor function we talked about above
var lineFunction = d3.svg.line()
                          .x(function(d) { return d.x; })
                          .y(function(d) { return d.y; })
                         .interpolate("linear");

//The SVG Container
var svgContainer = d3.select("body").append("svg")
                                    .attr("width", 200)
                                    .attr("height", 200);

//The line SVG Path we draw
var lineGraph = svgContainer.append("path")
                            .attr("d", lineFunction(lineData))
                            .attr("stroke", "blue")
                            .attr("stroke-width", 2)
                            .attr("fill", "none");

      

enter image description here

+3


source to share


3 answers


Here's another way, maybe in some cases, that might help:

All I do is split the data with filter

:



var lineGraph1 = svgContainer.append("path")
        .attr("d", lineFunction(lineData.filter(function(d) {
            return d.x <= 100;
        })))
        .attr("stroke", "blue")
        .attr("stroke-width", 2)
        .attr("fill", "none");
var lineGraph2 = svgContainer.append("path")
        .attr("d", lineFunction(lineData.filter(function(d) {
            return d.x >= 100;
        })))
        .attr("stroke", "red")
        .attr("stroke-width", 2)
        .attr("fill", "none");

      

+6


source


Here's a quick example I came up with:

Instead of one path, use multiple lines.

We need to transform our data into the following properties:

[
  {
    x1: currentX,
    y1: currentY,
    x2: nextX,
    y2: nextY
  },
  ...
]

      

Then we can draw them with a conditional attribute stroke

based on the data:



var lines = svgContainer.selectAll('line')
    .data(lineData)
    .enter()
    .append('line')
    .attr('x1', function(d) { return d.x1; })
    .attr('y1', function(d) { return d.y1; })
    .attr('x2', function(d) { return d.x2; })
    .attr('y2', function(d) { return d.y2; })
    .attr("stroke", function (d) {
        return (d.x > 50) ? 'red' : 'blue';
    })
    .attr("fill", "none")
    .attr("stroke-width", 2);

      

Here's a demo:

var lineData = [
        {"x": 1, "y": 5},
        {"x": 20, "y": 20},
                  { "x": 40,  "y": 10}, { "x": 60,  "y": 40},
                  { "x": 80,  "y": 5},  { "x": 100, "y": 60},
                { "x": 120,  "y": 15},  { "x": 140, "y": 40},
                { "x": 160,  "y": 25},  { "x": 180, "y": 20},
                { "x": 200,  "y": 15},  { "x": 220, "y": 80},
                { "x": 240,  "y": 35},  { "x": 260, "y": 60}
               ];
 
 //This is the accessor function we talked about above
var lineFunction = d3.svg.line()
                          .x(function(d) { return d.x; })
                          .y(function(d) { return d.y; })
                         .interpolate("linear");

//The SVG Container
var svgContainer = d3.select("body").append("svg")
                                    .attr("width", 200)
                                    .attr("height", 200);

lineData = lineData.map(function (point, index, arr) {
    var next = arr[index + 1],
        prev = arr[index - 1];
    return {
        x: point.x,
        y: point.y,
        x1: point.x,
        y1: point.y,
        x2: (next) ? next.x : prev.x,
        y2: (next) ? next.y : prev.y
    };
});

var lines = svgContainer.selectAll('line')
        .data(lineData)
        .enter()
        .append('line')
        .attr('x1', function(d) { return d.x1; })
        .attr('y1', function(d) { return d.y1; })
        .attr('x2', function(d) { return d.x2; })
        .attr('y2', function(d) { return d.y2; })
        .attr("stroke", function (d) {
            return (d.x > 50) ? 'red' : 'blue';
        })
        .attr("fill", "none")
        .attr("stroke-width", 2);
      

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
      

Run codeHide result


+3


source


I think you can achieve this by specifying a gradient for the line, not the style of it. Check out this solution here. change the color of the line plot based on the data (red for the upper threshold, say 0, and blue for below 0)

I asked a very similar question yesterday and was able to get it to work by reading the D3 documentation and looking at some samples like this https://bl.ocks.org/mbostock/3970883

svg.append("linearGradient")
               .attr("id", "line-gradient")
               .attr("gradientUnits", "userSpaceOnUse")
               .attr("x1", 0).attr("y1", y(0))
               .attr("x2", 0).attr("y2", y(2))
               .selectAll("stop")
               .data(
                      [
                       {offset: "100%", color: "blue"},
                       {offset: "100%", color: "red"},
                      ]
                    )
                .enter().append("stop")
                        .attr("offset", function(d) { return d.offset; })
                        .attr("stop-color", function(d) { return d.color; });

      

+1


source







All Articles