我希望你能提供帮助。我正在构建一个带有D3的条形图,我需要添加标签以及附加显示趋势和目标的路径。我为路径添加了一行但似乎没有生成。带有数据的我的CSV文件结构如下:
date,projectCode,numberOfSchools,newSchools
2011-12-1,"PRJ2.1",1188,0
代码如下:
<!Doctype html>
<html>
<head>
<title>D3 bar and line chart for Aphellion</title>
<meta charset="utf-8">
<script type="text/javascript" src="js/d3.v3.js"></script>
<!-- <script type="text/javascript" src"//cdnjs.cloudflare.com/ajax/libs/d3/3.4.8/d3.min.js"></script> -->
<style type="text/css">
/* the style for the page and charts goes here */
.axis {
font: 10px sans-serif;
}
.axis path
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.rect:hover {
fill: orange;
}
#tooltip {
background-color: white;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
-webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
-moz-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
pointer-events: none;
}
#tooltip.hidden {
display: none;
}
#tooltip p {
margin: 0;
font-family: sans-serif;
font-size: 16px;
line-height: 20px;
}
</style>
</head>
<body>
<div id="lineChart"></div>
<script type="text/javascript">
"Use strict"
//The script for the bar chart and line charts goes here
var margin = {top: 20, right: 20, bottom: 70, left: 40},
width = 600 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom
barPadding = 3;
//parse the date / time
var parseDate = d3.time.format("%Y-%m-%d").parse;
//set up the scales
var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);
var y = d3.scale.linear().range([height, 0]);
//set up the axis
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickFormat(d3.time.format("%Y-%m"));
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(5);
var svg = d3.select("body").append("svg")
.attr("class", "barChart")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.csv("Data/data.csv", function(error, data) {
data.forEach(function(d) {
d.date = parseDate(d.date.toString());
d.numberOfSchools = +d.numberOfSchools;
});
x.domain(data.map(function(d) {return d.date;}));
y.domain([0, d3.max(data, function(d) {return d.numberOfSchools;})]);
svg.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)");
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("Schools");
svg.selectAll("bar")
.data(data)
.enter()
.append("rect")
.style("fill", function(d) {
if(d.numberOfSchools < 1200) {
return "#ff0000";
} else if (d.numberOfSchools === 2000) {
return "#33cc33";
} else {return "steelblue";}
})
.attr("class", "rect")
.attr("x", function(d) {return x(d.date);})
.attr("width", x.rangeBand() - barPadding)
.attr("y", function(d) {return y(d.numberOfSchools);})
.attr("height", function(d) {return height - y(d.numberOfSchools);})
.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() / 2;
var yPosition = parseFloat(d3.select(this).attr("y")) + 14;
//Create the tooltip label
svg.append("text")
.attr("id", "tooltip")
.attr("x", xPosition)
.attr("y", yPosition)
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
.attr("font-size", "11px")
.attr("font-weight", "bold")
.attr("fill", "black")
.text(d.numberOfSchools + " current schools.");
})
.on("mouseout", function() {
//Remove the tooltip
d3.select("#tooltip").remove();
});
svg.selectAll("text")
.data(data)
.enter()
.append("text")
.text(function(d) {
return d.numberOfSchools;
})
.attr("x", function(d) {return x(d.date);})
.attr("y", function(d) {return y(d.numberOfSchools);});
})
//add a path to interpolate through the bars
var line = d3.svg.line()
.x(function(d) {return x(d.date)})
.y(function(d) {return y(d.numberOfSchools)});
//add the path
/*d3.select("svg")
.append("path")
.attr("d", line(data.numberOfSchools))
.attr("class", "numberOfSchools");
});*/
console.log("This code works");
</script>
</body>
</html>
理论上,我可以使用相同的代码来创建条形图的折线图吗?我尝试创建一个小提琴但我的CSV无法添加。尽管如此:http://jsfiddle.net/siyafrica/bfVHU/
答案 0 :(得分:0)
也许这会有所帮助:
我必须进行一系列更改才能使其正常工作,但基本上很难让rangeBands方法使用条形图使用时间数据。关于这个主题写了很多东西,这里有一个很好的(简短的)convo:https://groups.google.com/forum/#!topic/d3-js/7GsDmnB4kdE
我将其切换为使用日期刻度,这通常会起作用,但您必须做一些工作才能使条宽和定位正确。
var x = d3.time.scale().range([0, width]);
x.domain(d3.extent(data, function(d) { return d.date; }));
此外,您的线路生成器需要传递数据数组...
var line = d3.svg.line()
.x(function(d) {return x(d.date)})
.y(function(d) {return y(d.value)});
//add the path
svg.append("path")
.attr("d", line(data))
.attr("class", "numberOfSchools");
如果你想坚持使用序数x刻度并使用范围带,你可能需要一个辅助时间刻度来绘制路径,你需要在域的范围内添加所有日期,否则“空”天将会没有出现在你的图表上。