首页 > 解决方案 > 在 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 分配给我的数据集时,它会显示一个空图表。任何想法为什么?

标签: javascriptc#razormodel-view-controller

解决方案


根据我上次的编辑设法找到一个可行的解决方案:对我的控制器进行了一些小改动,那就是将我的一个模型(传递给我的视图)函数从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 中的内容显示数据。

我希望这可以对处于相同位置的人有所帮助。


推荐阅读