D3 version 4 AXIS - d3.js

Does someone know why I can't see the axis of my line chart?
This is the link to the chart: https://d3responsive.firebaseapp.com/responsive.html
And this is the JavaScript code:
/* D3-v4 curve interpolation comparison: https://bl.ocks.org/d3noob/ced1b9b18bd8192d2c898884033b5529 */
var dataline1 = [
{"mes":1, "impuestoPorcentaje":20},
{"mes":2, "impuestoPorcentaje":14},
{"mes":3, "impuestoPorcentaje":20},
{"mes":4, "impuestoPorcentaje":21},
{"mes":5, "impuestoPorcentaje":15},
{"mes":6, "impuestoPorcentaje":22},
{"mes":7, "impuestoPorcentaje":9},
{"mes":8, "impuestoPorcentaje":6},
{"mes":9, "impuestoPorcentaje":23},
{"mes":10, "impuestoPorcentaje":7},
{"mes":11, "impuestoPorcentaje": 40},
{"mes":12, "impuestoPorcentaje": 45}
];
var dataline2 = [
{"mes":1, "impuestoPorcentaje":14},
{"mes":2, "impuestoPorcentaje":19},
{"mes":3, "impuestoPorcentaje":24},
{"mes":4, "impuestoPorcentaje":24},
{"mes":5, "impuestoPorcentaje":24},
{"mes":6, "impuestoPorcentaje":27},
{"mes":7, "impuestoPorcentaje":32},
{"mes":8, "impuestoPorcentaje":38},
{"mes":9, "impuestoPorcentaje":11},
{"mes":10, "impuestoPorcentaje":25},
{"mes":11, "impuestoPorcentaje": 40},
{"mes":12, "impuestoPorcentaje": 45}
];
var wl = 550;
var hl = 450;
var svgl = d3.select("body").append("svg")
.attrs({
width: wl,
height: hl
});
// Domain and ranges
var xscalel1 = d3.scaleLinear()
.domain([0, d3.max(dataline1, function(d) {
return d.mes;
})])
.range([0, wl - 30]);
var yscalel1 = d3.scaleLinear()
.domain([0, d3.max(dataline1, function(d) {
return d.impuestoPorcentaje;
})])
.range([hl - 30, 15]);
var xscalel2 = d3.scaleLinear()
.domain([0, d3.max(dataline2, function(d) {
return d.mes;
})])
.range([0, wl - 30]);
var yscalel2 = d3.scaleLinear()
.domain([0, d3.max(dataline2, function(d) {
return d.impuestoPorcentaje;
})])
.range([hl - 30, 15]);
// Lines
var lineOne = d3.line()
.x(function(d) {
return xscalel1(d.mes);
})
.y(function(d) {
return yscalel1(d.impuestoPorcentaje);
})
.curve(d3.curveLinear);
var lineTwo = d3.line()
.x(function(d) {
return xscalel2(d.mes);
})
.y(function(d) {
return yscalel2(d.impuestoPorcentaje);
})
.curve(d3.curveMonotoneX);
var vis = svgl.append("path")
.attrs({
d: lineOne(dataline1),
"stroke": "#008080",
"stroke-width": 2,
"fill": "none"
});
var vis2 = svgl.append("path")
.attrs({
d: lineTwo(dataline2),
"stroke": "orange",
"stroke-width": 2,
"fill": "none"
});
// Add the x Axis
svgl.append("g")
.attr("transform", "translate(0," + hl + ")")
.call(d3.axisBottom(xscalel1));
// Add the y Axis
svgl.append("g")
.call(d3.axisLeft(yscalel1));

You are translating the axis all the way down to the height of the SVG. You have to leave some margin.
For instance, this is your code right now (I'm simplifying your domain):
var wl = 550;
var hl = 150;
var svgl = d3.select("body").append("svg")
.attr("width", wl)
.attr("height", hl);
var xscalel1 = d3.scaleLinear()
.domain([0, 100])
.range([0, wl-30]);
svgl.append("g")
.attr("transform", "translate(0," + hl + ")")
.call( d3.axisBottom(xscalel1) );
<script src="https://d3js.org/d3.v4.min.js"></script>
Nothing will show up after clicking "run code snippet", just a blank space. You can't see anything, because this:
.attr("transform", "translate(0," + hl + ")")
Is moving the axis to the height (hl) of the SVG, that is, to its end.
Now let's see the same code with some margin, like this:
.attr("transform", "translate(0," + (hl - 20) + ")")
That way, we are moving the axis to 20 pixels before the end (height) of the SVG.
And here is the result, now you can see the axis:
var wl = 550;
var hl = 150;
var svgl = d3.select("body").append("svg")
.attr("width", wl)
.attr("height", hl);
var xscalel1 = d3.scaleLinear()
.domain([0, 100])
.range([0, wl-30]);
svgl.append("g")
.attr("transform", "translate(0," + (hl - 20) + ")")
.call( d3.axisBottom(xscalel1) );
<script src="https://d3js.org/d3.v4.min.js"></script>

Related

Adding axes eats up my data

I'm following the D3 tutorial but adding the axis makes half of my data disappear and I don't understand why. I thought that maybe the axis is taking up the space that's meant for the data so I added an extra 10px to the transform property, but it doesn't make any difference.
var GIST = "https://gist.githubusercontent.com/charisseysabel/f8f48fbf11b8a1b0d62cbe2d6bdc2aa6/raw/2ead1537adb822fbd59a666afd5334d525480a13/nano-2017.tsv"
var width = 1000,
height = 550,
margin = {top: 20, right: 30, bottom: 30, left: 4};
var y = d3.scaleLinear()
.range([height, 0]);
var yScale = d3.scaleLinear()
.range([height, 0]);
var xScale = d3.scaleLinear()
.range([0, width]);
var xAxis = d3.axisLeft(yScale);
var yAxis = d3.axisBottom(xScale);
var chart = d3.select(".chart")
.attr("width", width)
.attr("height", height);
chart.append("g")
.attr("transform", "translate(10, 0)")
.call(xAxis);
chart.append("g")
.attr("transform", "translate(0, 540)")
.call(yAxis);
d3.tsv(GIST, type, function(error, data) {
y.domain([0, d3.max(data, function(d) { return d.value; })]);
var barWidth = width / data.length;
var bar = chart.selectAll("g")
.data(data)
.enter().append("g")
.attr("transform", function(d, i) {
return "translate(" + ((i * barWidth) + 10) + ",0)"; }
);
bar.append("rect")
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); })
.attr("width", barWidth - 1);
bar.append("text")
.attr("x", (barWidth / 2) - 2)
.attr("y", function(d) { return y(d.value) + 3; })
.attr("dy", ".75em")
.text(function(d) { return d.value; });
});
function type(d) {
d.value = +d.value;
return d;
}
When you do this...
var bar = chart.selectAll("g").etc...
... you're selecting group elements that already exist in the SVG, which are the axes, and binding your data to them.
There are two easy solutions:
Move your code that creates the axes to the bottom of the d3.tsv, that is, after you have appended the bars.
Select something that doesn't exist, like
var bar = chart.selectAll(null).etc. To read more about the logic behind selectAll(null), have a look at my answer here.

D3 V3 Multi-line Chart - Issues appending lines to svg

I'm having issues getting D3v4 to show lines on a chart. I might be getting v3/v4 syntax confused.
I have the data nested as there are 5 lines.
// Chart Canvas Dimentions
var margin = {top: 20, right: 80, bottom: 30, left: 50};
var width = 900;
var height = 600;
// Time Parse
var parseTime = d3.time.format("%Y-%m-%d %H:%M:%S");
// Chart Axis Sizes
yAxisMax = Math.max.apply(Math, data.map(function(o){return o.value;})) * 1.1;
yAxisMin = Math.min.apply(Math, data.map(function(o){return o.value;})) - (this.yAxisMax * 0.1);
xAxisMax = width * 0.99;
console.log('yAxisMax: '+yAxisMax);
console.log('yAxisMin: '+yAxisMin);
console.log('xAxisMax: '+xAxisMax);
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.category10();
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
chartLine = d3.svg.line()
.x(function(d){ return x(parseTime(d.date)) })
.y(function(d){ return y(d.value) })
.interpolate("basis");
// Nest Entries by Name (Groups the Lines by Names - Seperate Entities)
var nestedData = d3.nest()
.key(function(d) { return d.name; })
.entries(data);
// D3 Chart - This is the Context to Work With
var context = d3.select("#chartContainer").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("id", "D3lineChart")
.attr("class", "D3EventScopeContainer")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Interactive HoverLine
var hoverLine = context
.append('g')
.attr('class', 'hoverLineGroup')
.append("line")
.attr('transform', 'translate(70,0)')
.attr('class', 'interactiveHoverLine hidden')
.attr("x1", 0).attr("x2", 0)
.attr("y1", 0).attr("y2", height);
// Loop through data
nestedData.forEach(function(d,i) {
console.dir(d)
console.dir(d.values)
// Add Line
context
.append('g')
.attr('class', 'lineGroup')
.append('path')
.attr('transform', 'translate(70,0)')
.attr('class', 'chartLinesGroup tag'+ d.key.replace(/\s+/g, '').replace('.', '').replace('-', '').toLowerCase())
.style("stroke", function() { return d.color = color(d.key); }) // Add the colours dynamically
.style("stroke-opacity", 1)
//.attr('d', chartLine(d.values))
.on("mouseover", function() {
d3.select(this)
.style("stroke-width", 7.5)
})
.on("mouseout", function() {
d3.select(this)
.style("stroke-width", 2.5)
});
});
It fails when I enable the line
.attr('d', chartLine(d.values))
This function must not be formated correctly to use the data.
The error I get is - related to date processing:
Any advice would be greatly appreciated.
I'm essentially trying to get the the lines to show on the chart.
thanks
*** I get around the error message by adding .parse to the end of the time format line:
// Time Parse
var parseTime = d3.time.format("%Y-%m-%d %H:%M:%S").parse;
Still nothing showing on the screen - div/svg has height/width set...
hummmmm
You need to read API;) But at first u must try :
var x = d3.scaleTime()
.range([0, width]);
var y = d3.scaleLinear()
.range([height, 0]);
var color = d3.scaleOrdinal(d3.schemeCategory10);
var xAxis = d3.axisBottom(x).tickFormat(d3.timeFormat("%H:%M:%S.%L"));
var yAxis = d3.axisLeft(y);
parseTime = d3.timeParse("%Y-%m-%d %H:%M:%S.%L");
chartLine = d3.line()
.curve(d3.curveMonotoneX)
.x(function(d){ return x(parseTime(d.date)) })
.y(function(d){ return y(d.value) });
Hope its help

d3 center tick and x-axis label when single value

I have the following d3 code:
var json = [
{
date: "05/17",
numTags: 23
}
];
d3.select('summary-graph').selectAll('*').remove();
var svg = d3.select("summary-graph"),
margin = {
top: 20,
right: 30,
bottom: 30,
left: 40
},
width = svg.attr("width") - margin.left - margin.right,
height = svg.attr("height") - margin.top - margin.bottom;
var parseTime = d3.timeParse("%m/%y");
var svg = d3.select("summary-graph").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 + ")");
// Get the data
var data = json;
// format the data
data.forEach(function (d) {
console.log(d);
d.date = parseTime(d.date);
d.numTags = +d.numTags;
});
// set the ranges
var xScale = d3.scaleTime()
.range([0, width])
.domain(d3.extent(data, function (d) {
return d.date;
}))
.nice();
var yScale = d3.scaleLinear()
.range([height, 0])
.domain([0, d3.max(data, function (d) {
return Math.max(d.numTags);
})])
.nice();
// define the 1st line
var tagLine = d3.line()
.x(function (d) {
return xScale(d.date);
})
.y(function (d) {
return yScale(d.numTags);
});
// Axes
var xAxis = d3.axisBottom()
.scale(xScale)
.ticks(json.length)
.tickSizeOuter(0)
.tickFormat(d3.timeFormat('%B %Y'));
var yAxis = d3.axisLeft().scale(yScale);
svg.append("path")
.data([data])
.attr("class", "line")
.style("stroke", "blue")
.attr("d", tagLine);
var points = svg.selectAll(".point")
.data(data)
.enter().append("svg:circle")
.attr("stroke", "green")
.attr("fill", function(d, i) { return "blue" })
.attr("cx", function(d, i) { return xScale(d.date) })
.attr("cy", function(d, i) { return yScale(d.numTags) })
.attr("r", function(d, i) { return 10 });
// Add the X Axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.style("font-size","14px");;
// Add the Y Axis
svg.append("g")
.call(yAxis);
Which produces the following visualization:
I'm trying to figure out how to center the tick mark and show the x-axis label when there is only 1 data point like this. At 2 data points, I don't love how it still sets the tick marks at the extreme ends of the x-axis. For 3 data points and above, it looks nice (thanks to .nice() it seems).
Any help?
Based on Gerado's response, I was able to get close. The last sticking point is that the left side of the X-axis now has the month (March) despite no data for that day.
Fixed:
changed .ticks(json.length) to .ticks(d3.timeMonth.every(1))
Since you are using only a single data point, your date scale has a domain in which the lower and upper values are the same:
[
Mon May 01 2017 00: 00: 00 GMT + 1000,
Mon May 01 2017 00: 00: 00 GMT + 1000
]
For putting that circle in the middle of the x axis you have to set different values for the scale's domain.
There are several ways for doing that. My proposed solution here involves verifying if the domain's values are the same...
if (xScale.domain()[0].getTime() == xScale.domain()[1].getTime()) {
... and, if they are, changing them. In this case, I'm subtracting one day from the lower limit and adding one day to the upper limit:
if (xScale.domain()[0].getTime() == xScale.domain()[1].getTime()) {
var dateLess = d3.timeDay.offset(xScale.domain()[0], -1);
var dateMore = d3.timeDay.offset(xScale.domain()[0], 1);
xScale.domain([dateLess, dateMore])
}
Check the result:
var json = [{
date: "05/17",
numTags: 23
}];
var margin = {
top: 20,
right: 30,
bottom: 30,
left: 40
},
width = 400,
height = 200;
var parseTime = d3.timeParse("%m/%y");
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 + ")");
// Get the data
var data = json;
// format the data
data.forEach(function(d) {
d.date = parseTime(d.date);
d.numTags = +d.numTags;
});
// set the ranges
var xScale = d3.scaleTime()
.range([0, width])
.domain(d3.extent(data, function(d) {
return d.date;
}))
.nice();
if (xScale.domain()[0].getTime() == xScale.domain()[1].getTime()) {
var dateLess = d3.timeDay.offset(xScale.domain()[0], -1);
var dateMore = d3.timeDay.offset(xScale.domain()[0], 1);
xScale.domain([dateLess, dateMore])
}
var yScale = d3.scaleLinear()
.range([height, 0])
.domain([0, d3.max(data, function(d) {
return Math.max(d.numTags);
})])
.nice();
// define the 1st line
var tagLine = d3.line()
.x(function(d) {
return xScale(d.date);
})
.y(function(d) {
return yScale(d.numTags);
});
// Axes
var xAxis = d3.axisBottom()
.scale(xScale)
.ticks(json.length)
.tickSizeOuter(0)
.tickFormat(d3.timeFormat('%B %Y'));
var yAxis = d3.axisLeft().scale(yScale);
svg.append("path")
.data([data])
.attr("class", "line")
.style("stroke", "blue")
.attr("d", tagLine);
var points = svg.selectAll(".point")
.data(data)
.enter().append("svg:circle")
.attr("stroke", "green")
.attr("fill", function(d, i) {
return "blue"
})
.attr("cx", function(d, i) {
return xScale(d.date)
})
.attr("cy", function(d, i) {
return yScale(d.numTags)
})
.attr("r", function(d, i) {
return 10
});
// Add the X Axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.style("font-size", "14px");;
// Add the Y Axis
svg.append("g")
.call(yAxis);
<script src="https://d3js.org/d3.v4.js"></script>
EDIT: As you asked in your edit, when you have two data values my solution will create additional ticks on the limits, which is the expected behaviour:
var json = [{
date: "05/17",
numTags: 23
}, {
date: "05/17",
numTags: 17
}];
var margin = {
top: 20,
right: 30,
bottom: 30,
left: 40
},
width = 400,
height = 200;
var parseTime = d3.timeParse("%m/%y");
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 + ")");
// Get the data
var data = json;
// format the data
data.forEach(function(d) {
d.date = parseTime(d.date);
d.numTags = +d.numTags;
});
// set the ranges
var xScale = d3.scaleTime()
.range([0, width])
.domain(d3.extent(data, function(d) {
return d.date;
}))
.nice();
if (xScale.domain()[0].getTime() == xScale.domain()[1].getTime()) {
var dateLess = d3.timeDay.offset(xScale.domain()[0], -1);
var dateMore = d3.timeDay.offset(xScale.domain()[0], 1);
xScale.domain([dateLess, dateMore])
}
var yScale = d3.scaleLinear()
.range([height, 0])
.domain([0, d3.max(data, function(d) {
return Math.max(d.numTags);
})])
.nice();
// define the 1st line
var tagLine = d3.line()
.x(function(d) {
return xScale(d.date);
})
.y(function(d) {
return yScale(d.numTags);
});
// Axes
var xAxis = d3.axisBottom()
.scale(xScale)
.ticks(json.length)
.tickSizeOuter(0)
.tickFormat(d3.timeFormat('%B %Y'));
var yAxis = d3.axisLeft().scale(yScale);
svg.append("path")
.data([data])
.attr("class", "line")
.style("stroke", "blue")
.attr("d", tagLine);
var points = svg.selectAll(".point")
.data(data)
.enter().append("svg:circle")
.attr("stroke", "green")
.attr("fill", function(d, i) {
return "blue"
})
.attr("cx", function(d, i) {
return xScale(d.date)
})
.attr("cy", function(d, i) {
return yScale(d.numTags)
})
.attr("r", function(d, i) {
return 10
});
// Add the X Axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.style("font-size", "14px");;
// Add the Y Axis
svg.append("g")
.call(yAxis);
<script src="https://d3js.org/d3.v4.js"></script>
There are several ways for removing those ticks. One of them is using tickValues:
.tickValues(data.map(function(d){ return d.date}))
Here is the demo:
var json = [{
date: "05/17",
numTags: 23
}, {
date: "05/17",
numTags: 17
}];
var margin = {
top: 20,
right: 30,
bottom: 30,
left: 40
},
width = 400,
height = 200;
var parseTime = d3.timeParse("%m/%y");
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 + ")");
// Get the data
var data = json;
// format the data
data.forEach(function(d) {
d.date = parseTime(d.date);
d.numTags = +d.numTags;
});
// set the ranges
var xScale = d3.scaleTime()
.range([0, width])
.domain(d3.extent(data, function(d) {
return d.date;
}))
.nice();
if (xScale.domain()[0].getTime() == xScale.domain()[1].getTime()) {
var dateLess = d3.timeDay.offset(xScale.domain()[0], -1);
var dateMore = d3.timeDay.offset(xScale.domain()[0], 1);
xScale.domain([dateLess, dateMore])
}
var yScale = d3.scaleLinear()
.range([height, 0])
.domain([0, d3.max(data, function(d) {
return Math.max(d.numTags);
})])
.nice();
// define the 1st line
var tagLine = d3.line()
.x(function(d) {
return xScale(d.date);
})
.y(function(d) {
return yScale(d.numTags);
});
// Axes
var xAxis = d3.axisBottom()
.scale(xScale)
.ticks(json.length)
.tickSizeOuter(0)
.tickValues(data.map(function(d){ return d.date}))
.tickFormat(d3.timeFormat('%B %Y'));
var yAxis = d3.axisLeft().scale(yScale);
svg.append("path")
.data([data])
.attr("class", "line")
.style("stroke", "blue")
.attr("d", tagLine);
var points = svg.selectAll(".point")
.data(data)
.enter().append("svg:circle")
.attr("stroke", "green")
.attr("fill", function(d, i) {
return "blue"
})
.attr("cx", function(d, i) {
return xScale(d.date)
})
.attr("cy", function(d, i) {
return yScale(d.numTags)
})
.attr("r", function(d, i) {
return 10
});
// Add the X Axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.style("font-size", "14px");;
// Add the Y Axis
svg.append("g")
.call(yAxis);
<script src="https://d3js.org/d3.v4.js"></script>

Overlapping Axis Ticks with Margin

My X-Axis tick number is scaling to the full width of the svg and not just the graph (without the margin area), so it overlaps.
http://i.stack.imgur.com/SHiIj.png The top image has margin so the labels are shown, the bottom one shows that with no margin, the ticks appear correctly
How can I make the X-axis ticks scale to the graph width instead of the svg width?
var margin = {top: 10, right: 0, bottom: 50, left: 0},
width = windowWidth * 0.28 - margin.left - margin.right,
height = 150 - margin.top - margin.bottom;
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.category10();
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(4);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(4);
var line = d3.svg.line()
.interpolate("basis")
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.trials); });
var svg = d3.select("#data-graph").insert("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var masterLabelList = ['Total','Completed']
d3.tsv("/static/data.tsv" + '?time=' + new Date().getTime(), function(error, data) {
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "date"; }));
data.forEach(function(d) {
d.date = new Date(+d.date);
});
var category = color.domain().map(function(name) {
return {
name: name,
values: data.map(function(d) {
return {date: d.date, trials: +d[name]};
})
};
});
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([
d3.min(category, function(c) { return d3.min(c.values, function(v) { return v.trials; }); }),
d3.max(category, function(c) { return d3.max(c.values, function(v) { return v.trials; }); })
]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.style("fill", "#999999")
.call(xAxis);
Set margin's right property to a value greater than 0.
Then replace
var x = d3.time.scale()
.range([0, width]);
with
var x = d3.time.scale()
.range([0, width - margin.right]);

Prevent d3.js area chart from dropping below 0 or x-Axis

What would be causing this chart to have a value appear below the x-axis (0:00)?
My data looks like this (no values less than zero):
[{"x":1341806400,"y":4},
{"x":1342411200,"y":0},
{"x":1343016000,"y":0},
{"x":1343620800,"y":7},
{"x":1344225600,"y":6},
{"x":1344830400,"y":73},
{"x":1345435200,"y":328},
{"x":1346040000,"y":0},
{"x":1346644800,"y":0},
{"x":1347249600,"y":0},
{"x":1347854400,"y":0},
{"x":1348459200,"y":11},
{"x":1349064000,"y":17},
{"x":1349668800,"y":0},
{"x":1350273600,"y":0}]
Rendered Chart
The above chart is rendered via:
var margin = {top: 20, right: 30, bottom: 30, left: 40};
var width = max_width - margin.left - margin.right;
var height = 300; // + margin.top + margin.bottom;
var height_offset = 100;
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var z = d3.scale.category20c();
var ticks_interval;
switch(this.period_type){
case "day":
ticks_interval = d3.time.days;
break;
case "week":
ticks_interval = d3.time.weeks;
break;
case "month":
ticks_interval = d3.time.months;
break;
case "year":
ticks_interval = d3.time.years;
break;
}
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(ticks_interval);
var yAxis = d3.svg.axis()
.scale(y)
.tickFormat(function(d){
return numeral(d).format("00:00").replace(/^0:/,""); })
.orient("left");
var stack = d3.layout.stack()
.offset("zero")
.values(function(d) { return d.values; })
.x(function(d) { return d.date; })
.y(function(d) { return d.value; });
var nest = d3.nest()
.key(function(d) { return d.key; });
var area = d3.svg.area()
.interpolate("cardinal")
.x(function(d) { return x(d.date); })
.y0(function(d) {return y(d.y0);})
.y1(function(d) { return y(d.y0 + d.y); });
var svg = d3.select(chart_dom_el)
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + height_offset)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var layers = stack(nest.entries(data));
x.domain(d3.extent(data, function(d){ return d.date; }));
y.domain([0,d3.max(data,function(d){
return d.y0+ d.y;
})]);
// re-map for formatted date
data = _.map(data,function(d){
return {date: d.date.format("MM/D"),value:d.value};
});
svg.selectAll(".layer")
.data(layers)
.enter().append("path")
.attr("class", "layer")
.attr("d", function(d) { return area(d.values); })
.style("fill", function(d, i) { return z(i); });
var x_axis_options = {x: 4, y: 9, rotate: 0};
if(data.length > 20){
x_axis_options = {x: -27, y: 8, rotate: -45};
}else if(data.length > 13){
x_axis_options = {y: -5, x: 27, rotate: 90};
}
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.attr("y", x_axis_options.y)
.attr("x", x_axis_options.x)
.attr("transform", "rotate("+(x_axis_options.rotate)+")");
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
This appears to have to do with the interpolation mode you used on the area generator - try changing from cardinal to linear, or some other area interpolation mode

Resources