私は数ヶ月間d3 v4で作業しており、多くの研究を行っています。私は最終的にデータ結合コンセプトを理解していますが、グループ化された棒グラフを更新する方法を理解しようとすると、棒グラフの棒グラフを更新および削除するにはどうすればよいですか?
私の問題は、結合を実行するときに正しいSVG要素を選択しないため、update()
とexit()
のメソッドが常に空のセットを返すことです。ここに私のコードは、d3ブロックに基づいています:Codepenラインを参照してください#135ここですべての魔法はと思われるが起こっていると仮定。
/* Based on https://bl.ocks.org/mbostock/3887051 */
var svg = d3.select("svg"),
margin = { top: 20, right: 20, bottom: 100, left: 40 },
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom,
g = svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var formatTime = d3.timeFormat("%X");
var legendKeys = new Map();
var x0 = d3
.scaleBand()
.rangeRound([0, width])
.paddingInner(0.1);
var x1 = d3.scaleBand().padding(0.05);
var y = d3.scaleLinear().rangeRound([height, 0]);
var z = d3
.scaleOrdinal()
.range([
"#98abc5",
"#8a89a6",
"#7b6888",
"#6b486b",
"#a05d56",
"#d0743c",
"#ff8c00"
]);
var data = [];
for (var i = 0; i < 5; i++) {
generateData();
}
var keys = Object.keys(data[0].y);
keys.forEach(k => legendKeys.set(".data-" + k.replace(/ /g, "")));
g.append("g").attr("class", "bars");
var xAxis = g
.append("g")
.attr("class", "x--axis")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x0).tickFormat(formatTime));
var yAxis = g
.append("g")
.attr("class", "y--axis")
.call(d3.axisLeft(y).ticks(null, "s"));
var legend = g
.append("g")
.attr("font-family", "sans-serif")
.attr("font-size", 8)
.attr("text-anchor", "end")
.attr("class", "legend")
.selectAll("g")
.data(keys.slice())
.enter()
.append("g")
.attr("transform", function(d, i) {
return "translate(0," + i * 20 + ")";
});
legend
.append("rect")
.attr("x", width - 19)
.attr("width", 19)
.attr("height", 19)
.attr("style", "cursor:pointer")
.attr("fill", z)
.on("click", function(d) {
var key = ".data-" + d.replace(/ /g, "");
// determine if current line is visible
var active = legendKeys.get(key) ? false : true,
newOpacity = active ? 0 : 1;
// hide or show the elements
d3.selectAll(key).style("opacity", newOpacity);
// update whether or not the elements are active
legendKeys.set(key, active);
this.style.opacity = active ? 0.5 : 1;
});
legend
.append("text")
.attr("x", width - 24)
.attr("y", 9.5)
.attr("dy", "0.32em")
.text(function(d) {
return d;
});
window.setInterval(() => {
generateData();
if (data.length > 14) {
data.shift();
}
updateChart();
}, 1000);
function updateChart() {
x0.domain(
data.map(function(d) {
return d.x;
})
);
x1.domain(keys).rangeRound([0, x0.bandwidth()]);
y
.domain([
0,
d3.max(data, function(d) {
return d3.max(keys, function(key) {
return d.y[key];
});
})
])
.nice();
d3.select(".x--axis")
.transition()
.call(d3.axisBottom(x0).tickFormat(formatTime));
d3.select(".y--axis")
.transition()
.call(d3.axisLeft(y));
var barGroups = g
.select(".bars")
.selectAll(".barGroup")
.data(data);
barGroups
.enter()
.append("g")
.attr("transform", function(d) {
return "translate(" + x0(d.x) + ",0)";
})
.attr("class", "barGroup")
.selectAll("rect")
.data(function(d) {
return keys.map(function(key) {
return { key: key, value: d.y[key] };
});
})
.enter()
.append("rect")
.attr("x", function(d) {
return x1(d.key);
})
.attr("y", function(d) {
return y(d.value);
})
.attr("width", x1.bandwidth())
.attr("height", function(d) {
return height - y(d.value);
})
.attr("class", function(d) {
return "data-" + d.key.replace(/ /g, "");
})
.attr("fill", function(d) {
return z(d.key);
})
.merge(barGroups)
.attr("width", x1.bandwidth())
.attr("height", function(d) {
return height - y(d.value);
})
.attr("x", function(d) {
return x1(d.key);
})
.attr("y", function(d) {
return y(d.value);
});
// Exit
var old = barGroups
.exit()
.remove();
// Release memory for elements that were removed
old = null;
}
function generateData() {
var lastDate = new Date();
if (data.length > 0) {
lastDate = new Date(data[data.length - 1].x);
}
lastDate.setHours(lastDate.getHours() + 1);
data.push({
x: lastDate,
y: {
A: d3.randomUniform(0, 100)(),
B: d3.randomUniform(0, 100)(),
C: d3.randomUniform(0, 100)()
}
});
}
/* Based on https://bl.ocks.org/mbostock/3887051 */
rect.bar {
fill: steelblue;
}
text {
fill: #000;
font: 11px sans-serif;
font-weight:500;
}
/* body {
background-color: #f00;
} */
.legend rect:hover {
stroke-width:0.5;
stroke: black;
}
svg {
background-color:#eee;
shape-rendering: crispEdges;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.min.js"></script>
<!-- Based on https://bl.ocks.org/mbostock/3887051 -->
<svg width="900" height="400"></svg>
グループが正常に更新されているように見えるのは、更新していないバーです。彼らは独自の更新パターンが必要になります。 –
@ RyanMortonどうすればいいの? – RMS
この質問に対する回答(https://stackoverflow.com/questions/38921456/d3-updating-x-axis-groups-on-grouped-bar-chart)には、2つの変数(状態とバー)があり、両方の変数更新パターンに従います。私はそれが一般的に何が行われているかを示していると思う。 –