2

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.

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 ?

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

I call DrawChart Action in PricePoint controller:

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

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

 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.

<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?

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

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 Answers 2

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

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

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 :

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.

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");

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; }

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]

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.

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 :)

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

Sign up to request clarification or add additional context in comments.

1 Comment

Great work man ! It work's :D Everything i did is: remove brackets from the data declaration as you said, very helpful. Thank you very much :)
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.

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...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.