我是Mike Bostock的d3.js图表库d3js.org的铁杆粉丝。
我想用它在C# .Net应用程序中显示图表,但我不知道这是否可行。
可以通过生成HTM+JS代码并将其呈现在may浏览器窗口中来实现。然而,我知道d3.js库不能在没有work服务器的情况下在本地使用(然而我不知道没有work服务器什么工作,什么需要work服务器),因此简单的解决方案是行不通的。
有没有人尝试过开发d3.js图表的那种部署?为了得到最简单的解决方案,你有从哪里开始的想法吗?
发布于 2012-08-28 20:39:45
web服务器绝对不需要使用像d3.js这样的客户端JavaScript库。
对于C#,您需要嵌入一个web浏览器控件(在WindowsForms或WPF中)。
您需要确保浏览器在here所示的IE9标准模式下工作。
像平常一样创建你的网页。使用webbrowser.navigate导航到它们(作为文件系统上的文件)。
这应该是可行的。
发布于 2018-01-08 23:12:08
亡灵法术。
在所有使用nodeJS的操作系统上,您都可以使用C#和.NET-Core来实现这一点。
绝对不需要浏览器控件。
只需使用nuget安装JavaScript-Services,然后在nodejs中安装d3、jsdom和svg2png:
npm install –save svg2png
npm install –save jsdom
npm install –save d3
然后在Startup.cs中,在ConfigureServices中添加NodeServices
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
});
}
添加输出处理程序:
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");
}
然后添加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));
}
这将为您提供所需的d3图表,而不需要兼容svg的浏览器。
您可能需要更新npm,然后才能(成功)安装任何nodeJS模块。
npm install -g npm
您也可以在命令行应用程序中执行此操作,然后您需要设置自己的DI contrainer。
发布于 2019-04-01 20:35:43
也在寻找同样的解决方案,结果偶然发现了edge.js。它可以从任何.NET 4.5应用程序运行,并通过Nuget安装。它不需要安装node.js,但您需要使用NPM来安装D3。确保package-lock.json
和node_modules
文件夹在运行时与edge.js
文件位于同一目录中,或者是全局安装的。我只是从\edge
文件夹中运行npm i d3-array
,然后包含*.json和*.js文件,将它们设置为content并复制到输出目录。然后它就像这样简单:
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();
}
}
输出:D3 says: 1
注意:在.Net7.2中,我必须安装Edge.Js.Binaries
NuGet包才能在项目根目录中安装边缘文件夹。Edge.Js
包没有做到这一点,在4.5中做到了这一点。
https://stackoverflow.com/questions/12134200
复制相似问题