PDA

View Full Version : [CLOSED] Live Chart and JsonStore



bbo1971
Apr 28, 2012, 8:40 AM
Hi to all,
I'm trying to convert the live chart example in MVC. I created the controller, the view and it's working fine.

But when I try to add just a single data from the store it doesn't work as expected. I used the load method instead of reload but it still refresh the whole cache. I read the sencha documentation but no luck.
In the home controller I've the code to return a new point:


public JsonResult GetLiveData()
{
var random = new Random();
int floor=20;


var data = new ChartData
{
Name = DateTime.Now.ToString("hh:mm:ss"),
Data1 = Math.Floor(Math.Max(random.NextDouble() * 100, floor)),
Data2 = Math.Floor(Math.Max(random.NextDouble() * 100, floor)),
Data3 = Math.Floor(Math.Max(random.NextDouble() * 100, floor)),
};


return Json(data,JsonRequestBehavior.AllowGet);
}

In the view I left the example like the original (just changed the names of the fields) and in the taskmanager I wrote

<ext:TaskManager ID="TaskManager1" runat="server">
<Tasks>
<ext:Task TaskID="DataTask" AutoRun="true" Interval="5000">
<Listeners>
<Update Handler="#{Store1}.load();" />
</Listeners>
</ext:Task>
</Tasks>
</ext:TaskManager>

The result, as expected, is that I get just one point to my series.

Any hint on how to ad just the last point

Thanks in advance
Mario

Daniil
Apr 28, 2012, 9:53 AM
Hi,

I would try to use the Store loadData method.
http://docs.sencha.com/ext-js/4-1/#!/api/Ext.data.Store-method-loadData

You can pass "true" as the second parameter to append a data.

You will need to return a JSON object (-s) and call

store.loadData(jsonObjectsFromResponse, true);
within a success handler.

bbo1971
Apr 28, 2012, 10:17 AM
Thanks Daniil for your quick reply but I can't figure out how to solve my problem. Could you prepare a complete example or address me in the ext.net documentation on how to set the success handler (and exception handler) for the Store ?

Thanks in advance
Mario

Daniil
Apr 28, 2012, 11:29 AM
I've looked deeper and realized that there is no need to use the loadData method. It's much easy to deal with a memory proxy.

Hope the following example answers your questions and helps to start.

Example View

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>

<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Ext.Net.MVC v2 Example</title>

<script type="text/javascript">
var day = 0;

var onSuccess = function (store, newItem) {
store.proxy.data.push(newItem);
store.load();
};
</script>
</head>
<body>
<ext:ResourceManager runat="server" />

<ext:Panel
runat="server"
Title="Live Animated Chart"
Width="800"
Height="600"
Layout="FitLayout">
<Items>
<ext:Chart
ID="Chart1"
runat="server"
StyleSpec="background:#fff;"
Animate="true">
<Store>
<ext:Store runat="server">
<Model>
<ext:Model runat="server">
<Fields>
<ext:ModelField Name="Date" Type="Date" />
<ext:ModelField Name="Visits" />
<ext:ModelField Name="Views" />
<ext:ModelField Name="Users" />
</Fields>
</ext:Model>
</Model>
</ext:Store>
</Store>
<Axes>
<ext:NumericAxis
Fields="Views,Visits,Users"
Title="Number of Hits"
Minimum="0"
Maximum="100">
<GridConfig>
<Odd Opacity="1" Fill="#dedede" Stroke="#ddd" StrokeWidth="0.5" />
</GridConfig>
</ext:NumericAxis>

<ext:TimeAxis
Position="Bottom"
Fields="Date"
Title="Day"
DateFormat="MMM dd"
Constrain="true"
FromDate="<%# new DateTime(2012, 1, 1) %>"
ToDate="<%# new DateTime(2012, 1, 7) %>"
Grid="true"
AutoDataBind="true"/>
</Axes>
<Series>
<ext:LineSeries Axes="Left,Bottom" XField="Date" YField="Visits">
<Label Display="None" Field="Visits" TextAnchor="middle" />
<MarkerConfig Size="5" Radius="5" />
</ext:LineSeries>

<ext:LineSeries Axes="Left,Bottom" XField="Date" YField="Views">
<Label Display="None" Field="Visits" TextAnchor="middle" />
<MarkerConfig Size="5" Radius="5" />
</ext:LineSeries>

<ext:LineSeries Axes="Left,Bottom" XField="Date" YField="Users">
<Label Display="None" Field="Visits" TextAnchor="middle" />
<MarkerConfig Size="5" Radius="5" />
</ext:LineSeries>
</Series>
</ext:Chart>
</Items>
</ext:Panel>

<ext:TaskManager runat="server">
<Tasks>
<ext:Task TaskID="DataTask" AutoRun="true" Interval="2000">
<DirectEvents>
<Update
Url="/Chart/GetNewData"
Success="onSuccess(#{Chart1}.getStore(), result.result);"
Failure="alert('Failure');"
CleanRequest="true">
<ExtraParams>
<ext:Parameter Name="day" Value="day++" Mode="Raw" />
</ExtraParams>
</Update>
</DirectEvents>
</ext:Task>
</Tasks>
</ext:TaskManager>
</body>
</html>


Example Controller

using System;
using System.Collections.Generic;
using System.Web.Mvc;
using System.Linq;
using Ext.Net;
using Ext.Net.MVC;
using Controller = System.Web.Mvc.Controller;

namespace Work2MVC.Controllers
{
public class ChartController : Controller
{
public class DataItem
{
public DateTime Date
{
get;
set;
}

public int Visits
{
get;
set;
}

public int Views
{
get;
set;
}

public int Users
{
get;
set;
}
}

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

public AjaxResult GetNewData(int day)
{
var random = new Random();
var date = new DateTime(2012, 1, 1);

DataItem item = new DataItem
{
Date = date.AddDays(day),
Visits = Convert.ToInt32(random.NextDouble() * 100),
Views = Convert.ToInt32(random.NextDouble() * 100),
Users = Convert.ToInt32(random.NextDouble() * 100)
};

AjaxResult r = new AjaxResult();
r.Result = item;

return r;
}
}
}

bbo1971
Apr 28, 2012, 4:25 PM
Thanks Daniil it works almost perfect. Just a last small problem when the series arrives at 7 january it stop refreshing and the chart seems to be frozen. I slightly modified the success handler but no chance can you give me the last help ?


var onSuccess = function (store, newItem) {
store.proxy.data.push(newItem);
store.load();
if (store.getCount() > 10) {
store.suspendEvents();
store.removeAt(0);
store.resumeEvents();
}


Thanks in advance
Mario

Daniil
Apr 28, 2012, 6:35 PM
Well, I've just not implemented it in my example.

Here you are.

Example View

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>

<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Ext.Net.MVC v2 Example</title>

<script type="text/javascript">
var day = 0;

var onSuccess = function (chart, newItem) {
var store = chart.getStore(),
axes,
date = Ext.Date.parse(newItem.Date, "Y-m-dTH:i:s");

if (new Date(2012, 0, 7).getTime() < date.getTime()) {
chart.markerIndex = 1;
axes = chart.axes.get(1);
axes.toDate = date;
axes.fromDate = Ext.Date.add(Ext.Date.clone(axes.fromDate), Ext.Date.DAY, 1);
}

store.proxy.data.push(newItem);
store.load();
};
</script>
</head>
<body>
<ext:ResourceManager runat="server" />

<ext:Panel
runat="server"
Title="Live Animated Chart"
Width="800"
Height="600"
Layout="FitLayout">
<Items>
<ext:Chart
ID="Chart1"
runat="server"
StyleSpec="background:#fff;"
Animate="true">
<Store>
<ext:Store runat="server">
<Model>
<ext:Model runat="server">
<Fields>
<ext:ModelField Name="Date" Type="Date" />
<ext:ModelField Name="Visits" />
<ext:ModelField Name="Views" />
<ext:ModelField Name="Users" />
</Fields>
</ext:Model>
</Model>
</ext:Store>
</Store>
<Axes>
<ext:NumericAxis
Fields="Views,Visits,Users"
Title="Number of Hits"
Minimum="0"
Maximum="100">
<GridConfig>
<Odd Opacity="1" Fill="#dedede" Stroke="#ddd" StrokeWidth="0.5" />
</GridConfig>
</ext:NumericAxis>

<ext:TimeAxis
Position="Bottom"
Fields="Date"
Title="Day"
DateFormat="MMM dd"
Constrain="true"
FromDate="<%# new DateTime(2012, 1, 1) %>"
ToDate="<%# new DateTime(2012, 1, 7) %>"
Grid="true"
AutoDataBind="true"/>
</Axes>
<Series>
<ext:LineSeries Axes="Left,Bottom" XField="Date" YField="Visits">
<Label Display="None" Field="Visits" TextAnchor="middle" />
<MarkerConfig Size="5" Radius="5" />
</ext:LineSeries>

<ext:LineSeries Axes="Left,Bottom" XField="Date" YField="Views">
<Label Display="None" Field="Visits" TextAnchor="middle" />
<MarkerConfig Size="5" Radius="5" />
</ext:LineSeries>

<ext:LineSeries Axes="Left,Bottom" XField="Date" YField="Users">
<Label Display="None" Field="Visits" TextAnchor="middle" />
<MarkerConfig Size="5" Radius="5" />
</ext:LineSeries>
</Series>
</ext:Chart>
</Items>
</ext:Panel>

<ext:TaskManager runat="server">
<Tasks>
<ext:Task TaskID="DataTask" AutoRun="true" Interval="2000">
<DirectEvents>
<Update
Url="/Chart/GetNewData"
Success="onSuccess(#{Chart1}, result.result);"
Failure="alert('Failure');"
CleanRequest="true">
<ExtraParams>
<ext:Parameter Name="day" Value="day++" Mode="Raw" />
</ExtraParams>
</Update>
</DirectEvents>
</ext:Task>
</Tasks>
</ext:TaskManager>
</body>
</html>


And no change in the Controller.

bbo1971
Apr 28, 2012, 6:54 PM
Many thanks Daniil it works like a charm :)
To complete the sample and making it more real I just need to use minute and seconds instead of days (more realistic for live data) and I've to port it to razor ...

However my final two cents consideration. I bought ext.net 2 years ago but I never used it in production because, in my opinion, it wasn't ready for the prime time. Now you did a fantastic job and I'll use the library for our new products generation

Thanks a lot
Mario

Daniil
Apr 30, 2012, 11:00 AM
Thanks for the excellent feedback! It pushes us to work harder :)