Я пытался найти место назначения для смены сюжета с пчелами, но безрезультатно.Во-первых, я сделал простую диаграмму рассеяния, которая может переключаться, за исключением наложений оси x при переключении.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>D3: Transitioning points to randomized values, plus rescaled axes!</title>
<script src="https://d3js.org/d3.v4.min.js"></script><style type="text/css">
/* No style rules here yet */
</style>
</head>
<body>
<label>
<input type="radio" name='market' value="a" checked/>a
<input type="radio" name='market' value="b"/>b
</label>
<p>Click on this text to update the chart with new data values as many times as you like!</p>
<script type="text/javascript">
//Width and height
var w = 500;
var h = 300;
var padding = 30;
//Dynamic, random dataset
dataset = [
{"id":1,
"value":20,
"group":"a"},
{"id":1,
"value":10,
"group":"a"},
{"id":1,
"value":30,
"group":"a"},
{"id":1,
"value":40,
"group":"a"},
{"id":1,
"value":42,
"group":"a"},
{"id":1,
"value":10,
"group":"b"},
{"id":1,
"value":12,
"group":"b"},
{"id":1,
"value":15,
"group":"b"},
{"id":1,
"value":23,
"group":"b"},
{"id":1,
"value":22,
"group":"b"},
{"id":1,
"value":54,
"group":"b"}
]
//Create scale functions
var xScale = d3.scaleLinear()
.range([padding, w - padding * 2]);
var yScale = d3.scaleLinear()
.range([h - padding, padding]);
//Define X axis
var xAxis = d3.axisBottom()
.scale(xScale)
.ticks(5);
//Define Y axis
var yAxis = d3.axisLeft()
.scale(yScale)
.ticks(5);
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
draw(dataset.filter(d=> d.group=="a"));
//////////////////
//toggle//
//////////////////
d3.selectAll("input")
.on("change", function() {
var data_new = dataset.filter(d => (d.group == this.value));
draw(data_new);
});
//////////////////
//Create circles
//////////////////
function draw(dataset) {
//////////////////
//Create axis
xScale.domain([0, d3.max(dataset, function(d) { return d.value; })])
yScale.domain([0, 2])
var xAxis = d3.axisBottom()
.scale(xScale)
.ticks(5);
//Create X axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + (h - padding) + ")")
.transition(2000)
.call(xAxis);
//Create Y axis
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + padding + ",0)")
.call(yAxis);
//////////////////
//draw circle
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx", function(d) {
return xScale(d.value);
})
.attr("cy", function(d) {
return yScale(d.id);
})
.attr("r", 3)
.attr("opacity",0.2);
//update
svg.selectAll("circle")
.transition()
.duration(1000)
.attr("cx", function(d) {
return xScale(d.value);
})
}
</script>
</body>
</html>
Однако, когда применяется аналогичный код для графика с пчелиным теплом, точки не меняют местоположение при выделении, они просто накладывают слойкак ось X в первом примере:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
</style>
<label>
<input type="radio" name='market' value="a" checked/>a
<input type="radio" name='market' value="b"/>b
</label>
<svg width="400" height="200"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("svg"),
margin = {top: 40, right: 40, bottom: 40, left: 40},
width = svg.attr("width") - margin.left - margin.right,
height = svg.attr("height") - margin.top - margin.bottom;
var formatValue = d3.format(",d");
var x = d3.scaleLog()
.rangeRound([0, width]);
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
data = [
{"id":1,
"value":20,
"group":"a"},
{"id":1,
"value":21,
"group":"a"},
{"id":1,
"value":30,
"group":"a"},
{"id":1,
"value":32,
"group":"a"},
{"id":1,
"value":42,
"group":"a"},
{"id":1,
"value":10,
"group":"b"},
{"id":1,
"value":12,
"group":"b"},
{"id":1,
"value":15,
"group":"b"},
{"id":1,
"value":23,
"group":"b"},
{"id":1,
"value":22,
"group":"b"},
{"id":1,
"value":24,
"group":"b"}
]
//default
draw(data.filter(d=> d.group=="a"));
d3.selectAll("input")
.on("change", function()
{
var newdata = draw(data.filter(d=> d.group==this.value));
draw(newdata)
} )
/////////////////
//draw swarmplot
/////////////////
function draw(data) {
// transition
var t = d3.transition()
.duration(750);
x.domain(d3.extent(data, d=> d.value));
var simulation = d3.forceSimulation(data)
.force("x", d3.forceX(function(d) { return x(d.value); }).strength(1))
.force("y", d3.forceY(height / 3))
.force("collide", d3.forceCollide(18))
.stop();
for (var i = 0; i < 120; ++i) simulation.tick();
//axis
g.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x).ticks(20, ".0s"));
//for mouse-over
var cell = g.append("g")
.attr("class", "cells")
.selectAll("g").data(d3.voronoi()
.extent([[-margin.left, -margin.top], [width + margin.right, height + margin.top]])
.x(function(d) { return d.x; })
.y(function(d) { return d.y; })
.polygons(data)).enter().append("g");
//circle
cell.append("circle")
.attr("r", 3)
.attr("cx", function(d) { return d.data.x; })
.attr("cy", function(d) { return d.data.y; })
.attr("fill", d => (d.data.Food_Sub_Group))
.attr("opacity", 0.4);
//update circle
cell.selectAll("circle")
.transition()
.duration(1000)
.attr("cx", function(d) { return d.data.x; })
}
</script>
Что-нибудь здесь не так?Спасибо.