Search code examples
c#jqueryjsonasp.net-mvc-4flot

How to pass JSON data from MVC4 to Flot without writing an adapter


I am generating data for Jquery flot in my MVC controller and want to use more sophisticated structure where I would be able to change colors for each bar etc..

to do this I need to pass data structure that looks following

{
label: "y = 3",
data: [[0, 3], [10, 3]]
}

I had no problem passing data when it was simple array by simply getting the data and shaping it like following

var data = topAgents.Select(agent => new List<object>
        {
            agent.User != null ? string.Format("{0}", agent.User).Replace("SAGANTGB\\", "") : null,
            agent.Amount
        }).ToList();

        return Json(data, JsonRequestBehavior.AllowGet);

and in javascript side:

function onAgentDataReceived(series) {
        $("#agents").empty();
        $.plot("#agents", [series], { bars: { show: true, barWidth: 0.6, align: "center" }, xaxis: { mode: "categories", tickLength: 0 } });
    }

However now I can't seem to be able to shape data into such a structure that would fit what $.plot is expecting.

So far I have tried:

KeyValue pair:

var grouped = result.GroupBy(o => o.CREATE_USER_ID).Select(agent => new
                {
                    data = new KeyValuePair<string,int>(
                    agent.Key != null ? string.Format("{0}", agent.Key).Replace("SAGANTGB\\", "") : null, agent.Count()
                        ),
                    color = "yellow"
                }).ToList();

Object with properties:

var grouped =  result.GroupBy(o => o.CREATE_USER_ID).Select(agent => new
                {
                    data = new { A=
                    agent.Key != null ? string.Format("{0}", agent.Key).Replace("SAGANTGB\\", "") : null, B = agent.Count()
                        },
                    color = "yellow"
                }).ToList();

Name Value collection

var grouped =    result.GroupBy(o => o.CREATE_USER_ID).Select(agent => new
                {
                    data = new NameValueCollection
                    {{
                        agent.Key != null ? string.Format("{0}", agent.Key).Replace("SAGANTGB\\", "") : null,  agent.Count().ToString()}
                    },
                    color = "yellow"
                }).ToList();

Anonymous object array

var grouped = result.GroupBy(o => o.CREATE_USER_ID).Select(agent => new
                {
                    data = new object[] { agent.Key != null ? string.Format("{0}", agent.Key).Replace("SAGANTGB\\", "") : null,  agent.Count()},
                    color = "yellow"
                }).ToList();

but none of them flied

IMHO simple data = new object { agent.Key, agent.Count()}, should work but it fails on build with: Error 16 Invalid anonymous type member declarator. Anonymous type members must be declared with a member assignment, simple name or member access..

I could reshape the data in JS after retrieving it however would like to avoid this unnecessary step.

How do I pass data from MVC to javascript without having to reshape it on JS end?


Solution

  • After writing this question for 20 minutes, succeeded on next try

     var grouped =
       result.GroupBy(o => o.CREATE_USER_ID).Select(agent => new
        {
            data = new List<List<object>>
            {
                new List<object>
                {
                    agent.Key != null ? string.Format("{0}", agent.Key).Replace("SAGANTGB\\", "") : null,
                    agent.Count()
                }
            },
            color = "yellow"
        }).ToList();
    
    return Json(grouped, JsonRequestBehavior.AllowGet);
    

    Apparently you need to double wrap it in list.

    Forgot to mention there is no longer need to wrap in in array on JS side

     $.ajax({
            url: '/dashboard/Home/CancellationAgents/',
            type: "GET",
            dataType: "json",
            success: onCancellationAgentsReceived
        });
    
        function onCancellationAgentsReceived(series) {
            $("#agentcancellations").empty();
            $.plot("#agentcancellations", series, {
                bars: { show: true, barWidth: 0.7, align: "center" }, xaxis: {mode: "categories", tickLength: 0, position: "bottom"}});
        }
    

    Hope this saves you some time