javascript - 在 javascript 中动态创建一个 C# 对象数组(使用 ChartJs)
问题描述
我正在尝试创建一个包含多个数据集的图表(使用 CharJs.js)并将其显示在我的 MVC 项目中。这个想法是不要手动预定义数据集,然后在我看来访问其中的每一个。这必须根据列表中有多少对象动态构建。
这是我的模型:
[DataContract]
public class DataPoint : IDataPoint
{
public DataPoint(string label, double y)
{
this.Label = label;
this.Y = y;
}
//Explicitly setting the name to be used while serializing to JSON.
[DataMember(Name = "label")]
public string Label { get; set; }
//Explicitly setting the name to be used while serializing to JSON.
[DataMember(Name = "y")]
public Nullable<double> Y { get; set; }
//public List<double> Y { get; set; }
}
我的控制器:
public async Task<ActionResult> ShowDetails(int ProductId, string PartId, string SupplierName, string fromSearchString, int? fromPage)
{
List<string> DbSupplierList = await _itScopeRepository.GetSupplierByPartId(Convert.ToInt32(PartId));
var ItScopeProduct = _itScopeRepository.GetProductById(ProductId);
ItScopeProduct.Supplier = SupplierName;
ItScopeProduct.SupplierList = DbSupplierList;
ViewBag.FromSearchString = fromSearchString;
ViewBag.FromPage = fromPage;
var obj = await CreateLineChart(DbSupplierList, PartId);
ItScopeProduct.DataPoints = obj;
return View("DetailsView", ItScopeProduct);
}
在我的例子中,DataPoints 是类型List<List<DataPoint>>
,并且列表正在我的视图中展开:
这是我的观点:
<!DOCTYPE HTML>
<html>
<head>
<script src="~/Scripts/jquery-1.7.1.js"></script>
<script type="text/javascript">
window.onload = function () {
var dataSecond = {
type: "line",
name:'@Html.Raw(JsonConvert.SerializeObject(Model.Supplier))',
showInLegend: true,
dataPoints: @Html.Raw(JsonConvert.SerializeObject(Model.DataPoints[0]))
};
var dataSecond2 = {
type: "line",
name:"Dexxit",
showInLegend: true,
dataPoints: @Html.Raw(JsonConvert.SerializeObject(Model.DataPoints[1]))
};
var chart = new CanvasJS.Chart("chartContainer", {
animationEnabled: true,
title: {
text: "Product price history"
},
axisY: {
includeZero: false
},
toolTip: {
shared: true
},
data: [dataSecond, dataSecond2]
});
chart.render();
}
</script>
</head>
<body>
<div id="chartContainer" style="height: 370px; width: 100%;"></div>
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
</body>
</html>
如您所见,现在我手动从列表中获取每个对象,我希望将其集成到一个循环中,在其中创建一个对象数组,然后将其传递给我的图表数据集。
我尝试过这样的事情:
var testing;
var listOfDataPoints = [];
for(var i = 0; i < @Model.DataPoints.Count; i++){
testing = {
type: "line",
name: '@Html.Raw(JsonConvert.SerializeObject(Model.Supplier))',
showInLegend: true,
dataPoints: @Html.Raw(JsonConvert.SerializeObject(Model.DataPoints[i]))
};
listOfDataPoints.push(testing);
}
但不幸的是,我无法将 javascript int 值传递给我的 C# 模型,因此使该解决方案无法使用。
现在我的问题是:是否可以遍历我的对象列表并创建 n 数量(基于我的列表中有多少项目)的 javascript 对象并将它们插入到数组中?
js obj 应具有以下结构:
var myDataset = {
type: "line",
name: '@Html.Raw(JsonConvert.SerializeObject(Model.Supplier))',
showInLegend: true,
dataPoints: @Html.Raw(JsonConvert.SerializeObject(Model.DataPoints[i]))
}
附言。我对 javascript 不是很有经验,这就是为什么我要寻求一些指导的原因,因为我没有找到与我需要的类似的东西。
编辑
我尝试了另一种方法:让 ac# 循环并在我创建对象的地方执行一个 javascript 函数。
var yest = [];
var listOfPoints = [];
function addMarker(supplier, datapo)
{
yest = {
type: "line",
name: "Dexxit",
showInLegend: true,
dataPoints: datapo
};
listOfPoints.push(yest);
}
@for(int i = 0; i < Model.DataPoints.Count; i++)
{
@:addMarker('@Html.Raw(JsonConvert.SerializeObject(Model.Supplier))', @Html.Raw(JsonConvert.SerializeObject(Model.DataPoints[i])));
}
但是当我将 listOfPoints 分配给我的数据集时,它会显示一个空图表。任何想法为什么?
解决方案
根据我上次的编辑设法找到一个可行的解决方案:对我的控制器进行了一些小改动,那就是将我的一个模型(传递给我的视图)函数从List<List<DataPoint>> DataPoints {get;set;}
`List>> DataPoint{get;set;}
我的新控制器:
public async Task<ActionResult> ShowDetails(int ProductId, string PartId, string SupplierName, string fromSearchString, int? fromPage)
{
List<string> DbSupplierList = await _itScopeRepository.GetSupplierByPartId(Convert.ToInt32(PartId));
var ItScopeProduct = _itScopeRepository.GetProductById(ProductId);
ItScopeProduct.Supplier = SupplierName;
ItScopeProduct.SupplierList = DbSupplierList;
ViewBag.FromSearchString = fromSearchString;
ViewBag.FromPage = fromPage;
var obj = await CreateLineChart(DbSupplierList, PartId);
List<KeyValuePair<string, List<IDataPoint>>> ConvertToInterface = new List<KeyValuePair<string, List<IDataPoint>>>();
foreach (var item in obj)
{
ConvertToInterface.Add(new KeyValuePair<string, List<IDataPoint>>(item.Key, item.Value.ToList<IDataPoint>()));
}
ItScopeProduct.DataPoints = ConvertToInterface;
return View("DetailsView", ItScopeProduct);
}
更新视图:
<!DOCTYPE HTML>
<html>
<head>
<script src="~/Scripts/jquery-1.7.1.js"></script>
<script type="text/javascript">
window.onload = function () {
var listOfDataPoints = [];
var MyObj;
function addMarker(supplier, datapo)
{
var yest = {
type: "line",
name: supplier,
showInLegend: true,
dataPoints: datapo
};
return yest;
}
@for(int i = 0; i < Model.DataPoints.Count; i++)
{
@:MyObj = addMarker('@Html.Raw(JsonConvert.SerializeObject(Model.DataPoints[i].Key))', @Html.Raw(JsonConvert.SerializeObject(Model.DataPoints[i].Value)));
@:listOfDataPoints.push(MyObj);
}
var chart = new CanvasJS.Chart("chartContainer", {
animationEnabled: true,
title: {
text: "Product price history"
},
axisY: {
includeZero: false
},
toolTip: {
shared: true
},
data: listOfDataPoints
});
chart.render();
}
</script>
</head>
<body>
<div id="chartContainer" style="height: 370px; width: 100%;"></div>
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
</body>
</html>
我的图表现在是动态构建的,它可以根据我的 Model.DataPoints 中的内容显示数据。
我希望这可以对处于相同位置的人有所帮助。