Reputation: 201
I'm trying to create a multi series line plot with D3 based on nested data (key variable of subgrp). I would like the colour of the stroke line to be determined by a non-key field (grp), but I can't access the value.
I've managed to achieve this using a none D3 approach (appending subgrp and grp and using this as the key), but there must be a more compliant way of doing it. I've looked at a number of similar questions/ tutorial, but haven't been able to get them to work.
A simplified version of the code is below.
Thanks in advance.
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://d3js.org/d3.v5.min.js"></script>
<body>
<script>
//build the data array
var dataset = [
{"yval": 1,"xval": 4,"grp":"a",subgroup:"sg1"}
,{"yval": 10,"xval": 20,"grp":"a",subgroup:"sg1"}
,{"yval": 30,"xval": 30,"grp":"a",subgroup:"sg2"}
,{"yval": 40,"xval": 10,"grp":"a",subgroup:"sg2"}
,{"yval": 10,"xval": 30,"grp":"b",subgroup:"sg3"}
,{"yval": 30,"xval": 40,"grp":"b",subgroup:"sg3"}
,{"yval": 0.4,"xval": 10,"grp":"b",subgroup:"sg4"}
,{"yval": 50,"xval": 90,"grp":"b",subgroup:"sg4"}
]
//nest the data on the subgroup
var dataNest = d3.nest()
.key(function(d) {return d.subgroup;})
.entries(dataset);
//line generator
var line = d3.line()
.x(function(d) { return d.xval; })
.y(function(d) { return d.yval; })
//add an svg element
svg=d3.select("body")
.append("svg");
//for each subgroup plot a distinct line
dataNest.forEach(function(d,i) {
svg.append("path")
.attr("d", line(d.values))
.style("stroke","red")
//style colour should be driven by an if clause based on the grp field
});
</script>
</html>
Upvotes: 1
Views: 71
Reputation: 28713
Just access the field you want
.style("stroke", e => d.values[0].grp == "a" ? "red" : "blue")
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://d3js.org/d3.v5.min.js"></script>
<body>
<script>
//build the data array
var dataset = [
{"yval": 1,"xval": 4,"grp":"a",subgroup:"sg1"}
,{"yval": 10,"xval": 20,"grp":"a",subgroup:"sg1"}
,{"yval": 30,"xval": 30,"grp":"a",subgroup:"sg2"}
,{"yval": 40,"xval": 10,"grp":"a",subgroup:"sg2"}
,{"yval": 10,"xval": 30,"grp":"b",subgroup:"sg3"}
,{"yval": 30,"xval": 40,"grp":"b",subgroup:"sg3"}
,{"yval": 0.4,"xval": 10,"grp":"b",subgroup:"sg4"}
,{"yval": 50,"xval": 90,"grp":"b",subgroup:"sg4"}
]
//nest the data on the subgroup
var dataNest = d3.nest()
.key(function(d) {return d.subgroup;})
.entries(dataset);
//line generator
var line = d3.line()
.x(function(d) { return d.xval; })
.y(function(d) { return d.yval; })
//add an svg element
svg=d3.select("body")
.append("svg");
//for each subgroup plot a distinct line
dataNest.forEach(function(d,i) {
svg.append("path")
.attr("d", line(d.values))
.style("stroke", e => d.values[0].grp == "a" ? "red" : "blue")
//style colour should be driven by an if clause based on the grp field
});
</script>
</html>
Upvotes: 3