Reputation: 7204
I have a D3 area chart which is being drawn just as I want it. I have tried to make it resize with the window. It resizes correctly horizontally, but vertically it seems to be set based on its original height. This is using Safari 9.0.2. It's difficult to describe what its doing so here are some screenshots:
Here is my code:
<html>
<meta charset="utf-8">
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
<style>
#graph
{
width: 100%;
height: 100%;
position: absolute;
}
</style>
<body>
<svg id="graph"></svg>
<script>
var width = parseInt(d3.select("#graph").style("width"));
var height = parseInt(d3.select("#graph").style("height"));
var parseDate = d3.time.format("%d-%b-%y").parse;
var xScale = d3.time.scale()
.range([0, width]);
var yScale = d3.scale.linear()
.range([height, 0]);
var actual = d3.svg.area()
.x(function(d) { return xScale(d.date); })
.y0(height)
.y1(function(d) { return yScale(d.actual); });
var svg = d3.select("#graph")
function resize()
{
width = parseInt(d3.select("#graph").style("width"))
height = parseInt(d3.select("#graph").style("height"));
xScale.range([0, width]);
yScale.range([height, 0]);
svg.selectAll("#actual")
.attr("d", actual);
}
d3.select(window).on('resize', resize);
d3.csv("areachart.csv", function(error, data)
{
data.forEach(function(d, i)
{
d.date = parseDate(d.date);
d.actual = +d.actual;
});
xScale.domain(d3.extent(data, function(d) { return d.date; }));
yScale.domain([0, d3.max(data, function(d) { return d.actual; })]);
svg.append("path")
.attr("id", "actual")
.datum(data)
.attr('fill', 'red')
.attr("d", actual);
});
</script>
</body>
</html>
Here is the areachart.csv:
date,actual
1-Jan-16,400
1-Feb-16,500
1-Mar-16,634
1-Apr-16,408
1-May-16,185
1-Jun-16,500
1-Jul-16,467
1-Aug-16,456
1-Sep-16,900
1-Oct-16,108
1-Nov-16,200
1-Dec-16,466
Does anyone know how to fix this please? Thanks. Andrew.
Upvotes: 1
Views: 1153
Reputation: 7204
Thank you fengshui for your help. I finally got it working. Here is my full answer:
<html>
<meta charset="utf-8">
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
<style>
#graph
{
width: 100%;
height: 100%;
position: absolute;
}
</style>
<body>
<svg id="graph"></svg>
<script>
var width = parseInt(d3.select("#graph").style("width"));
var height = parseInt(d3.select("#graph").style("height"));
var parseDate = d3.time.format("%d-%b-%y").parse;
var xScale = d3.time.scale()
.range([0, width]);
var yScale = d3.scale.linear()
.range([height, 0]);
function actualArea()
{
var actual = d3.svg.area()
.x(function(d) { return xScale(d.date); })
.y0(height)
.y1(function(d) { return yScale(d.actual); });
return actual
}
var svg = d3.select("#graph")
function resize()
{
width = parseInt(d3.select("#graph").style("width"))
height = parseInt(d3.select("#graph").style("height"));
xScale.range([0, width]);
yScale.range([height, 0]);
svg.selectAll("#actual")
.attr("d", actualArea());
}
d3.select(window).on('resize', resize);
d3.csv("areachart.csv", function(error, data)
{
data.forEach(function(d, i)
{
d.date = parseDate(d.date);
d.actual = +d.actual;
});
xScale.domain(d3.extent(data, function(d) { return d.date; }));
yScale.domain([0, d3.max(data, function(d) { return d.actual; })]);
svg.append("path")
.attr("id", "actual")
.datum(data)
.attr('fill', 'red')
.attr("d", actualArea());
});
</script>
</div>
</body>
Upvotes: 0
Reputation: 1563
While resizing, it seems to be set based on its original height vertically is because the svg area setting is not updated in resize
function:
svg.selectAll("#actual")
.attr("d", actual);
Here, the function used to draw d
is still using the initial height:
var actual = d3.svg.area()
.x(function(d) { return xScale(d.date); })
.y0(height) // initial height
.y1(function(d) { return yScale(d.actual); });
Try to include height updating in resize function should work.
Upvotes: 2