I have several D3 charts, one a basic Heat Map and the others things like Donut Chart or Bar Chart. The Pie, Donut and Bar charts will all show in a PDF when using wkhtmltopdf, but my Heat Map will not. I cannot understand why not.
Here is a working Bar Chart (note, I am passing data to the chart through a Django Template):
<div id="duelChart"></div>
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script>
var data = [
{ "name": "Stat 5", "value": {{ stat.duel_defensive_won|default:0 }}, },
{ "name": "Stat 4", "value": {{ stat.duel_offensive_won|default:0 }}, },
{ "name": "Stat 3", "value": {{ stat.aerial_duels_won|default:0 }}, },
{ "name": "Stat 2", "value": {{ stat.ground_duels_won|default:0 }}, },
{ "name": "Stat 1", "value": {{ stat.duel_won|default:0 }}, },];
var margin = { top: 15, right: 25, bottom: 15, left: 60 };
var width = 400 - margin.left - margin.right,
height = 250 ;
var svg = d3.select("#duelChart").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 + ")");
var x = d3.scale.linear()
.range([0, width])
.domain([0, d3.max(data, function (d) {
return d.value;
})]);
var y = d3.scale.ordinal()
.rangeRoundBands([height, 0], .1)
.domain(data.map(function (d) {
return d.name;
}));
//make y axis to show bar names
var yAxis = d3.svg.axis()
.scale(y)
//no tick marks
.tickSize(0)
.orient("left");
var gy = svg.append("g")
//.attr("class", "y axis")
//.call(yAxis)
var bars = svg.selectAll(".bar")
.data(data)
.enter()
.append("g")
//append rects
bars.append("rect")
.attr("class", "bar")
.attr("y", function (d) {
return y(d.name);
})
.attr("height", y.rangeBand())
.attr("x", 0)
.attr("width", function (d) {
return x(d.value);
});
//add a value label on the left of each bar
bars.append("text")
.attr("class", "label")
//y position of the label is halfway down the bar
.attr("y", function (d) {
return y(d.name) + y.rangeBand() / 2 + 4;
})
//x position is 3 pixels to the right of the bar
//.attr("x", function (d) {
// return x(d.value) + 3;
//})
.style('fill', 'white')
.text(function (d) {
return d.name;
});
</script>
Here is the not working (simple) Heat Map:
<div id="heatMap" style="margin-left:12px"></div>
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script>
data = [];
{% for column in heatmap.gridData %}
{% for row in column %}
data.push({ "week": {{ forloop.counter0 }} , "day" : {{ forloop.parentloop.counter0 }}, "value": {{ row }} }, );
{% endfor %}
{% endfor %}
var colorDomain = d3.extent(data, function (d) {
return d.value;
});
var colorScale = d3.scale.linear()
.domain(colorDomain)
.range(["lightblue", "blue"]);
var svg = d3.select("#heatMap")
.append("svg")
.attr("width", 835)
.attr("height", 535)
.append("g")
.attr("transform", "translate(" + 0 + "," + 0 + ")");
var rectangles = svg.selectAll("rect")
.data(data)
.enter()
.append("g");
rectangles
.append('rect')
.attr("x", function (d) {
return d.day * 41;
})
.attr("y", function (d) {
return d.week * 41;
})
.attr("width", 42)
.attr("height", 41).
style("fill", function (d) {
return colorScale(d.value);
});
</script>
This Heat Map renders exactly as I would expect in the browser window, but when I try and send it to a PDF using django-wkhtmltopdf, the image doesn't come in.
Please note <script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
is actually within the <head> ... </head>
at the top of the html file but I included within the local script to show I had included it. Both charts, along with many others are in the same html page. The Heat Map is the only one not rendering in wkhtmltopdf.
Any help explaining why it is not rendering (and how to fix) would be very much appreciated