PDA

View Full Version : [CLOSED] Need help with MVC Line Chart with Dynamic Data



PriceRightHTML5team
Aug 16, 2013, 3:24 PM
I'm trying to create a chart with dynamic data.

My data consists of products and countries where a product has a different price in each country. I can have any n number of countries or n number of products.

In the Ext.Net MVC example the data is mapped to a static field (ie: Data1, Data2).

How do I properly create the data model for a Line Chart in MVC to display my dynamic data?

Below is my code.

Thank you,
Rob

--

Raw Data




Product Country Price
A USA 100
A Canada 70
A Mexico 50
B USA 25
B Canada 20
B Mexico 5



Crosstab Data




Product USA Canada Mexico
A 100 70 50
B 25 20 5



Data Model





namespace SomeSite.DTOs
{
public class ChartDataDTO
{
public string SeriesName { get; set; } // Product
public string DataName { get; set; } // Country
public double DataValue { get; set; } // Product Price
}
}



View




@model List<SomeSite.DTOs.ChartDataDTO>
@{

var X = Html.X();

}

@functions
{
private Ext.Net.Model getChartModel()
{
var chartModel = new Ext.Net.Model();

chartModel.Fields.Add(new ModelField() { Name = "SeriesName" });

var distinctCountries = Model.GroupBy(g => new { g.DataName }).ToList();

foreach (var country in distinctCountries)
{
chartModel.Fields.Add(new ModelField { Name = country.Key.DataName });
}

return chartModel;

}

private string[] getNumericFields()
{
var countriesData = new List<string>();

foreach (var modelData in Model)
{
countriesData.Add(modelData.DataName);
}

return countriesData.ToArray();
}


private List<LineSeries> getLineSeries()
{
var lineSeriesList = new List<LineSeries>();

foreach(var modelData in Model)
{
var lineSeries = new LineSeries();
var xFields = new List<string>();
xFields.Add(modelData.SeriesName);

var yFields = new List<string>();
yFields.Add(modelData.DataValue.ToString());

lineSeries.Axis = Position.Left;
lineSeries.XField = xFields.ToArray();
lineSeries.YField = yFields.ToArray();
lineSeries.HighlightConfig = new SpriteAttributes { Size = 7, Radius = 7 };
lineSeries.MarkerConfig = new SpriteAttributes { Type = SpriteType.Cross, Size = 4, Radius = 4, StrokeWidth = 0 };

lineSeriesList.Add(lineSeries);
}

return lineSeriesList;

}
}


@(X.Panel()
.Title("Line Chart")
.Layout(LayoutType.Fit)
.Width(800)
.Height(600)
.TopBar(X.Toolbar()
.Items(
X.Button()
.Text("Reload Data")
.Icon(Icon.ArrowRefresh)
.Handler("#{Chart1}.getStore().reload()"),
X.Button()
.Text("Save Chart")
.Icon(Icon.Disk)
.Handler("saveChart")
)
)
.Items(
X.Chart()
.ID("Chart1")
.StyleSpec("background:#fff;")
.Shadow(true)
.StandardTheme(StandardChartTheme.Category1)
.Animate(true)
.LegendConfig(X.ChartLegend().Position(LegendPosit ion.Right))
.Store(X.Store()
.Data(Model)
.Model(this.getChartModel())
.Proxy(X.AjaxProxy()
.Url(Url.Action("GetChartData"))
.Reader(X.JsonReader().Root("result"))
)
)
.Axes(
X.NumericAxis()
.Fields(this.getNumericFields())
.Title("Scenario Data")
.MinorTickSteps(1)
.Minimum(0)
.GridConfig(X.AxisGrid()
.Odd(new SpriteAttributes { Opacity = 1, Fill = "#ddd", Stroke = "#bbb", StrokeWidth = 0.5 })
),
X.CategoryAxis()
.Position(Position.Bottom)
.Fields("SeriesName")
.Title("Scenario")
)
.Series(this.getLineSeries())


)
)

Daniil
Aug 16, 2013, 5:08 PM
Hi @PriceRightHTML5team,

Please post a controller action as well. With data for testing.

PriceRightHTML5team
Aug 16, 2013, 6:26 PM
here is code from the controller that provides data




public ActionResult Results()
{
var chartDataList = getMockChartData();

return View(chartDataList );
}

public List<ChartDataDTO> getMockChartData()
{
var chartDataList = new List<ChartDataDTO>();

// Product A
chartDataList.Add(new ChartDataDTO { SeriesName = "ProductA", DataName = "USA", DataValue = 100 });
chartDataList.Add(new ChartDataDTO { SeriesName = "ProductA", DataName = "Canada", DataValue = 70 });
chartDataList.Add(new ChartDataDTO { SeriesName = "ProductA", DataName = "Mexico", DataValue = 50 });

// Product B
chartDataList.Add(new ChartDataDTO { SeriesName = "ProductB", DataName = "USA", DataValue = 25 });
chartDataList.Add(new ChartDataDTO { SeriesName = "ProductB", DataName = "Canada", DataValue = 20 });
chartDataList.Add(new ChartDataDTO { SeriesName = "ProductB", DataName = "Mexico", DataValue = 5 });

return chartDataList();
}

Daniil
Aug 19, 2013, 10:09 AM
Thank you.

I am a bit confused that you picked up a LineSeries. Do you you need a ColumnSeries?

If I understand the requirement correctly, you need something like this.

View

@model List<object>

@{

var X = Html.X();
}

@functions
{
private Ext.Net.Model getChartModel()
{
var chartModel = new Ext.Net.Model();

chartModel.Fields.Add(new ModelField() { Name = "ProductName" });
chartModel.Fields.Add(new ModelField() { Name = "DataValueUSA" });
chartModel.Fields.Add(new ModelField() { Name = "DataValueCanada" });
chartModel.Fields.Add(new ModelField() { Name = "DataValueMexico" });

return chartModel;
}

private string[] getNumericFields()
{
return new string[] { "DataValueUSA", "DataValueCanada", "DataValueMexico" };
}


private ColumnSeries getColumnSeries()
{
var columnSeries = new ColumnSeries();

columnSeries.Axis = Position.Left;
columnSeries.XField = new string[] { "ProductName" };
columnSeries.YField = new string[] { "DataValueUSA", "DataValueCanada", "DataValueMexico" };

return columnSeries;

}
}

<!DOCTYPE html>
<html>
<head>
<title>Ext.Net.MVC v2 Example</title>
</head>
<body>
@X.ResourceManager()

@(X.Chart()
.Width(800)
.Height(600)
.LegendConfig(X.ChartLegend().Position(LegendPosit ion.Right))
.Store(X.Store()
.Data(Model)
.Model(this.getChartModel())
.Proxy(X.AjaxProxy()
.Url(Url.Action("GetChartData"))
.Reader(X.JsonReader().Root("result"))
)
)
.Axes(
X.NumericAxis()
.Fields(this.getNumericFields())
.Title("Scenario Data")
.MinorTickSteps(1),
X.CategoryAxis()
.Position(Position.Bottom)
.Fields("ProductName")
.Title("Scenario")
)
.Series(this.getColumnSeries())
)
</body>
</html>


Controller

public ActionResult Index()
{
var chartDataList = getMockChartData();

return View(chartDataList);
}

public List<object> getMockChartData()
{
var chartDataList = new List<object>();

chartDataList.Add(new { ProductName = "ProductA", DataValueUSA = 100, DataValueCanada = 70, DataValueMexico = 50 });
chartDataList.Add(new { ProductName = "ProductB", DataValueUSA = 25, DataValueCanada = 20, DataValueMexico = 5 });

return chartDataList;
}