如何在MVC中实现图表的动态数据?

时间:2022-02-02 14:30:02

Im new in ASP.NET MVC, im doing on my own project and i have some problems. I want to draw line chart from with data from database.

我在ASP。NET MVC,我正在做我自己的项目,我有一些问题。我想用数据库中的数据绘制折线图。

I hope you will understend me (bad english, sorry):

我希望你能理解我(不好的英语,对不起):

I have table of metals, after i click on specific one, i want to see chart that show me price of metal by date.

我有金属的表格,在我点击特定的表格后,我想看到图表,显示金属的价格日期。

For example, i click on Copper;

例如,我点击铜;

PricePoint is my Controller, wich action shoud i call here ?

PricePoint是我的控制器,我需要在这里调用吗?

<a href="@Url.Action("DrawChart", "PricePoint", new { id = item.ID })">@Html.DisplayFor(modelItem => item.name)</a>

I call DrawChart Action in PricePoint controller:

我在PricePoint controller中调用DrawChart动作:

public ActionResult DrawChart()
            {
    return View();
           }

In same controlller i create action that add data from database to json and return it.

在同一控制器中,我创建了将数据从数据库添加到json并返回的操作。

 public ActionResult Statistics(int ?id) {
        // here i pull data from database to stats 
        return Json(stats,JsonRequestBehavior.AllowGet);
    }

This is my view page where i want to show chart, DrawChart.cshtml file.

这是我的视图页面,我想在这里显示图表。cshtml文件。

<script type="text/javascript">
    $.get('@Url.Action("Statistics")', function(result){
        new Morris.Line({
            // ID of the element in which to draw the chart.
            element: 'myfirstchart',
            // Chart data records -- each entry in this array corresponds to a point on
            // the chart.
            data: [
             result
            ],
            // The name of the data record attribute that contains x-values.
            xkey: 'year',
            // A list of names of data record attributes that contain y-values.
            ykeys: ['value'],
            // Labels for the ykeys -- will be displayed when you hover over the
            // chart.
            labels: ['Value']
        });
    });


</script>

When i click on metal, DrawChart action return view DrawChart.cshtml, then JavaScript run Statistics function and populate data for chart, is that how this works?

当我点击金属,绘制图动作返回视图绘制图。cshtml,然后JavaScript运行统计函数并为图表填充数据,这是如何工作的?

I have blank page, with no result, when i type in url: http://localhost:50101/PricePoint/DrawChart When url is next, i see json data from database: http://localhost:50101/PricePoint/Statistics

当我输入url: http://localhost:50101/PricePoint/DrawChart(下一个url)时,我有一个空页,但没有结果,我看到了来自数据库的json数据:http://localhost:50101/PricePoint/Statistics

I dont know where is problem. When i put example data in script, like this

我不知道哪里有问题。当我在脚本中放入示例数据时,就像这样

data: [
      { year: '2008', value: 20 },
      { year: '2009', value: 10 },
      { year: '2010', value: 5 },
      { year: '2011', value: 5 },
      { year: '2012', value: 20 }
    ],

i see line chart as expected. Again, sorry for bad english, hope you can help me and i hope you understend my question.

我看到了预期的线图。再次,很抱歉英语不好,希望你能帮助我,我希望你能理解我的问题。

2 个解决方案

#1


1  

I had a play with it and I managed to display the chart just fine. Here are a few things to watch out for that may be the cause of your problem:

我用它玩了一会儿,我设法把图表显示得很好。以下是一些你需要注意的事情,它们可能是造成你的问题的原因:

1) your call to $.get('@Url.Action("Statistics")' is not passing in an id though you declared one on your action public ActionResult Statistics(int ?id). Considering it's nullable maybe you are prepared to serve a default set of data if no id is passed, but thought I'd mention in case that is what's affecting the logic of your database retrieval and affecting the results returned

1)您对$.get(“@Url.Action”(“Statistics”)的调用没有传入id,但您在action public ActionResult Statistics(int ?id)上声明了id。考虑到它是可空的,如果没有传递id,那么您可能准备提供一组默认的数据,但是我想如果这影响了数据库检索的逻辑并影响返回的结果,那么我应该提到这一点

2) I noticed that your link to the DrawChart action passed in new { id = item.ID } however this not captured on the server-side since your DrawChart action is missing the parameter, it should be something like : public ActionResult DrawChart(id). I understand this could've been for the sake of simplifying it just to post here and may not affect anything but thought I'd point it out

2)我注意到您在new {id = item中传递到DrawChart动作的链接。但是,由于您的DrawChart操作缺少参数,所以在服务器端没有捕捉到这一点,应该是这样的:public ActionResult DrawChart(ID)。我理解这可能是为了简化它只是为了在这里发布,可能不会影响任何东西,但我想我应该指出来

3) Be careful about what you are returning from the MVC action. The stats object in return Json(stats,JsonRequestBehavior.AllowGet); should be a C# array containing the properties value and year for each object in the array, so something like :

3)要注意从MVC动作返回的内容。返回Json中的stats对象(stats、JsonRequestBehavior.AllowGet);应该是一个c#数组,包含数组中每个对象的属性值和年份,因此如下:

new[] {new Entry() {value = 20, year = 2008}, new Entry() {value = 10, year = 2009}};

If you just pass a string to the return Json() statement it won't work properly since it'll think it's just one long json string not a json array object.

如果您只是将一个字符串传递给return Json()语句,它将无法正常工作,因为它会认为它只是一个长Json字符串,而不是一个数组Json对象。

If you want to return a string rather than an actual serialized c# collection then you can use something like : return Content(dataString, "application/json");

如果您想返回一个字符串,而不是实际的序列化c#集合,那么您可以使用如下内容:return Content(dataString,“application/json”);

4) Case matters! Make sure that the json returned contains properties with names of year and value for each entry just as you declared in your morris object on the xkey and ykey values. This can be quite a subtle trap since return Json() will serialize your json objects exactly as they are declared in your classes and while the tendency in javascript code is to start variables and properties with lower-case in .Net properties are usually declared with upper-case such as public int Year { get; set; }

4)情况下问题!请确保返回的json包含具有年份名称和每个条目的值的属性,就像您在xkey和ykey值中声明的morris对象中声明的那样。这可能是相当微妙的陷阱,因为返回Json()将序列化Json对象一样他们在类声明,而趋势javascript代码开始变量和属性在。net与小写属性通常用大写,如公共声明int年{得到;设置;}

Conclusion: I got it working by returning this code :

结论:我通过返回代码使它工作:

 public ActionResult Statistics(int ?id) {
       var data = new[] {new Entry() {value = 20, year = 2008}, new Entry() {value = 10, year = 2009}};

            return Json(data,JsonRequestBehavior.AllowGet);
    }

And on your Morris initialization code remove the array brackets from the data declartion so data : result and not data : [result]

在Morris初始化代码中从数据声明中删除数组括号数据:result而不是data: [result]

Your first step to troubleshoot this is to look at what your Statistics method is returning. You can do this really easily by testing your web site in Chrome, for instance, and hitting F12 then choose the Network tab. Then Ctrl+F5 the page and find the call to the server in the results pane. Click on it and then choose Response and keep troubleshooting your method till it returns what you need.

解决这一问题的第一步是查看统计方法返回的内容。例如,你可以在Chrome中测试你的网站,点击F12,然后选择Network选项卡。然后在“结果”窗格中按Ctrl+F5找到对服务器的调用。单击它,然后选择Response并继续对方法进行故障排除,直到它返回您需要的内容。

If the data is in a wrong format and doesn't contain the keys that Morris expects Morris will throw an error saying Uncaught TypeError: Cannot read property 'match' of undefined . Keep trying till you make that go away and hopefully you should see your graph :)

如果数据格式错误,且不包含Morris期望Morris抛出的键,则会出现一个错误,表示未捕获的TypeError:无法读取未定义的属性“match”。继续尝试,直到你把它去掉,希望你能看到你的图表:)

PS: one last thing, I'd wrap the Morris init code in a $(document).ready() call

最后一件事,我将把Morris init代码封装在一个$(document).ready()调用中

#2


0  

When i send data (values and dates) from function (manualy input), everything is ok, json file is populeted god, and i see chart, but when i send data from database, there is no chart but i see that json file is also populeted.

当我从函数(手工输入)发送数据(值和日期)时,一切都没问题,json文件是流行的,我看到了图表,但是当我从数据库发送数据时,没有图表,但我看到json文件也是流行的。

Here is code:

下面是代码:

  public class YearlyStat
    {
        public string year { get; set; }
        public double value { get; set; }
    }

public ActionResult Statistics(int? id)
    {
        //var result = db.pricepoints.Where(r => r.commodityID.Equals(id));
        var items = from item in db.pricepoints
                    where (item.commodityID == id)
                    select item;

        var stats = new List<YearlyStat>();

        foreach (var item in items)
        {
            stats.Add(new YearlyStat
            {
                year = item.date_of_price.ToShortDateString(),
                value = item.value
            });

        }
        //but this work's
        //string s = "2.2.2002";
        //double v = 20.20;
        //stats.Add(new YearlyStat { year = s, value = v });
        //or
        //stats.Add(new YearlyStat { year = "2.2.2002", value = 20.20 });

        return Json(stats, JsonRequestBehavior.AllowGet);
    }

Types are string and double in both cases...

在这两种情况下,类型都是string和double。

#1


1  

I had a play with it and I managed to display the chart just fine. Here are a few things to watch out for that may be the cause of your problem:

我用它玩了一会儿,我设法把图表显示得很好。以下是一些你需要注意的事情,它们可能是造成你的问题的原因:

1) your call to $.get('@Url.Action("Statistics")' is not passing in an id though you declared one on your action public ActionResult Statistics(int ?id). Considering it's nullable maybe you are prepared to serve a default set of data if no id is passed, but thought I'd mention in case that is what's affecting the logic of your database retrieval and affecting the results returned

1)您对$.get(“@Url.Action”(“Statistics”)的调用没有传入id,但您在action public ActionResult Statistics(int ?id)上声明了id。考虑到它是可空的,如果没有传递id,那么您可能准备提供一组默认的数据,但是我想如果这影响了数据库检索的逻辑并影响返回的结果,那么我应该提到这一点

2) I noticed that your link to the DrawChart action passed in new { id = item.ID } however this not captured on the server-side since your DrawChart action is missing the parameter, it should be something like : public ActionResult DrawChart(id). I understand this could've been for the sake of simplifying it just to post here and may not affect anything but thought I'd point it out

2)我注意到您在new {id = item中传递到DrawChart动作的链接。但是,由于您的DrawChart操作缺少参数,所以在服务器端没有捕捉到这一点,应该是这样的:public ActionResult DrawChart(ID)。我理解这可能是为了简化它只是为了在这里发布,可能不会影响任何东西,但我想我应该指出来

3) Be careful about what you are returning from the MVC action. The stats object in return Json(stats,JsonRequestBehavior.AllowGet); should be a C# array containing the properties value and year for each object in the array, so something like :

3)要注意从MVC动作返回的内容。返回Json中的stats对象(stats、JsonRequestBehavior.AllowGet);应该是一个c#数组,包含数组中每个对象的属性值和年份,因此如下:

new[] {new Entry() {value = 20, year = 2008}, new Entry() {value = 10, year = 2009}};

If you just pass a string to the return Json() statement it won't work properly since it'll think it's just one long json string not a json array object.

如果您只是将一个字符串传递给return Json()语句,它将无法正常工作,因为它会认为它只是一个长Json字符串,而不是一个数组Json对象。

If you want to return a string rather than an actual serialized c# collection then you can use something like : return Content(dataString, "application/json");

如果您想返回一个字符串,而不是实际的序列化c#集合,那么您可以使用如下内容:return Content(dataString,“application/json”);

4) Case matters! Make sure that the json returned contains properties with names of year and value for each entry just as you declared in your morris object on the xkey and ykey values. This can be quite a subtle trap since return Json() will serialize your json objects exactly as they are declared in your classes and while the tendency in javascript code is to start variables and properties with lower-case in .Net properties are usually declared with upper-case such as public int Year { get; set; }

4)情况下问题!请确保返回的json包含具有年份名称和每个条目的值的属性,就像您在xkey和ykey值中声明的morris对象中声明的那样。这可能是相当微妙的陷阱,因为返回Json()将序列化Json对象一样他们在类声明,而趋势javascript代码开始变量和属性在。net与小写属性通常用大写,如公共声明int年{得到;设置;}

Conclusion: I got it working by returning this code :

结论:我通过返回代码使它工作:

 public ActionResult Statistics(int ?id) {
       var data = new[] {new Entry() {value = 20, year = 2008}, new Entry() {value = 10, year = 2009}};

            return Json(data,JsonRequestBehavior.AllowGet);
    }

And on your Morris initialization code remove the array brackets from the data declartion so data : result and not data : [result]

在Morris初始化代码中从数据声明中删除数组括号数据:result而不是data: [result]

Your first step to troubleshoot this is to look at what your Statistics method is returning. You can do this really easily by testing your web site in Chrome, for instance, and hitting F12 then choose the Network tab. Then Ctrl+F5 the page and find the call to the server in the results pane. Click on it and then choose Response and keep troubleshooting your method till it returns what you need.

解决这一问题的第一步是查看统计方法返回的内容。例如,你可以在Chrome中测试你的网站,点击F12,然后选择Network选项卡。然后在“结果”窗格中按Ctrl+F5找到对服务器的调用。单击它,然后选择Response并继续对方法进行故障排除,直到它返回您需要的内容。

If the data is in a wrong format and doesn't contain the keys that Morris expects Morris will throw an error saying Uncaught TypeError: Cannot read property 'match' of undefined . Keep trying till you make that go away and hopefully you should see your graph :)

如果数据格式错误,且不包含Morris期望Morris抛出的键,则会出现一个错误,表示未捕获的TypeError:无法读取未定义的属性“match”。继续尝试,直到你把它去掉,希望你能看到你的图表:)

PS: one last thing, I'd wrap the Morris init code in a $(document).ready() call

最后一件事,我将把Morris init代码封装在一个$(document).ready()调用中

#2


0  

When i send data (values and dates) from function (manualy input), everything is ok, json file is populeted god, and i see chart, but when i send data from database, there is no chart but i see that json file is also populeted.

当我从函数(手工输入)发送数据(值和日期)时,一切都没问题,json文件是流行的,我看到了图表,但是当我从数据库发送数据时,没有图表,但我看到json文件也是流行的。

Here is code:

下面是代码:

  public class YearlyStat
    {
        public string year { get; set; }
        public double value { get; set; }
    }

public ActionResult Statistics(int? id)
    {
        //var result = db.pricepoints.Where(r => r.commodityID.Equals(id));
        var items = from item in db.pricepoints
                    where (item.commodityID == id)
                    select item;

        var stats = new List<YearlyStat>();

        foreach (var item in items)
        {
            stats.Add(new YearlyStat
            {
                year = item.date_of_price.ToShortDateString(),
                value = item.value
            });

        }
        //but this work's
        //string s = "2.2.2002";
        //double v = 20.20;
        //stats.Add(new YearlyStat { year = s, value = v });
        //or
        //stats.Add(new YearlyStat { year = "2.2.2002", value = 20.20 });

        return Json(stats, JsonRequestBehavior.AllowGet);
    }

Types are string and double in both cases...

在这两种情况下,类型都是string和double。