Comment intégrer d3.graphique js dans l'application C#?

Je suis un grand fan de D3 de Mike Bostock.bibliothèque de graphiques js: d3js.org.

Je voudrais l'utiliser pour afficher des graphiques dans une application C#. Net, mais je ne sais pas si c'est possible.

Cela peut être possible en générant des codes HTM + JS et en les rendant dans une fenêtre webbrowser. Cependant, j'ai compris d3.la bibliothèque js ne peut pas être utilisée localement sans serveur web (Cependant, je n'ai pas compris ce qui fonctionne sans serveur web et ce qui nécessite un serveur web), donc une solution simple ne le fait pas travail.

Quelqu'un a-t-il essayé de développer ce type de déploiement de d3.js graphiques? Avez-vous une idée sur où commencer, afin d'avoir la solution la plus simple?

23
demandé sur John Saunders 2012-08-27 01:51:10

2 réponses

Un serveur web n'est certainement pas nécessaire pour utiliser une bibliothèque JavaScript côté client comme d3.js.

Pour C#, vous devrez intégrer un contrôle de navigateur web (dans WindowsForms ou WPF).

Vous devez vous assurer que le navigateur fonctionne en mode Standard IE9 comme indiqué ici.

Créez vos pages web comme vous le feriez normalement. Accédez à eux en utilisant webbrowser.naviguer (comme des fichiers sur le système de fichiers.)

Cela devrait fonctionner.

11
répondu WiredPrairie 2012-08-28 12:39:45

Nécromancie.

Vous pouvez le faire avec C# et. net-Core sur tous les systèmes d'exploitation utilisant nodeJS.
Absolument aucun contrôle du navigateur requis.
Installez simplement JavaScript-Services avec nuget, puis installez d3, jsdom et svg2png dans nodejs:

npm install –save svg2png
npm install –save jsdom
npm install –save d3

Puis au démarrage.cs, ajouter NodeServices dans ConfigureServices

using Microsoft.AspNetCore.NodeServices;

public void ConfigureServices(IServiceCollection services)
{
      // services.AddMvc();

      // https://geeks.ms/clanderas/2016/10/18/asp-net-core-node-services-to-execute-your-nodejs-scripts/
      // https://blogs.msdn.microsoft.com/webdev/2017/02/14/building-single-page-applications-on-asp-net-core-with-javascriptservices/
      services.AddNodeServices( options => {
      // options.DebuggingPort 
      });
}

Ajouter un gestionnaire de sortie:

 public class AgeInfo
        {

            public string age;
            public int population;

            public AgeInfo(string prmAge, int prmPop)
            {
                this.age = prmAge;
                this.population = prmPop;
            }

        }


        // http://gunnarpeipman.com/2017/10/aspnet-core-node-d3js/
        public async Task<IActionResult> Chart([FromServices] INodeServices nodeServices)
        {
            var options = new { width = 400, height = 200 };

            var data = new[] {
                new { label = "Abulia", count = 10 },
                new { label = "Betelgeuse", count = 20 },
                new { label = "Cantaloupe", count = 30 },
                new { label = "Dijkstra", count = 40 }
            };

            List<AgeInfo> ls = new List<AgeInfo>();
            ls.Add( new AgeInfo("<5", 2704659));
            ls.Add( new AgeInfo("5-13", 4499890));
            ls.Add( new AgeInfo("14-17", 2159981));
            ls.Add( new AgeInfo("18-24", 3853788));
            ls.Add( new AgeInfo("25-44", 14106543));
            ls.Add( new AgeInfo("45-64", 8819342));
            ls.Add( new AgeInfo("≥65", 612463));


            // string markup = await nodeServices.InvokeAsync<string>("Node/d3Pie.js", options, data);

            string markup = await nodeServices.InvokeAsync<string>("Node/d3chart.js", options, ls);

            string html = @"<!DOCTYPE html>
<html>
<head><meta charset=""utf-8"" />
<style type=""text/css"">
.arc text 
{
  font: 10px sans-serif;
  text-anchor: middle;
}
.arc path 
{
  stroke: #fff;
}
</style>
</head>
<body>
    <img src=""" + markup + @""" />
</body>
</html>";

            return Content(html, "text/html");
        }

Puis ajoutez le JavaScript

// Include all modules we need
const svg2png = require("svg2png");
const { JSDOM } = require("jsdom");
const d3 = require('d3');



// https://bl.ocks.org/mbostock/3887235
module.exports = function (callback, options, data) {


    var dom = new JSDOM('<!DOCTYPE html><html><head><meta charset="utf-8" /></head><body><svg width="960" height="500"></svg></body></html>');
    var document = dom.window.document;
    dom.window.d3 = d3.select(dom.window.document);


    // callback(null, dom.window.document.body.innerHTML);


    var svg = dom.window.d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height"),
    radius = Math.min(width, height) / 2,
    g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");



    var color = d3.scaleOrdinal(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);

    var pie = d3.pie()
        .sort(null)
        .value(function (d) {
            return d.population;
        });


    var path = d3.arc()
        .outerRadius(radius - 10)
        .innerRadius(0);

    var label = d3.arc()
        .outerRadius(radius - 40)
        .innerRadius(radius - 40);

    /*
    var dataaa =
        [
            {
                age: "<5",
                population: 2704659
            },
            {
                age: "5-13",
                population: 4499890
            },
            {
                age: "14-17",
                population: 2159981
            },
            {
                age: "18-24",
                population: 3853788
            },
            {
                age: "25-44",
                population: 14106543
            }
            ,
            {
                age: "45-64",
                population: 8819342
            }
            ,
            {
                age: "≥65",
                population: 612463
            }
        ];
    */

        var arc = g.selectAll(".arc")
        .data(pie(data))
        .enter().append("g")
        .attr("class", "arc");

    arc.append("path")
        .attr("d", path)
        .attr("fill", function (d) {
            return color(d.data.age);
        });

    arc.append("text")
        .attr("transform", function (d) {
            return "translate(" + label.centroid(d) + ")";
        })
        .attr("dy", "0.35em")
        .text(function (d) {
            return d.data.age;
        });
    //});

    // var svgText = dom.window.document.body.outerHTML;
    // var svgText = dom.window.document.body.innerHTML;
    var svgText = dom.window.document.body.querySelector("svg").outerHTML
    // callback(null, svgText);

    // var svgText = dom.window.d3.select("svg").html();
    // svgText=process.version; // v8.6.0
    // svgText= JSON.stringify(process.versions); //
    // var pjson = require('./package.json'); svgText = pjson.version;
    // callback(null, svgText);
    // callback(null, JSON.stringify(  { width: width, height: height } ));

    // var buf = Buffer.from(svgText);
    // callback(null, JSON.stringify( buf ));
    // var output = svg2png.sync(buf, { width: width, height: height } );
    // callback(null, JSON.stringify( output ));
    //callback(null,  svgText);
    // callback(null,  'data:image/svg+xml;base64,' + Buffer.from(svgText).toString('base64'));


    svg2png(Buffer.from(svgText), { width: width, height: height })
        .then(buffer => 'data:image/png;base64,' + buffer.toString('base64') )
        .then(buffer => callback(null, buffer));

}

Cela devrait vous donner le D3-chart requis sans besoin d'un navigateur compatible svg.

Vous devrez peut-être mettre à jour npm avant de pouvoir (avec succès) installer des modules nodeJS.

npm install -g npm

Vous pouvez également le faire dans une application de ligne de commande, juste que vous devez configurer votre propre di contrainer.

4
répondu Stefan Steiger 2018-01-08 15:12:07