1

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>

1 Answer 1

3

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>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.