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

匿名 (未验证) 提交于 2019-12-03 03:03:02

问题:

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

Is there a way I can use condition within stroke color style based on value of X ?

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"); 

回答1:

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

All I do is split the data by using a 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"); 


回答2:

Here's a quick example that I've come up with:

Instead of a single path, let's use multiple lines.

We'll need to convert our data to have the following properties:

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

Then we can draw them with a conditional stroke attribute based on 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>


回答3:

I think you can achieve this by defining gradient for the line instead of styling it. Check out this solution here. change color of line graph based on data (red for above threshold of say 0 , and blue for below 0)

I asked a very similar question yesterday and was able to get it working by reading D3 documentation and looking at some samples like this one 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; }); 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!