I'm new to D3, but loving it so far. But I know my solutions lack... elegance.
I am trying to have 2 controls, a table and a graph displaying the data represented by the cells of the table. If you click on a cell on the table, the associated line should be highlighted. If you hover over a line the associate table cell will change color. Eventually there will be a third control showing detail data specific to that cel. Unfortunately I've only managed to make this work if I use static calls to the update function. If I try to be clever and dynamic the whole thing breaks.
I've tried to minimize my example as much as I can below. The click table->update line works because the calls to SelectData() that updates everything uses constant data. However the mouseover on the lines doesn't work. Eventually I need the table to be more dynamic too, but for now, how do I fix this?
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.lineDefault {
fill: none;
stroke: red;
stroke-width: 1.5px;
stroke-dasharray: 4,4;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
</style>
<body>
<div id="wrap">
<table>
<tr>
<td id="dataBlock" onclick="SelectData(0)">1</td>
<td id="dataBlock" onclick="SelectData(1)">2</td>
</tr>
<tr>
<td id="dataBlock" onclick="SelectData(2)">3</td>
<td id="dataBlock" onclick="SelectData(3)">4</td>
</tr>
</table>
<div>
<svg class="chart"></svg>
</div>
</div>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var width = 600, height = 600;
var maxx = 100,
maxy = 100;
var linedata = {};
linedata[0] = [[0, 50 ],[ 50, 60 ],[100, 100]];
linedata[1] = [[0, 40 ],[ 40, 40 ],[100, 90 ]];
linedata[2] = [[0, 20 ],[ 50, 30 ],[100, 90 ]];
linedata[3] = [[0, 0 ],[ 60, 30 ],[100, 30 ]];
var activeElement = 0;
var graphlines = {};
var numlines = 0;
chart = d3.select(".chart").attr("viewBox", "0 0 600 600").append("g");
var x = d3.scale.linear().domain([0, maxx]).range([0, width]);
var y = d3.scale.linear().domain([0, maxy]).range([height, 0]);
var xAxis = d3.svg.axis().scale(x).orient("bottom");
var yAxis = d3.svg.axis().scale(y).orient("left");
var line = d3.svg.line()
.x(function(d) { return x(d[0]); })
.y(function(d) { return y(d[1]); });
for (var i = 0; i < 4; i++) {
graphlines[i] = chart
.append("path")
.datum(linedata[i])
.attr("class", "lineDefault")
.attr("id", "linedata")
.attr("d", line)
.on("mouseover", SelectData(i));
numlines++;
}
function SelectData(n) {
d3.selectAll("td").transition()
.style("background-color", function(d, i) {
return i == n ? "#c99" : "#fff";
});
activeElement = n;
for (var i = 0; i<numlines; i++) {
if (i == n) {
graphlines[i]
.style("stroke-dasharray", "1,0")
.transition()
.style("stroke-width", "3")
.style("stroke", "steelblue");
} else {
graphlines[i]
.style("stroke-dasharray", "4,4")
.transition()
.style("stroke-width", "1.5")
.style("stroke", "red");
}
}
}
</script>
The mouseclick on the table effects the lines, the mouseover on the lines does not effect the table. Also I will accept any berating on my elegance and pointers to fixing them.