-1

I am using Json.net to create a data structure for Flot Javascript library

public ActionResult PrepareChartData(int id)
{
    List<DeviceChannel> deviceChannel = (from dc in db.DeviceChannels.Include(c => c.Device)
                                .Include(c => c.Channel).OrderBy(c => c.ChannelID)
                                .Where(c => c.DeviceID == id)
                                select dc).ToList();
    List<ChannelData> channelData = (from cd in db.ChannelDatas
                                    join dc in db.DeviceChannels on cd.DeviceChannelID equals dc.DeviceChannelID
                                    where cd.DeviceChannelID == id
                                    select cd).ToList();
    JObject retVal = new JObject(new JProperty("",
                                new JArray(
                                    from x in deviceChannel
                                    select new JObject (
                                        new JProperty("label", x.Channel.Description),
                                        new JProperty("data",
                                        new JArray(
                                                from cd in  channelData
                                                select new JArray(new JValue(cd.DataDateTime),new JValue(cd.Value))
                                            )
                                        )
                                    )
                                )    
                            )
                        );
    return Json(retVal, JsonRequestBehavior.AllowGet);
}

The problem appears to be that JSon.Net does not allow a JArray directly inside a JObject, so I added a JProperty but that does not match the structure required by Flot library

"": [
    {
      "label": "Voltage A",
      "data": [
        [
          "2014-06-25T14:24:38.41",
          750.0
        ],
        [
          "2014-06-25T15:28:04.427",
          750.0
        ],
        [
          "2014-06-25T16:29:13.757",
          750.0
        ]
      ]
    },
    {
      "label": "Voltage B",
      "data": [
        [
          "2014-06-25T14:24:38.41",
          750.0
        ],
        [
          "2014-06-25T15:28:04.427",
          750.0
        ],
        [
          "2014-06-25T16:29:13.757",
          750.0
        ],
      ]
    }
   ]

Question: Do I use a different method to generate the data structure or can I do this with JSON.Net?

sakir
  • 3,391
  • 8
  • 34
  • 50
Eric Hewett
  • 557
  • 7
  • 16

1 Answers1

1

In addition to what @Stijn says in his comment, flot is also not going to like those datetime strings. It requires javascript epochs when working with time. You want something like (untested):

JArray retVal = new JArray(
      from x in deviceChannel
      select new JObject (
          new JProperty("label", x.Channel.Description),
          new JProperty("data",
          new JArray(
                from cd in channelData
                select new JArray(new JValue((cd.DataDateTime - new DateTime(1970,1,1)).TotalSeconds * 1000),new JValue(cd.Value))
            )
        )
    )
);

UPDATES

Essentially the MVC framework doesn't know how to seriealize JSON.NET objects. You can force it pretty simply, see this question and this one. But before you go down this path , you should decide which JSON library you are using for your application. MVC uses the built-in JavascriptSerializer and unless you have a compelling need to use JSON.NET (it is faster), I would just stick with it. Here's similar code (I don't have your linq structures so this is just a demonstration):

    public class FlotSeries
    {
        public List<double[]> data;
        public string label;
    }

    public ActionResult Test()
    {
        FlotSeries flotSeries = new FlotSeries();
        flotSeries.label = "Series1";
        flotSeries.data = new List<double[]>();
        flotSeries.data.Add(new double[] { (DateTime.Now - new DateTime(1970, 1, 1)).TotalSeconds * 1000, 23.0 });
        flotSeries.data.Add(new double[] { (DateTime.Now - new DateTime(1970, 1, 1)).TotalSeconds * 1000, 12.0 });
        return Json(flotSeries, JsonRequestBehavior.AllowGet);
    }

Resulting JSON:

{"data":[[1407837905793.7207,23],[1407837905793.7207,12]],"label":"Series1"}

Update:

public ActionResult PrepareChartData(int id)
{
    List<FlotSeries> _flotSeries = new List<FlotSeries>();
    var deviceChannels = db.DeviceChannels
                        .Include(c=>c.Channel)
                        .OrderBy(c=>c.ChannelID)
                        .Where(c=>c.DeviceID==id);
    foreach (var dc in deviceChannels)
    {
        FlotSeries fs = new FlotSeries();
        fs.data = new List<double[]>();
        fs.label = dc.Channel.Description;
        var channelDatas = db.ChannelDatas
                        .OrderBy(c => c.DataDateTime)
                        .Where(c => c.DeviceChannelID == dc.DeviceChannelID);
        foreach (var q in channelDatas)
        {
            fs.data.Add( new Double[] {(q.DataDateTime - new DateTime(1970, 1, 1)).TotalSeconds * 1000, q.Value }  );   
        }
        _flotSeries.Add(fs);
    }
    return Json(_flotSeries, JsonRequestBehavior.AllowGet);
}
Community
  • 1
  • 1
Mark
  • 106,305
  • 20
  • 172
  • 230
  • This code produces a JSON object structured as I require it. One the serverside the object contains the data but when it is returned to the client side either into my View (.cshmtl) or directly by using the browser to target the URL the structure is as expected with [] {} but all the data has been removed. I have tried adding "application/json" to the Json() return object. – Eric Hewett Aug 12 '14 at 12:43
  • @EricHewett, which version of ASP.NET/MVC are you using? – Mark Aug 12 '14 at 13:07
  • ASP.NET MVC 5.2.0 Json.net 6.0.4 – Eric Hewett Aug 12 '14 at 13:19
  • Thanks @Mark I was coming to a similar conclusion - I found this http://stackoverflow.com/questions/14913324/json-structure-is-returned-empty-without-property-names-and-values-when-using-n but you've moved it on to the next step. Very frustrating. I will try your idea. – Eric Hewett Aug 12 '14 at 14:27