• # Générer des rapports PDF - la version over-engineered

    Posté par (site web personnel) . En réponse au lien JSPyBridge - utiliser des bibliothèques JavaScript en Python. Évalué à 4.

    Sur Windfit, on affiche plein de jolis graphes générés côté client avec d3js. Maintenant, on souhaite générer des rapports mensuels PDF pour les clients. Rapports qui contiendraient des jolies graphes. Sauf que les rapports seraient générés côtés backend (Python/Django) et que je n'ai absolument pas envie de re-implémenter les graphes dans une techno différentes. Du coup je cherche une solution pour réutiliser facilement nos super graphes JS côté backend.

    Ben avec JSPyBridge, j'ai réussi à faire un PoC presque pas dégueulasse :D

    Ma vue Django :

    from django.shortcuts import render
    import javascript
    import random
    def scatter_svg_view(request):
     # Generate some points
     points = [{
     "x": random.gauss(0.5, 0.3),
     "y": random.gauss(0.5, 0.2)
     } for _ in range(800)]
     # Da JS part
     js = "points = " + str(points) + "\n"
     js += """\
    const jsdom = await import("jsdom")
    const d3 = await import("d3")
    // Create the SVG node
    const dom = new jsdom.JSDOM(`<svg width="800" height="600"></svg>`);
    let svg = d3.select(dom.window.document).select("svg")
    svg.attr("viewBox", [0, 0, 800, 600])
    // Add debug background
    svg.append("rect",)
     .attr("width", 800)
     .attr("height", 600)
     .attr("fill", "magenta")
    // Draw the points
    svg.selectAll(".cf-point")
     .data(points)
     .join(enter => enter.append("circle"), update => update, exit => exit.remove())
     .attr("cx", p => p.x * 800)
     .attr("cy", p => p.y * 600)
     .attr("r", 4)
     .attr("fill", "green")
    return svg.node().outerHTML
     """
     # Generate the SVG by executing the JS
     svg = javascript.eval_js(js)
     # Render the final page 
     return render(request, "chartpdf/scatter.html", {"svg": svg})

    Le template

    <!DOCTYPE html>
    <html lang="en">
    <head>
     <meta charset="UTF-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>Document</title>
    </head>
    <body>
     {{ svg|safe }}
    </body>
    </html>

    Et pouf, j'ai une page contenant mon SVG généré par D3 mais côté backend.

    Et on me signale dans l'oreillette que je ferais mieux de me tourner directement vers nodejs pour ça pultôt que de passer par JSPyBridge.