// the goal here is to see to what extent I can use one set of data to define classes at the group level // and another set to control entering/updating/exiting the data "use strict"; var svg = d3.select("body").append("svg") .attr("width", 1000) .attr("height", 400) // set up data var streamsForm = { "a": [1, 2, 5, 9, 10, 11, 23, 24, 25, 27, 28, 29, 30], "b": [3, 4, 12, 13, 14, 15, 16], "c": [6, 7, 8, 17, 18, 19, 20, 21, 22, 26] } var streams = { "a": [], "b": [], "c": [] } var data = [] for (var i = 0; i < 30; i++) { data[i] = { value: i } if (streamsForm["a"].indexOf(i) != -1) { data[i]["stream"] = "a"; streams["a"] = { value: i, stream: "a" } } else if (streamsForm["b"].indexOf(i) != -1) { data[i]["stream"] = "b"; streams["b"] = { value: i, stream: "b" } } else { data[i]["stream"] = "c"; streams["c"] = { value: i, stream: "c" } } } var stream_colors = { "a": "lightblue", "b": "darkgrey", "c": "orange" } setup(streams) function setup(streamsID) { for (var stream in streams) { svg.append("g") .attr("class", "stream_" + stream) .attr("fill", function(d) { return stream_colors[stream] }).selectAll("rect") .data(streams[stream], function(d) { return d.value }) .enter() .append("rect") .attr({ width: 25, height: 100, y: 62 }) .attr("x", function(d) { return d.value * 25 }) .attr("stroke", "white"); } } svg.on("mousemove", function(d) { return update(d3.mouse(this)[0]) }) // works, but is not ideal to have to filter through so many times function subsetData(data, stream, z) { return data.slice(z - 1, z + 5).filter(function(d) { if (d.stream == stream) { return d } }) } function update(x) { var z = Math.ceil(x / 25); for (var stream in streams) { var k = svg.selectAll(".stream_" + stream).selectAll("rect") .data(subsetData(data, stream, z), function(d) { return d.value; }) console.log(k) // no update // enter k.enter().append("rect") .attr({ width: 25, height: 100, y: 62 }) .attr("x", function(d) { console.log(d.value * 25) return d.value * 25 }) .attr("stroke", "white"); // exit k.exit().remove(); } }