我正在尝试重新创建多区域图表
http://tympanus.net/codrops/2012/08/29/multiple-area-charts-with-d3-js/
但是我没有进入可拖动区域的第一个月。
<body>
<div id="chart-container">
<script type="text/javascript">
var margin = {top: 10, right: 40, bottom: 150, left: 60},
width = 940 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom,
contextHeight = 50;
contextWidth = (width * .5) + 50;
var parseDate = d3.time.format("%Y-%m-%d").parse;//declare outside the for loop
var svg = d3.select("#chart-container").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", (height + margin.top + margin.bottom));
d3.csv('data_multiplec.csv', createChart);
function createChart(data){
var countries = [];
var charts = [];
var maxDataPoint = 0;
/* Loop through first row and get each country
and push it into an array to use later */
for (var prop in data[0]) {
if (data[0].hasOwnProperty(prop)) {
if (prop != 'Month') {
countries.push(prop);
}
}
};
var countriesCount = countries.length;
var startYear = data[0].Month;
var endYear = data[data.length - 1].Month;
var chartHeight = height * (1 / countriesCount);
/* Let's make sure these are all numbers,
we don't want javaScript thinking it's text
Let's also figure out the maximum data point
We'll use this later to set the Y-Axis scale
*/
data.forEach(function(d) {
for (var prop in d) {
if (d.hasOwnProperty(prop)) {
if (prop != 'Month') {
d[prop] = parseFloat(d[prop]);
if (d[prop] > maxDataPoint) {
maxDataPoint = d[prop];
}
}
}
}
d.Month = (parseDate(d.Month));
});
for(var i = 0; i < countriesCount; i++){
charts.push(new Chart({
data: data.slice(),
id: i,
name: countries[i],
width: width,
height: height * (1 / countriesCount),
maxDataPoint: maxDataPoint,
svg: svg,
margin: margin,
showBottomAxis: (i == countries.length - 1)
}));
}
/* Let's create the context brush that will
let us zoom and pan the chart */
var contextXScale = d3.time.scale()
.range([0, contextWidth + 240])
.domain(charts[0].xScale.domain());
var contextAxis = d3.svg.axis()
.scale(contextXScale)
.tickSize(contextHeight)
.tickPadding(-10)
.orient("bottom");
var contextArea = d3.svg.area()
.interpolate("monotone")
.x(function(d) { return contextXScale(d.Month); })
.y0(contextHeight)
.y1(0);
var brush = d3.svg.brush()
.x(contextXScale)
.on("brush", onBrush);
var context = svg.append("g")
.attr("class","context")
.attr("transform", "translate(" + (margin.left + width * .15) + "," + (height + margin.top + chartHeight - 10) + ")");
context.append("g")
.attr("class", "x axis top")
.attr("transform", "translate(0,0)")
.call(contextAxis)
context.append("g")
.attr("class", "x brush")
.call(brush)
.selectAll("rect")
.attr("y", 0)
.attr("height", contextHeight);
context.append("text")
.attr("class","instructions")
.attr("transform", "translate(0," + (contextHeight + 20) + ")")
.text('Click and drag above to zoom / pan the data');
function onBrush(){
/* this will return a date range to pass into the chart object */
var b = brush.empty() ? contextXScale.domain() : brush.extent();
for(var i = 0; i < countriesCount; i++){
charts[i].showOnly(b);
}
}
}
function Chart(options){
this.chartData = options.data;
this.width = options.width;
this.height = options.height;
this.maxDataPoint = options.maxDataPoint;
this.svg = options.svg;
this.id = options.id;
this.name = options.name;
this.margin = options.margin;
this.showBottomAxis = options.showBottomAxis;
var localName = this.name;
/* XScale is time based */
this.xScale = d3.time.scale()
.range([0, this.width])
.domain(d3.extent(this.chartData.map(function(d) { return d.Month; })));
/* YScale is linear based on the maxData Point we found earlier */
this.yScale = d3.scale.linear()
.range([this.height,0])
.domain([0,this.maxDataPoint]);
var xS = this.xScale;
var yS = this.yScale;
/*
This is what creates the chart.
There are a number of interpolation options.
'basis' smooths it the most, however, when working with a lot of data, this will slow it down
*/
this.area = d3.svg.area()
.interpolate("basis")
.x(function(d) { return xS(d.Month); })
.y0(this.height)
.y1(function(d) { return yS(d[localName]); });
/*
This isn't required - it simply creates a mask. If this wasn't here,
when we zoom/panned, we'd see the chart go off to the left under the y-axis
*/
this.svg.append("defs").append("clipPath")
.attr("id", "clip-" + this.id)
.append("rect")
.attr("width", this.width)
.attr("height", this.height);
/*
Assign it a class so we can assign a fill color
And position it on the page
*/
this.chartContainer = svg.append("g")
.attr('class',this.name.toLowerCase())
.attr("transform", "translate(" + this.margin.left + "," + (this.margin.top + (this.height * this.id) + (10 * this.id)) + ")");
/* We've created everything, let's actually add it to the page */
this.chartContainer.append("path")
.data([this.chartData])
.attr("class", "chart")
.attr("clip-path", "url(#clip-" + this.id + ")")
.attr("d", this.area);
this.xAxisTop = d3.svg.axis().scale(this.xScale).orient("bottom");
this.xAxisBottom = d3.svg.axis().scale(this.xScale).orient("top");
/* We only want a top axis if it's the first country */
if(this.id == 0){
this.chartContainer.append("g")
.attr("class", "x axis top")
.attr("transform", "translate(0,0)")
.call(this.xAxisTop);
}
/* Only want a bottom axis on the last country */
if(this.showBottomAxis){
this.chartContainer.append("g")
.attr("class", "x axis bottom")
.attr("transform", "translate(0," + this.height + ")")
.call(this.xAxisBottom);
}
this.yAxis = d3.svg.axis().scale(this.yScale).orient("left").ticks(10);
this.chartContainer.append("g")
.attr("class", "y axis")
.attr("transform", "translate(-15,0)")
.call(this.yAxis);
this.chartContainer.append("text")
.attr("class","country-title")
.attr("transform", "translate(15,40)")
.text(this.name);
}
Chart.prototype.showOnly = function(b){
this.xScale.domain(b);
this.chartContainer.select("path").data([this.chartData]).attr("d", this.area);
this.chartContainer.select(".x.axis.top").call(this.xAxisTop);
this.chartContainer.select(".x.axis.bottom").call(this.xAxisBottom);
}
</script>
</div>
</body>
</html>
第一个月,即1月份失踪。我改变了上下文宽度,但仍然不适应。
csv数据是:
日本,印度,美国,俄罗斯,英国,月
1000,2000,3000,2200,1230,2013-01-12 1300,2300,2400,2288,2123,2013-01-21 300,700,600,388,500,2013-02-12 200,300,900,588,700,2013-03-12 88,300,1900,1588,1000,2013-04-12 3500,600,800,588,323,2013-04-22 200,3000,900,588,2000,2013-06-12 200,3000,900,588,2000,2013-07-12 200,3000,900,588,2000,2013-08-12 200,3000,900,588,2000,2013-09-12 200,3000,900,588,2000,2013-10-12 400,1000,1800,1288,3000,2013-10-27 200,3000,900,588,2000,2013-11-12 200,3000,900,588,2000,2013-12-12