0

I'm struggling with dynamic data, C# MVC and Google Charts for a while now. What I try to achieve is reading out a database file and create a Google chart for each group.

I saw an example like http://www.aspdotnet-pools.com/2014/07/dynamic-google-scatter-chart-in-aspnet.html but dont know in that example how to handle dynamic data in the controller file.

Controller:

namespace AppRepo.Controllers
{
    public class RepositoriesController : Controller
    {
        private Database1Entities db = new Database1Entities();

        // GET: Repositories
        public ActionResult Index()
        {

            return View(db.Repositories.ToList());

        }

        public ActionResult Grouped()
        {
            return View(db.Repositories.ToList());

        }

        public ActionResult Charts()
        {
            return View(db.Repositories.ToList());


        }
}

VIEW file:

@model List<AppRepo.Models.Repository>

@{
    ViewBag.Title = "Charts";
}

@section Scripts
{
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>

    <script type="text/javascript">
        google.load('visualization', '1', { packages: ['corechart'] });
    </script>

    <script type="text/javascript">
        google.setOnLoadCallback(drawChart);
        function drawChart() {
            var tdata = new google.visualization.DataTable();
            var data = [{ "Name": "A", "Qty": 1 }, { "Name": "B", "Qty": 2 }, { "Name": "C", "Qty": 3 }, { "Name": "D", "Qty": 4 }];

            tdata.addColumn('string', 'Name');
            tdata.addColumn('number', 'Qty');

            for (var i = 0; i < data.length; i++) {
                tdata.addRow([data[i].Name, data[i].Qty]);
            }
            var options = {
                width: 1000,
                height: 563,
                //title: '@Model.Select(r => r.BackupServer)',
                hAxis: {
                    title: 'Date',
                    gridlines: { count: 10 }
                },
                vAxis: {
                    title: '% Free'
                }
            };




            chart = new google.visualization.ColumnChart(document.getElementById('divchart'));

            chart.draw(tdata,options);
        }

    </script>
}
<div id='divchart'>
</div>

I also get the following error now:

The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[AppRepo.Models.Repository]', but this dictionary requires a model item of type 'AppRepo.Models.Repository'.

BDL
  • 21,052
  • 22
  • 49
  • 55

1 Answers1

0

Your issue is that your view's model is AppRepo.Models.Repository, but you're passing into it a List of AppRepo.Models.Repository objects.

If you update your view's model to be List<AppRepo.Models.Repository>, the error you're receiving should disappear. However, you'll then need to go through and update your references to your model in your view file, since things like @Html.Raw(Model.FreePct) won't work anymore. That will be pretty easy, though, if you want all of the FreePct values in your List of Repository objects, you can just do something like @Model.Select(r => r.FreePct) instead.

UPDATED ANSWER AFTER UPDATED QUESTION:

Here's the general format I use for drawing charts. It uses some jQuery, but it works reliably for me. Also, by separating out the loading and drawing of the charts, you can have your page be more responsive by only loading the data when you need to, and then you can re-draw as much as you want without re-loading.

Notice that when I use chart, data, and options, I'm not prefacing them with var because I want to use the global instances of these variables.

UPDATE: I think this should use your Model data properly. Notice that in the for loop, the method is tdata.addRows, not tdata.addRow.

<div id='divchart'>
</div>

@section Scripts
{
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>

    <script type="text/javascript">
        google.load('visualization', '1', { packages: ['corechart'] });
    </script>

    <script type="text/javascript">

        var chart;
        var options;
        var data;

        $(document).ready(function () {
            LoadChartData();
            DrawChart();
        });

        function LoadChartData() {
            var tdata = new google.visualization.DataTable();
            tdata.addColumn('date', "Date");
            tdata.addColumn('number', "FreePct");

            @for (int i = 0; i < Model.Count; i++) 
            {
                @: tdata.addRows([@Model.ElementAt(i).Date, @Model.ElementAt(i).FreePct]);
            }

            options = {
                width: 1000,
                height: 563,
                title: '@Model.Select(r => r.BackupServer).FirstOrDefault()',
                hAxis: {
                    title: 'Date',
                    gridlines: { count: 10 }
                },
                vAxis: {
                    title: '% Free'
                }
            };

            var chartContainer = document.getElementById("divchart");

            while (chartContainer == null) {
                chartContainer = document.getElementById("divchart");
            }

            chart = new google.visualization.ColumnChart(chartContainer);
        }

        function DrawChart() {

            chart.draw(data, options);
        }

    </script>
}
Sean Cogan
  • 2,516
  • 2
  • 27
  • 42
  • The [i] is not recognized this way. – Sander Rozemuller Feb 23 '15 at 15:05
  • Oh, yeah, I see the mistake there. GIve me a minute to fix that. – Sean Cogan Feb 23 '15 at 15:11
  • I used the second answer from here: http://stackoverflow.com/questions/2002831/asp-net-mvc-how-can-you-loop-through-model-data-in-javascript My answer is now updated. – Sean Cogan Feb 23 '15 at 15:14
  • Still not working. Think the code is correct but the data isn't and thats way the chart isn't there. I've uncommented the title in the options. The title is see now is : System.Linq.Enumerable +WhereSelectListIterator`2[AppRepo.Models.Repository,System.String] – Sander Rozemuller Feb 23 '15 at 15:17
  • If Model is a List of Repositories, Select won't work for the title. The title is expecting a string, while Select will return a list of Strings. So, maybe you'll want to add a FirstOrDefault in there at some point. Either replace the Select with it, or put it after the Select. – Sean Cogan Feb 23 '15 at 15:19
  • Ok. Dont see the clue anymore. – Sander Rozemuller Feb 23 '15 at 15:28
  • No not resolved. Still got no chart. It looks like the data is wrong or something. If i use static data everything is fine so the overall code is fine. It just the data. – Sander Rozemuller Feb 23 '15 at 19:10
  • Ok, well if you feel that the solution I presented helped you to get the correct code, you could mark it as the accepted answer. If not, hopefully you'll get your answer about the data! – Sean Cogan Feb 23 '15 at 20:33
  • Sean, i think you put me in the right direction so i did accept the answer. Hope i can find the right solution for getting the data in the right way. – Sander Rozemuller Feb 24 '15 at 07:51
  • Glad I could be of help, hope you find the right answer soon! – Sean Cogan Feb 24 '15 at 11:05