首先,我会说我非常精通C#,但是在JS&Nancy中几乎是一个新手。我试图将二维数组从C#.Net Framework控制台应用程序传递到位于http://visjs.org/docs/graph3d/的Graph3d包中。 Graph3d示例代码可以正常工作。我可以修改其JS来做一个简单的5x5数组,将所有数组值设置为2,但数组中间(2,2)的值是22。它按预期绘制图形:
以下是绘制以上图片的JS代码:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Graph 3D demo</title>
<style>
html, body {
font: 10pt arial;
padding: 0;
margin: 0;
width: 100%;
height: 100%;
}
#mygraph {
position: absolute;
width: 100%;
height: 100%;
}
</style>
<!-- for mobile devices like android and iphone -->
<meta name="viewport" content="target-densitydpi=device-dpi, width=device-width" />
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.21.0/vis.min.js"></script>
<script type="text/javascript">
var data = null;
var graph = null;
var request = new XMLHttpRequest();
request.open('GET', 'http://192.168.1.153:1234/', true);
request.onload = function () {
// Begin accessing JSON data here
//var data = JSON.parse(this.response);
console.log(this.response);
}
request.send();
// Called when the Visualization API is loaded.
function drawVisualization() {
// Create and populate a data table.
data = new vis.DataSet();
data.add([{x:0,y:0,z:2}]);
data.add([{x:0,y:1,z:2}]);
data.add([{x:0,y:2,z:2}]);
data.add([{x:0,y:3,z:2}]);
data.add([{x:0,y:4,z:2}]);
data.add([{x:1,y:0,z:2}]);
data.add([{x:1,y:1,z:2}]);
data.add([{x:1,y:2,z:2}]);
data.add([{x:1,y:3,z:2}]);
data.add([{x:1,y:4,z:2}]);
data.add([{x:2,y:0,z:2}]);
data.add([{x:2,y:1,z:2}]);
data.add([{x:2,y:2,z:22}]);
data.add([{x:2,y:3,z:2}]);
data.add([{x:2,y:4,z:2}]);
data.add([{x:3,y:0,z:2}]);
data.add([{x:3,y:1,z:2}]);
data.add([{x:3,y:2,z:2}]);
data.add([{x:3,y:3,z:2}]);
data.add([{x:3,y:4,z:2}]);
data.add([{x:4,y:0,z:2}]);
data.add([{x:4,y:1,z:2}]);
data.add([{x:4,y:2,z:2}]);
data.add([{x:4,y:3,z:2}]);
data.add([{x:4,y:4,z:2}]);
// specify options
var options = {
width: '100%',
height: '100%',
style: 'surface',
showPerspective: true,
showGrid: true,
showShadow: false,
keepAspectRatio: true,
verticalRatio: 0.5,
backgroundColor: {
strokeWidth: 0
}
};
// create our graph
var container = document.getElementById('mygraph');
graph = new vis.Graph3d(container, data, options);
}
</script>
</head>
<body onresize="graph.redraw();" onload="drawVisualization()">
<div id="mygraph"></div>
</body>
</html>
非常简单
但是,当我尝试将相同的5x5数组从C#通过Nancy发送到JS时,图片看起来并不相同。数据数组正确,已通过Firefox中的“控制台”窗口验证。这是错误的图片:
这是使用Nancy运行Web服务器并将数组传递给JS的C#代码:
using System;
using System.IO;
using System.Reflection;
using System.Text;
using Nancy;
using Nancy.ModelBinding;
using Nancy.Conventions;
using Nancy.Hosting.Self;
namespace test3x3graph
{
class Program
{
static void Main(string[] args)
{
//Start Nancy web server
Nancy.Json.JsonSettings.MaxJsonLength = int.MaxValue;
string nancyUri = "http://localhost:4143/";
NancyHost host = new NancyHost(new Uri(nancyUri));
host.Start();
Console.WriteLine("NancyFx is running on " + nancyUri);
Console.WriteLine("\nPress any key to exit");
Console.ReadKey();
}
}
public class CustomRootPathProvider : IRootPathProvider
{
public string GetRootPath()
{
return Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
}
}
public class CustomBootstrapper : DefaultNancyBootstrapper
{
protected override IRootPathProvider RootPathProvider
{
get { return new CustomRootPathProvider(); }
}
protected override void ConfigureConventions(NancyConventions conventions)
{
base.ConfigureConventions(conventions);
conventions.StaticContentsConventions.Add(
StaticContentConventionBuilder.AddDirectory("public", @"public")
);
}
}
public class SurfaceModel
{
public static string SurfaceData = string.Empty;
//public static double[,] SurfaceData;
//static constructor to generate sample data
static SurfaceModel()
{
const int size = 5;
double[,] data = new double[size, size];
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
data[i, j] = 2;
}
}
data[2, 2] = 22;
//SurfaceData = data;
//convert to string representation
StringBuilder sb = new StringBuilder();
sb.Append("[");
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
sb.Append("[");
sb.Append(i.ToString());
sb.Append(",");
sb.Append(j.ToString());
sb.Append(",");
sb.Append(data[i, j].ToString());
sb.Append("]");
if (j < size - 1)
sb.Append(",");
}
if (i < size - 1)
sb.Append(",");
}
sb.Append("]");
SurfaceData = sb.ToString();
}
}
public class TestModule : Nancy.NancyModule
{
public TestModule()
{
Get["/"] = args =>
{
SurfaceModel model = this.Bind<SurfaceModel>();
return View["surface", model];
};
}
}
}
最后,这是从C#接收表面模型的JS代码:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Graph3D test</title>
<style>
html, body {
font: 10pt arial;
padding: 0;
margin: 0;
width: 100%;
height: 100%;
}
#mygraph {
position: absolute;
width: 100%;
height: 100%;
}
</style>
<!-- for mobile devices like android and iphone -->
<meta name="viewport" content="target-densitydpi=device-dpi, width=device-width" />
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.21.0/vis.min.js"></script>
<script type="text/javascript">
var data = null;
var graph = null;
// inject surface model here...
var surfaceData = @Model.SurfaceData;
// Called when the Visualization API is loaded.
function drawVisualization() {
console.log(surfaceData);
// Create and populate a data table.
data = new vis.DataSet();
for(var x = 0; x < surfaceData.length; x++) {
for(var y = 0; y < surfaceData[x].length; y++) {
data.add([
{
x: x,
y: y,
z: surfaceData[x][y]
}
]);
}
}
// specify options
var options = {
width: '100%',
height: '100%',
style: 'surface',
showPerspective: true,
showGrid: true,
showShadow: false,
keepAspectRatio: true,
verticalRatio: 0.5,
backgroundColor: {
strokeWidth: 0
}
};
// create our graph
var container = document.getElementById('mygraph');
graph = new vis.Graph3d(container, data, options);
}
</script>
</head>
<body onresize="graph.redraw();" onload="drawVisualization()">
<div id="mygraph"></div>
</body>
</html>
该JS与有效的JS几乎完全相同;只有数据部分不同。所有Graph3d选项都是相同的,所以让我感到困惑的是图片不呈现相同的图像。
还要注意,在C#中,双精度数组在发送给JS之前已转换为字符串表示形式。当我尝试将其作为双精度数组传递时,生成的图片为空白。如果可以使用字符串表示形式找到解决方案,那就太好了。但是,能够避免中间步骤并将双精度数组直接传递给JS会更加清洁。
谢谢您的建议。
答案 0 :(得分:0)
使用Json.NET序列化程序,我能够使它工作。令我感到非常惊讶的是,JsonConvert.SerializeObject没有添加允许JSON.Parse正确无误地反序列化字符串的单引号。
无论如何,这是相关的C#代码:
//create a 1-dimensional array to send to Javascript.
//the first item is the number of rows; the 2nd item is the number of columns;
//the remaining items are the values from the 2-d array in row-major order
double[] data1d = new double[size*size + 2];
data1d[0] = data1d[1] = size;
int k = 2;
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
data1d[k++] = data[i, j];
}
}
SurfaceData = "'" + JsonConvert.SerializeObject(data1d) + "'";
这是相关的Javascript代码:
// inject surface model here.
// Model.Surface data is a 2-dimensional array stored in a 1-dimensional array as follows:
// Array item [0] is the number of rows. Array item [1] is the number of columns.
// The remaining array items are the values from the 2-d array in row-major order
var surfaceData = JSON.parse(@Model.SurfaceData);
// Called when the Visualization API is loaded.
function drawVisualization() {
console.log(surfaceData);
// Create and populate a data table.
data = new vis.DataSet();
var k = 2;
for(var x = 0; x < surfaceData[0]; x++) {
for(var y = 0; y < surfaceData[1]; y++) {
data.add([{x: x, y: y, z: surfaceData[k++]}]);
}
}
答案 1 :(得分:0)
您可以提供脚本路径或CSS路径
Get("/api/scripts/scripts.js", _ => return (Response)File.ReadAllText(scriptPath);
您基本上可以在此处进行任何操作来产生内容。