我想通过单选按钮选择值时更新条形图。此值作为查询的参数传递,以获取相应的JSON数据。
代码工作正常,不包括一个方面。当我通过单击任何单选按钮选择值时,条形图将绘制在现有条形图的顶部。我希望每次选择新选项时都重新绘制图表。
// set the dimensions of the canvas
var margin = {top: 20, right: 20, bottom: 70, left: 40},
width = 600 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
// set the ranges
var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);
var y = d3.scale.linear().range([height, 0]);
// define the axis
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10);
var compSvg = d3.select(".company");
var companies = [];
d3.json("http://localhost:8983/solr/techproducts/select?q=popularity:[10%20TO%20*]&wt=json&fl=cat&facet=true&facet.field=cat", function(error, resp) {
var results = resp.facet_counts.facet_fields.cat;
for (var i = 0; i < 5; i++) {
var value = results[i*2];
companies.push(value);
}
});
//functions for toggling between data
function change(value){
update(value);
}
function update(comp){
var query = 'cat:"' + comp + '"';
var url = "http://localhost:8983/solr/techproducts/select?q=" + encodeURIComponent(query) + "&rows=10&fl=manu,price&wt=json"
// load the data
d3.json(url, function(error, resp) {
if (error) return console.error(error);
resp.response.docs.forEach(function(d) {
d.manu = d.manu;
d.price = +d.price;
});
// scale the range of the data
x.domain(resp.response.docs.map(function(d) { return d.manu; }));
y.domain([0, d3.max(resp.response.docs, function(d) { return d.price; })]);
// add axis
compSvg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)" );
compSvg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 5)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Price");
// Add bar chart
compSvg.selectAll("bar")
.data(resp.response.docs)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.manu); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.price); })
.attr("height", function(d) { return height - y(d.price); });
});
}
答案 0 :(得分:2)
第一次加载图表时,一切都按预期工作:您有一个空选择,输入选择为数据数组中的每个项创建一个元素。你也追加轴。
使用change
功能第二次加载图表时,首先重复您创建图表所做的操作:您有一个空选择,因为selectAll("bar")
将为空,并且输入选择为数据数组中的每个项创建一个新元素。你也追加轴。
您需要使用更新和退出选择才能正常运行:
添加初始数据后,您需要使用更新选择来修改条形图,输入以引入新条形图(如果一个数据集使用的条形图比另一个更多),以及退出选择以退出不需要的条形图形(如果有数据集比另一个使用更少的条形图。在输入,更新,退出过程中有大量的在线信息;请记住,v4和v3之间存在差异。
这看起来像:
var data = [
[1,2,3,4,5],
[6,4,3],
[5,10,1,7,1,3]
];
var i = 0;
var width = 500;
var height = 500;
var svg = d3.select("body")
.append("svg")
.attr("width",width)
.attr("height",height);
var y = d3.scale.linear().range([height, 0]);
var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);
update(data[0]);
timer();
function update(dataset) {
// update scales
y.domain([0,d3.max(dataset, function(d) { return d; })] );
x.domain(dataset.map(function(d,i) { return i; }) );
// Bind Data
var bars = svg.selectAll(".bars")
.data(dataset);
// Update existing bars:
bars.transition()
.attr("x",function(d,i) { return x(i); })
.attr("y",function(d) { return y(d); })
.attr("width", x.rangeBand() )
.attr("height", function(d) { return height - y(d); })
.duration(1000);
// New Bars
bars.enter()
.append("rect")
.attr("class","bars")
.attr("x",function(d,i) { return x(i); })
.attr("width", x.rangeBand() )
.attr("y",height)
.attr("height",0)
.transition()
.attr("y",function(d) { return y(d); })
.attr("height", function(d) { return height - y(d); })
.duration(1000);;
// Un-needed Bars:
bars.exit()
.transition()
.attr("height", 0)
.duration(1000)
.remove();
}
function timer() {
setTimeout(function() { update(data[i++%3]); timer() } , 1500);
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
&#13;
答案 1 :(得分:-1)
稍作修改可能会满足您的需求:
function change(value){
// erase all contents before update
compSvg.html("");
update(value);
}