web-dev-qa-db-fra.com

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

Je suis un grand fan de la bibliothèque de graphiques d3.js de Mike Bostock: 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 affichant dans une fenêtre du navigateur Web. Cependant, j'ai compris que la bibliothèque d3.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 fonctionne pas.

Quelqu'un at-il essayé de développer ce type de déploiement de cartes d3.js? Vous avez une idée par où commencer pour avoir la solution la plus simple?

31
bobby

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 devrez vous assurer que le navigateur fonctionne en mode Normes IE9 comme indiqué ici .

Créez vos pages Web comme vous le feriez normalement. Accédez à ces fichiers à l'aide de webbrowser.navigate (en tant que fichiers du système de fichiers uniquement.)

Cela devrait fonctionner.

14
WiredPrairie

Nécromancement.

Vous pouvez le faire avec C # et .NET-Core sur tous les systèmes d'exploitation utilisant nodeJS.
Absolument aucun contrôle de 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 dans Startup.cs, ajoutez 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 
      });
}

Ajoutez 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");
}

Et 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 graphique d3 requis sans avoir besoin d'un navigateur compatible svg.

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

npm install -g npm

Vous pouvez également le faire dans une application en ligne de commande, juste là, vous devez configurer votre propre contrainer DI.

8
Stefan Steiger

Cherchait la même solution et est tombé sur Edge.js . Il peut être exécuté à partir de n'importe quelle application .NET 4.5 et installé via Nuget. Il ne nécessite pas que node.js soit installé mais vous aurez besoin de node pour installer D3 à l'aide de NPM. Assure-toi package-lock.json et le node_modules le dossier se trouve dans le même répertoire que le Edge.js fichier à l'exécution, ou installé globalement. Je viens de courir npm i d3-array de l'intérieur du \Edge dossier, puis a inclus les fichiers * .json et * .js, les définir sur le contenu et les copier dans le répertoire de sortie. Alors c'est aussi simple que:

class Program {
    public static async Task Start(int[] someArray) {
        var func = Edge.Func(@"
            var d3 = require('d3-array')
            return function (data, callback) {
                callback(null, 'D3 says: ' + d3.min(data));
            }
        ");
        Console.WriteLine(await func(someArray));
    }

    static void Main(string[] args) {
        Start(new int[] { 1, 2, 3, 4 }).Wait();
    }
} 

Les sorties: D3 says: 1

REMARQUE: dans .Net7.2, j'ai dû installer le Edge.Js.Binaries Package NuGet pour installer le dossier Edge à la racine du projet. Le Edge.Js package ne l'a pas fait, en 4.5 il l'a fait.

0
maeneak