我有一个条形图,从两个下拉列表中提取一个值 - 年份和类型。当我更改这些选项时,条形图并不总是显示正确的数据。我认为我过滤不正确,我想知道什么是更好的方法来解决这个问题。谢谢!
代码:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body { font: 12px Arial;}
.bar {
fill: #0078a5;
}
.bar:hover {
fill: #18b7f2;
}
#tooltip {
position: absolute;
width: auto;
height: auto;
padding: 4px 6px;
background-color: #fff;
border:1px solid #eee;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
pointer-events: none;
}
#tooltip.hidden {
display: none;
}
#pop{
background-color: #fff;
border:1px solid #eee;
}
#tooltip p {
margin: 0;
font-family: sans-serif;
font-size: 14px;
}
.axis {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
#legendContainer{
position:absolute;
top:85px;
left:10px;
overflow: auto;
height:360px;
width:120px;
font-family:Helvetica, Arial, sans-serif;
font-size:11px;
}
#legend{
width:100px;
height:200px;
}
.legend {
font-size: 12px;
font-weight: normal;
text-anchor: left;
cursor: pointer;
}
#bar{
background:#ccc;
color:#222;
padding:8px 15px;
margin-right:6px;
border-radius:5px;
float:left;
width:20px;
}
.active{
background:#0b3774 !important;
color:#fff !important;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<label for="years">Year: </label>
<select id="years">
<option value="1900">1900</option>
<option value="1950">1950</option>
<option value="2000">2000</option>
<option value="2015" selected="selected">2015</option>
</select>
<label for="inds">Type: </label>
<select id="inds">
<option value="apples">apples</option>
<option value="pears">pears</option>
<option value="tomatoes">tomatoes</option>
</select>
<div id="legendContainer" class="legendContainer">
<svg id="legend"></svg>
</div>
<div id="tooltip" class="hidden">
<p><span id="state"></span></p>
</div>
<script>
function filterJSON(json, key, value) {
var result = [];
for (var foo in json) {
if (json[foo][key] === value) {
result.push(json[foo]);
}
}
return result;
}
var margin = {top: 20, right: 20, bottom: 130, left: 160},
width = 1200 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom,
padding = 0.25;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width - margin.left - margin.right], padding);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10);
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.json("data.json", function(error, json) {
if (error) throw error;
json.forEach(function(d) {
d.year = "" + d.year + "";
d.value = +d.value;
});
var myYear = d3.select("#years").node().value;
var myInd = d3.select("#inds").node().value;
console.log("myYear: ", myYear);
console.log("myInd: ", myInd);
d3.select('#years')
.on("change", function () {
var timeo = document.getElementById("years");
var yearo = timeo.options[timeo.selectedIndex].value;
data = filterJSON(json, 'year', yearo);
updateGraph(data);
});
d3.select('#inds')
.on("change", function () {
var sect = document.getElementById("inds");
var section = sect.options[sect.selectedIndex].value;
data = filterJSON(json, 'produce', section);
updateGraph(data);
});
// initial graph / defaults
var pop = filterJSON(json, 'year', "2015");
var data = filterJSON(pop, 'produce', 'apples');
updateGraph(data);
});
function updateGraph(data) {
// data.sort(function(a,b) {return b.state-a.state;});
data.forEach(function(d) {
d.active = true;
});
data.sort(function(a,b) {return a.value-b.value;});
x.domain(data.map(function(d) { return d.state; }));
y.domain([0, d3.max(data, function(d) { return d.value; })]);
var color = d3.scale.category20b();
var bars = svg.selectAll(".bar")
.data(data);
bars
.enter().append("rect")
.attr("class", "bar")
.on("mouseover", function(d) {
//Get this bar's x/y values, then augment for the tooltip
var xPosition = parseFloat(d3.select(this).attr("x")) + x.rangeBand() + 100;
var yPosition = parseFloat(d3.select(this).attr("y")) / 2 + height / 2;
//Update the tooltip position and value
d3.select("#tooltip")
.style("left", xPosition + "px")
.style("top", yPosition + "px")
.select("#state")
.text(d.state + ": " + d.produce + ": " + d.year + ": " + d.value);
d3.select("#tooltip").classed("hidden", false);
})
.on("mouseout", function() {
d3.select("#tooltip").classed("hidden", true);
})
.on("click", function(d){
d3.select(this).style("fill", "#ff3300");
});
bars.transition()
.attr("id", function(d){ return 'tag'+d.state.replace(/\s+/g, '');})
.attr("x", function(d) { return x(d.state); })
.attr("width", x.rangeBand())
.attr("y", function(d) {return y(d.value); })
.attr("height", function(d) { return height - y(d.value); });
bars.exit().remove();
svg.selectAll(".axis").remove();
var legend = d3.select("#legend")
.selectAll("text")
.data(data);
legend.enter().append("text")
.attr("x", 0)
.attr("y", function(d,i){return 10 +i*15;})
.attr("class", "legend")
.style("fill", "#0078a5")
.on("click", function(d){
// Determine if current line is visible
d.active = !d.active;
// Hide or show the elements based on the ID
d3.select("#tag"+d.state.replace(/\s+/g, ''))
.transition()
.duration(100)
.style("fill", "#ff3300");
var xPosition = parseFloat(d3.select(this).attr("x")) + x.rangeBand() + 100;
var yPosition = parseFloat(d3.select(this).attr("y")) / 2 + height / 2;
//Update the tooltip position and value
d3.select("#tooltip")
.style("left", xPosition + "px")
.style("top", yPosition + "px")
.select("#state")
.text(d.state + ": " + d.year + ": " + d.value);
d3.select("#tooltip").classed("hidden", false);
});
legend.transition()
.text(function(d){return d.state;});
legend.exit().remove();
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("value");
};
</script>
数据:
[
{
"state":"Maine",
"produce":"apples",
"year":1900,
"value":"131"
},
{
"state":"Maine",
"produce":"apples",
"year":1950,
"value":"231"
},
{
"state":"Maine",
"produce":"apples",
"year":2000,
"value":"191"
},
{
"state":"Maine",
"produce":"apples",
"year":2015,
"value":"302"
},
{
"state":"Pennsylvania",
"produce":"apples",
"year":1900,
"value":"31"
},
{
"state":"Pennsylvania",
"produce":"apples",
"year":1950,
"value":"331"
},
{
"state":"Pennsylvania",
"produce":"apples",
"year":2000,
"value":"291"
},
{
"state":"Pennsylvania",
"produce":"apples",
"year":2015,
"value":"250"
},
{
"state":"Ohio",
"produce":"apples",
"year":1900,
"value":"11"
},
{
"state":"Ohio",
"produce":"apples",
"year":1950,
"value":"230"
},
{
"state":"Ohio",
"produce":"apples",
"year":2000,
"value":"185"
},
{
"state":"Ohio",
"produce":"apples",
"year":2015,
"value":"310"
},
{
"state":"Maine",
"produce":"pears",
"year":1900,
"value":"171"
},
{
"state":"Maine",
"produce":"pears",
"year":1950,
"value":"121"
},
{
"state":"Maine",
"produce":"pears",
"year":2000,
"value":"231"
},
{
"state":"Maine",
"produce":"pears",
"year":2015,
"value":"202"
},
{
"state":"Pennsylvania",
"produce":"pears",
"year":1900,
"value":"73"
},
{
"state":"Pennsylvania",
"produce":"pears",
"year":1950,
"value":"151"
},
{
"state":"Pennsylvania",
"produce":"pears",
"year":2000,
"value":"399"
},
{
"state":"Pennsylvania",
"produce":"pears",
"year":2015,
"value":"140"
},
{
"state":"Ohio",
"produce":"pears",
"year":1900,
"value":"146"
},
{
"state":"Ohio",
"produce":"pears",
"year":1950,
"value":"130"
},
{
"state":"Ohio",
"produce":"pears",
"year":2000,
"value":"195"
},
{
"state":"Ohio",
"produce":"pears",
"year":2015,
"value":"210"
},
{
"state":"Maine",
"produce":"tomatoes",
"year":1900,
"value":"71"
},
{
"state":"Maine",
"produce":"tomatoes",
"year":1950,
"value":"221"
},
{
"state":"Maine",
"produce":"tomatoes",
"year":2000,
"value":"31"
},
{
"state":"Maine",
"produce":"tomatoes",
"year":2015,
"value":"102"
},
{
"state":"Pennsylvania",
"produce":"tomatoes",
"year":1900,
"value":"173"
},
{
"state":"Pennsylvania",
"produce":"tomatoes",
"year":1950,
"value":"194"
},
{
"state":"Pennsylvania",
"produce":"tomatoes",
"year":2000,
"value":"195"
},
{
"state":"Pennsylvania",
"produce":"tomatoes",
"year":2015,
"value":"230"
},
{
"state":"Ohio",
"produce":"tomatoes",
"year":1900,
"value":"216"
},
{
"state":"Ohio",
"produce":"tomatoes",
"year":1950,
"value":"184"
},
{
"state":"Ohio",
"produce":"tomatoes",
"year":2000,
"value":"125"
},
{
"state":"Ohio",
"produce":"tomatoes",
"year":2015,
"value":"150"
}
]
答案 0 :(得分:1)
您可以使用过滤器而不是每个属性,并将两个循环合并为一个,如下所示:
<input type='text' placeholder='Write your comment here' />
工作代码here
希望这有帮助!