I'm working on a parallel plot that is like this:

I'm trying to implement the brush function that selects for every column the number of paths and highlight them if they are in a precise range.
The problem is that I don't know exactly how to take the coordinate of the node of the path in that precise column.
Here is the code in which I try to implement it:
// set the dimensions and margins of the graph
var margin = {top: 30, right: 30, bottom: 10, left: 40},
width = 560 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
var brushParallelWidth = 50;
// append the svg object to the body of the page
var svgParallel = d3.select("#parallelPlot")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
function drawParallelPlot(){
// Parse the Data
d3.csv("../../data/processed/ParallelPlotData.csv", function(data) {
// Here I set the list of dimension manually to control the order of axis:
dimensions = ["GreenAreaDensity","LowEmission","AutobusStopDensity","CirculatingVehicles","ExposedNoisePollution"]
// Build the X scale -> it find the best position for each Y axis
var xParallel = d3.scalePoint()
.range([0, width])
.domain(dimensions);
// For each dimension, I build a linear scale. I store all in a y object
var yParallel = {}
var name;
for (i in dimensions) {
name = dimensions[i]
//console.log(name);
yParallel[name] = d3.scaleLinear()
.domain( d3.extent(data, function(d) {
//console.log(+d[name] + " is of type: " + typeof(+d[name])) // print the value and the type
return +d[name]; // --> Different axis range for each group
}) )
.range([height, 0])
}
// Highlight the specie that is hovered
var highlight = function(d){
//selected_city = d.City
// first every group turns grey
d3.selectAll(".line")
.transition().duration(200)
.style("stroke", "lightgrey")
.style("opacity", "0.5")
// Second the hovered specie takes its color
d3.selectAll("." + selected_city)
.transition().duration(200)
.style("stroke",function(p){ return( "#4682B4");})
.style("opacity", "1")
}
// Unhighlight
var doNotHighlight = function(d){
d3.selectAll(".line")
.transition().duration(200).delay(1000)
.style("stroke", function(p){ return( "#AAA");} )
.style("opacity", "1")
}
// The path function take a row of the csv as input, and return x and y coordinates of the line to draw for this raw.
function path(d) {
return d3.line()(dimensions.map(function(column) {
//console.log("here's the y coordinate of the axes: " + yParallel[column](d[column]));
//console.log("column is " + column);
return [xParallel(column), yParallel[column](d[column])];
}));
}
// Draw the lines
svgParallel
.selectAll("myPath")
.data(data)
.enter()
.append("path")
.attr("class", "pt") //here I call my class pt
.attr("class", function (d) { return "line" + d.City} ) // 2 class for each line: 'line' and the group name
.attr("d", path)
.style("fill", "none" )
.style("stroke", function(d){ return("#AAA")} )
.style("opacity", 0.5)
//.on("mouseover", highlight)
//.on("mouseleave", doNotHighlight )
// Draw the axis:
svgParallel.selectAll("myAxis")
// For each dimension of the dataset I add a 'g' element:
.data(dimensions).enter()
.append("g")
.attr("class", "axis")
// I translate this element to its right position on the x axis
.attr("transform", function(d) { return "translate(" + xParallel(d) + ")"; })
// And I build the axis with the call function
.each(function(d) { d3.select(this).call(d3.axisLeft().ticks(5).scale(yParallel[d])); })
// Add axis title
.append("text")
.style("text-anchor", "middle")
.attr("y", -9)
.text(function(d) { return d; })
.style("fill", "black")
//initialize the brush
const brushParallel = d3.brushY()
.extent([
[-(brushParallelWidth / 2), 0 ],
[ brushParallelWidth / 2, height]
])
.on("start brush end", brushedParallel)
//here I append the parallel brush for every axis --- store in a variable?
svgParallel.append("g")
.selectAll("g") //select all the graph
.data(dimensions)
.enter().append("g")
.attr("transform", d=>`translate(${xParallel(d)}, 0)`)
.attr("class", "brush")
.call(brushParallel);
//function passed to the brush to highlight the y axis
function brushedParallel() {
console.log("Prova funzione brushed");
//var actives = dimensions.filter(function(p){ return !yParallel[p].event.selection.empty(); });
extent = d3.event.selection; //sarebbe il punto in alto e in basso della selezione brush
//questi array servono per la colorazione dei path
var selectedLines=[]; //qui metto tutte i path della selezione
var allLines =[]; //qui metto tutti i path
//for every dimension
//I must take the brush associated
//and then color the path that are selected by the brush
//here I scroll through all the paths of the graph
d3.selectAll(".pt")
.each(dimensions.map(function(column){
var myLine = d3.select(this); //salvo la linea del path
//allLines.push(myLine); //here I push all the lines
console.log("dimension map");
if(extent[0][0] > yParallel[column](this.d[column]) && extent[0][1] < yParallel[column](this.d[column])){
console.log(yParallel[column](this.d[column]));
console.log("la brush funziona");
//selectedLines.push(myLine); //here I push only the selected lines
}
}));
}
})
}
drawParallelPlot();
I think the problem arises in the brushedParallel function, where I should select the paths and then store them in a variable that is used to change their color.
Here I link a simplyfied version of this plot, with an associated dataset:
https://stackblitz.com/edit/so76371176-cfsvya?file=index.js
Does anyone have any idea how to do this selection or how to fix the code?
Any help is appreciated!