使用javascript动态创建C#对象数组(使用ChartJs)

时间:2018-07-10 11:04:27

标签: javascript c# razor model-view-controller

我正在尝试使用多个数据集创建一个图表(使用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);
    }

在这里,我的数据点类型为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]))
}

Ps。我对javascript不太有经验,这是为什么我没有找到与我需要的东西相似的东西以寻求指导的原因。

编辑

我尝试了另一种方法:进行c#循环并在创建对象的地方执行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分配给我的数据集时,它将显示一个空图表。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

根据我的上一次编辑设法找到可行的解决方案: 在Controller上进行了一些小更改,这就是将我的一个Model模型(传递给View的那个模型)功能从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中的内容显示数据。

我希望这对处于同一职位的人有所帮助。