使用wkhtmltopdf将D3图表转换为pdf

时间:2018-08-19 16:17:37

标签: javascript d3.js wkhtmltopdf django-wkhtmltopdf

我有几个D3图表,一个是基本的热图,其他则是甜甜圈图或条形图。使用wkhtmltopdf时,饼图,甜甜圈图和条形图都将以PDF格式显示,但我的热图不会显示。我不明白为什么不这样做。

这是一个工作的条形图(注意,我正在通过Django模板将数据传递到该图):

        <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>

这是不起作用的(简单的)热图:

<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>

此热图的渲染与我在浏览器窗口中所期望的完全相同,但是当我尝试使用django-wkhtmltopdf将其发送到PDF时,图像就不会出现。

请注意,<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>实际上位于html文件顶部的<head> ... </head>之内,但我包含在本地脚本中以表明我已包含它。两种图表以及许多其他图表都位于同一html页面中。热图是唯一未在wkhtmltopdf中呈现的图。

非常感谢您解释为什么不渲染(以及如何修复)

0 个答案:

没有答案