我目前正在尝试从CSV文件制作一系列简单的条形图。 CSV文件分为多个列,每个列代表一个调查问题。每行代表一个调查受访者,每个单元格是特定问题的特定问题的答案。
这个想法是在顶部有一个两个箭头按钮,允许我更改图表,以便它代表调查中的下一个问题。
当我第一次加载页面时,我可以加载任何给定的图表,但是当我尝试使用按钮时,我会得到非常奇怪的行为,有些条不会消失,有些条会与其他条加倍。
按下几个按钮后,这两个轴和杆都加倍了:
我怀疑我正在严格分配密钥,以便d3不知道需要删除的内容,但我无法理解其中的内容。这是代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="http://d3js.org/d3.v3.min.js"></script>
<style>
</style>
<script type="text/javascript">
function draw(data) {
"use strict";
// Sets up initial question
var current_question = [1];
/*sets up the canvas for the visualization*/
var margin = 75,
width = 1400 - margin,
height = 700 - margin;
/*Adds title*/
d3.select("body")
.append("h2")
.text("Environmental Attitudes");
//Adds space for updated question text later
var question_text = d3.select("body")
.append('div')
.attr('class','question_text');
/*Adds buttons for question selection*/
var buttons =d3.select("body")
.append('div')
.attr('class','question_selection_buttons');
// y scale
var y = d3.scale.linear()
.range([height,0]);
// x scale
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
//x axis
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
//y axis
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
/*Adds the SVG element that will house everything else*/
var svg = d3.select("body")
.append("svg")
.attr("id", "svg_main")
.attr("width", width + margin)
.attr("height", height + margin);
// list of variables
var questions = d3.keys(data[0]).filter(function(d){
var x = "cluster";
if (d.indexOf(x) === -1 && d !== 'ids') {
return d ;
}
});
var num_questions = questions.length;
function update_chart(question) {
/*
d3.selectAll("svg > *")
.remove();
*/
// filters out NaN observations from data from the question "question"
var new_data = data.filter(function(d){
if(isNaN(+d[question])){
return false;
}
return true;
});
// rolls up data by answer in "question"
var nested = d3.nest()
.key(function(d){return d[question];
})
.rollup(function(leaves){
var total = data.length
var responses = leaves.length;
return {
'responses' : responses,
'percent' : responses/total
};
})
.entries(new_data)
var elem = svg.selectAll('rect')
.data(nested)
.exit()
.remove();
//sets the domain of x by passing it the range of possible values
x.domain(nested.map(function (d) {
return d.key;
}));
//sets the domain of y by passing it the range of possible values
y.domain([0, d3.max(nested, function (d) {
return +d.values['percent'].toPrecision(3);
})]);
//draws x axis
svg.append("g")
.attr('class','x axis')
.attr('transform', 'translate(0,' + height + ')')
.call(xAxis);
//draws y axis
svg.append('g')
.attr("class", 'y axis')
.call(yAxis);
svg.selectAll('g')
.data(nested)
.enter().append('g')
.attr('class','response')
.attr('transform', function(d){
return "translate (" + x(d.key) + ",0)";
});
svg.selectAll('rect')
.data(nested)
.enter().append("rect")
.attr("width", x.rangeBand())
.attr('height', function(d){
return height-y(+d.values['percent'].toPrecision(3));
})
.attr("y", function(d){return y(+d.values['percent'].toPrecision(3))})
.attr('transform', function(d){
return "translate (" + x(d.key) + ",0)";
});
};
var left = buttons.append('div')
.selectAll('div')
.data(current_question)
.enter()
.append('div')
.attr("class", "button")
.text("<")
.attr("id", "left-button");
var right = buttons.append('div')
.selectAll('div')
.data(current_question)
.enter()
.insert('div')
.attr("class", "button")
.text(">")
.attr("id", "right-button");
left.on("click", function(d) {
current_question--
if (current_question < 0) {
current_question = num_questions-1;
};
update_chart(questions[current_question])
});
right.on("click", function(d) {
current_question++
if (current_question >= num_questions) {
current_question = 0
}
update_chart(questions[current_question]);
});
update_chart(questions[current_question[0]]);
}
</script>
</head>
</body>
<script type="text/javascript">
d3.csv("clusterData.csv", draw)
</script>
</body>
</html>
再说一遍。通过在每次更新时清除svg元素的所有内容,我已经使图表正确刷新。该代码在上面的代码中被注释掉了。我想通过使用来做到这一点 .exit()。除去()。
以下是CSV格式的较小数据片段:
ids,ldcgrn,othssame,chemgen,natchld,natpark,sex,nukegen,harmgood,topprob1,drivless,grnmoney,topprob2,peopgrn,natsci,grngroup,redcehme,grntaxes,grncon,govdook,knowsol,chemfree,ihlpgrn,tempgen1,recycle,grndemo,impgrn,scigrn,h2oless,carsgen,indusgen,grnprice,grwthelp,nobuygrn,grneffme,helpharm,grnprog,toodifme,grnsign,harmsgrn,grnexagg,popgrwth,watergen,natenrgy,busgrn,natsoc,privent,grnsol,natroad,age,usdoenuf,grwtharm,econgrn,race,polgreed,polviews,grnintl,knwcause,grnecon,2_clusters,3_clusters,4_clusters,5_clusters,6_clusters,7_clusters,8_clusters,9_clusters,
1269,2,3,3,2,2,Female,1,4,Poverty,NaN,0,Health care,More information and education for people about the advantages of protecting the environment,2,0,1,4,3,4,3,1,4,3,NaN,0,3,3,1,3,2,3,3,1,NaN,4,4,4,0,4,3,4,3,2,More information and education for businesses about the advantages of protecting the environment,2,NaN,5,2,71,2,3,3,Black,4,6,3,3,3,1,0,1,0,5,6,2,0,
1403,4,2,3,1,1,Male,3,2,Health care,2,0,The environment,Heavy fines for people who damage the environment,2,0,2,3,5,3,4,2,4,3,2,0,4,4,2,1,1,2,4,4,2,3,4,5,0,4,4,4,1,2,NaN,2,4,3,2,18,2,2,4,Black,2,4,5,5,2,1,1,2,3,0,0,3,7,
1868,4,4,2,1,1,Male,1,2,The economy,NaN,0,Health care,More information and education for people about the advantages of protecting the environment,2,0,2,2,5,NaN,1,1,2,3,3,0,4,4,2,1,1,2,4,2,4,4,4,4,0,4,4,4,2,3,Heavy fines for businesses that damage the environment,2,5,4,2,51,1,2,4,White,4,4,4,1,3,1,1,1,3,0,0,3,7,
1296,2,2,2,1,1,Female,NaN,4,Health care,2,0,Immigration,More information and education for people about the advantages of protecting the environment,NaN,0,2,4,5,1,3,3,5,3,4,0,3,3,2,4,3,2,3,3,4,4,NaN,2,0,3,3,4,1,1,Heavy fines for businesses that damage the environment,1,3,2,NaN,41,1,3,NaN,White,4,4,4,3,2,0,1,2,2,3,2,7,4,
1256,2,4,2,1,2,Male,5,2,The economy,NaN,0,Poverty,More information and education for people about the advantages of protecting the environment,2,0,3,5,5,4,2,3,4,4,2,0,4,3,3,2,3,4,5,3,4,4,5,1,0,5,3,3,3,1,More information and education for businesses about the advantages of protecting the environment,1,3,5,1,51,2,2,4,Black,2,5,4,3,5,1,0,1,3,1,3,4,2,
1943,2,4,3,1,2,Female,2,1,Immigration,2,0,The economy,More information and education for people about the advantages of protecting the environment,1,0,2,5,5,2,2,2,4,3,3,0,3,2,3,1,1,2,4,2,5,4,2,4,0,4,2,4,1,1,More information and education for businesses about the advantages of protecting the environment,1,2,2,2,52,1,3,3,White,4,7,4,2,1,0,1,2,2,3,2,7,4,
1940,2,2,3,2,2,Male,3,2,Terrorism,3,0,Poverty,Use the tax system to reward people who protect the environment,1,0,3,3,4,2,2,3,4,1,4,0,2,2,2,2,2,3,4,2,2,4,4,4,0,4,2,4,1,1,Use the tax system to reward businesses that protect the environment,1,2,5,2,47,2,2,4,White,3,4,4,2,2,0,1,2,2,3,3,7,2,
1941,2,4,4,1,2,Male,4,2,Health care,1,0,Crime,More information and education for people about the advantages of protecting the environment,2,0,2,5,1,4,2,3,4,1,3,0,4,2,2,1,2,4,4,2,2,2,2,4,0,2,4,4,1,2,Heavy fines for businesses that damage the environment,2,2,5,2,75,1,2,4,White,2,3,4,2,4,1,0,1,0,5,6,2,2,
答案 0 :(得分:1)
夫妻问题:
1。)您将在每次更新时重新附加轴。添加一个空白,然后每次更新。
2。)您的rects
根本没有关注输入,更新,退出模式。请参阅下文,了解我如何相互独立地处理输入,更新和退出。
// set x domain to new data
x.domain(nested.map(function (d) {
return d.key;
}));
// set y domain to new data
y.domain([0, d3.max(nested, function (d) {
return +d.values['percent'].toPrecision(3);
})]);
// select your rects and bind your data
// note how I'm giving it a "key" function to guarantee the join is computed properly (https://github.com/mbostock/d3/wiki/Selections#data)
var rects = svg.selectAll('rect')
.data(nested, function(d){
return d.key;
});
// handle those elements entering
rects
.enter().append("rect");
// handle the update
rects
.attr("width", x.rangeBand())
.attr('height', function(d){
return height-y(+d.values['percent'].toPrecision(3));
})
.attr("y", function(d){return y(+d.values['percent'].toPrecision(3))})
.attr('x', function(d){
return x(d.key);
});
// handle the exit
rects.exit().remove();
// just update an already existing axis
svg.select('g.x.axis')
.call(xAxis);
svg.select('g.y.axis')
.call(yAxis);
Here's a working example where I've cleaned up your code a bit.