我已经阅读过关于如何从单选按钮返回值的多个SO答案,但我对如何使用此返回值更新图表感到有些困惑。
在下面的示例中,单选按钮不会更新任何内容,这里出了什么问题?
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
<meta charset="utf-8">
<title>D3: Loading data from a CSV file</title>
</head>
<body>
<div class="chart-container">
<form class="controls">
Scale:
<label>
<label><input type="radio" name="market" value="A" checked>
A</label>
<label><input type="radio" name="market" value="B"> B</label>
</label>
</form>
<svg class="chart js-chart"></svg>
</div>
<script type="text/javascript">
var margin = {top: 20, right: 20, bottom: 30, left: 40},
w = 600 - margin.left - margin.right,
h = 300 - margin.top - margin.bottom;
d3.csv('food.csv', function(error, data) {
if (error) throw error;
// format the data
data.forEach(function(d) {
d.Deliciousness=+d.Deliciousness
});
//radio button
d3.selectAll(("input[name='market']")).on("change", function(){
console.log(this.value)
var data_new=data.filter(d=>(d.Market==this.value));
console.log(data_new);
redraw(data_new);
});
function redraw(data){
var svg = d3.select("body")
.append("svg")
.attr("width", w + margin.left + margin.right)
.attr("height", h + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left+"," +
margin.top+")");
var xScale = d3.scaleBand()
.domain(d=>d.Food)
.range([0,w])
.paddingInner(0.2);
xScale.domain(data.map(function(d) { return d.Food; }));
var xAxis = d3.axisBottom()
.scale(xScale)
.ticks(5);
var yScale = d3.scaleLinear()
.domain([0, d3.max(data, d=>d.Deliciousness)])
.rangeRound([h,0]);
var yAxis = d3.axisLeft()
.scale(yScale)
.ticks(5);
svg.selectAll('rect')
.data(data)
.enter()
.append('rect')
.attr('x',(d,i) => margin.left + i*w/data.length)
.attr('y',d=>yScale(d.Deliciousness))
.attr('width', 20)
.attr('height',d =>h-yScale(d.Deliciousness))
.attr('fill',"blue");
}
})
// });
</script>
</body>
</html>
,数据是:
Market, Food,Deliciousness
A, Apples,9
A, Green Beans,5
A, Bananas,5
B, Apples,4
B, Green Beans,8
B, Bananas,7
它只返回B市场的图表,选择A市场并不起作用:最初只是空白。
然后在选择B后,B图表显示,切换回A,B图表保留,A图表不显示。
答案 0 :(得分:1)
代码中的主要问题是:
redraw()
内附加SVG。将其移到外面,仅附加一次的SVG。您没有更新并输入选择。它应该是:
var rect = svg.selectAll('rect')
.data(data);
var rectEnter = rect.enter()
.append('rect')
.merge(rect)
.attr('x', (d) => xScale(d.Food))
.attr('y', d => yScale(d.Deliciousness))
.attr('width', xScale.bandwidth())
.attr('height', d => h - yScale(d.Deliciousness))
.attr('fill', "blue");
此外,退出选择也是一个好主意。
小问题:
x
和width
属性。这是更新的bl.ocks:https://bl.ocks.org/GerardoFurtado/40c4a36d48e6dfaa30f0325f2973098f/fd2f8c76bf3cbaf6b57c34dfc2f00b0d394079ac