c# Resort a list - c#

This is a pretty complicated sort. Basically I take a list of Answers and I order them by Question priority first. Priority is a zero based integer (0 being the highest priority).
What I want to do then, is sort each answer by it's priority.
For example, like this:
var answers = new List<AnswerRequestModel>
{
new AnswerRequestModel
{
Id = 1,
Priority = 0,
Text = "Very high"
},
new AnswerRequestModel
{
Id = 2,
Priority = 1,
Text = "High"
},
new AnswerRequestModel
{
Id = 3,
Priority = 2,
Text = "Medium"
},
new AnswerRequestModel
{
Id = 4,
Priority = 3,
Text = "Low"
}
};
This assumes there is only one question. If there were two questions:
var answers = new List<AnswerRequestModel>
{
new AnswerRequestModel
{
Id = 1,
Priority = 0,
Question = new QuestionRequestModel { Type = QuestionType.Two },
Text = "Very high",
Formulas = new List<AnswerFormula> { new AnswerFormula { Expression = "Very high", Operator = "=", Field = "quality"} }
},
new AnswerRequestModel
{
Id = 2,
Priority = 1,
Question = new QuestionRequestModel { Type = QuestionType.Two },
Text = "High",
Formulas = new List<AnswerFormula> { new AnswerFormula { Expression = "High", Operator = "=", Field = "quality"} }
},
new AnswerRequestModel
{
Id = 3,
Priority = 2,
Question = new QuestionRequestModel { Type = QuestionType.Two },
Text = "Medium",
Formulas = new List<AnswerFormula> { new AnswerFormula { Expression = "Medium", Operator = "=", Field = "quality"} }
},
new AnswerRequestModel
{
Id = 4,
Priority = 3,
Question = new QuestionRequestModel { Type = QuestionType.Two },
Text = "Low",
Formulas = new List<AnswerFormula> { new AnswerFormula { Expression = "Low", Operator = "=", Field = "quality"} }
},
new AnswerRequestModel
{
Id = 5,
Priority = 0,
Question = new QuestionRequestModel { Type = QuestionType.Two, Priority = 1},
Text = "Blacks",
Formulas = new List<AnswerFormula> { new AnswerFormula { Expression = "Blacks", Operator = "=", Field = "colour"} }
},
new AnswerRequestModel
{
Id = 6,
Priority = 1,
Question = new QuestionRequestModel { Type = QuestionType.Two, Priority = 1 },
Text = "Silvers",
Formulas = new List<AnswerFormula> { new AnswerFormula { Expression = "Silvers", Operator = "=", Field = "colour" } }
},
new AnswerRequestModel
{
Id = 7,
Priority = 2,
Question = new QuestionRequestModel { Type = QuestionType.Two, Priority = 1 },
Text = "Reds",
Formulas = new List<AnswerFormula> { new AnswerFormula { Expression = "Blues", Operator = "=", Field = "colour" } }
},
new AnswerRequestModel
{
Id = 8,
Priority = 3,
Question = new QuestionRequestModel { Type = QuestionType.Two, Priority = 1 },
Text = "Yellows",
Formulas = new List<AnswerFormula> { new AnswerFormula { Expression = "Yellows", Operator = "=", Field = "colour" } }
}
};
In both these examples, the order is correct. But now comes the complication.
If I select an answer. I need it to resort, also if the answers and questions come in the wrong order I want them to be sorted correctly.
The method needs to also work when selecting multiple answers.
My method currently looks like this:
public IList<AnswerRequestModel> SortAnswersByPriority(IList<AnswerRequestModel> answers)
{
if (!answers.Any()) return answers;
var chosenAnswers = answers.Where(m => m.Active).ToList();
var sortedAnswers = answers.OrderBy(m => m.Question.Priority).ThenBy(m => m.Priority);
if (!chosenAnswers.Any())
return sortedAnswers.ToList();
var questionIds = answers.GroupBy(m => m.Question.Id).Select(m => m.Key).ToList();
foreach(var questionId in questionIds)
{
var questionAnswers = answers.Where(m => m.Question.Id == questionId).ToList();
if (!questionAnswers.Any()) continue;
var highestPriority = questionAnswers.OrderBy(m => m.Priority).First().Priority;
var chosenQuestionAnswers = answers.Where(m => m.Active).ToList();
var count = chosenQuestionAnswers.Count;
var ordered = questionAnswers.OrderBy(a => 1);
switch (count)
{
case 1:
var choseHighest = chosenQuestionAnswers.SingleOrDefault(m => m.Priority.Equals(highestPriority)) != null;
ordered = choseHighest ? ordered.OrderBy(m => m.Priority) : ordered.OrderByDescending(m => m.Priority);
break;
default:
ordered = ordered.ThenByDescending(m => m.Active).ThenByDescending(m => m.Priority);
break;
}
var questionAnswerIds = ordered.Select(m => m.Id).ToList();
sortedAnswers = sortedAnswers.ThenBy(m => questionAnswerIds.IndexOf(m.Id));
}
return sortedAnswers.ToList();
}
If I put a breakpoint on sortedAnswers = sortedAnswers.ThenBy(m => questionAnswerIds.IndexOf(m.Id)); I can see that my sort is working correctly, because the answer ids are sorted. But when it executes the line with the breakpoint, nothing changes.
Can someone help me figure this out?

Unless your breakpoint is after the ToList() then you won't see a change. The OrderBy/ThenBy methods are implemented using deferred execution. Until you start enumerating the ThenBy query (i.e. using a foreach or ToList/ToArray) you won't see any changes.
sortedAnswers = sortedAnswers
.ThenBy(m => questionAnswerIds.IndexOf(m.Id))
.ToList(); // put your break point after this line

I solved this, but I think it was actually an issue with my logic rather than anything else. I changed my method to this:
public IList<AnswerRequestModel> SortAnswersByPriority(IList<AnswerRequestModel> answers)
{
if (!answers.Any()) return answers;
var chosenAnswers = answers.Where(m => m.Active).ToList();
// If we have no chosen answers, then just do a default sort by priority
if (!chosenAnswers.Any()) return answers.OrderBy(m => m.Question.Priority).ThenBy(m => m.Priority).ToList();
var sortedAnswers = answers.OrderBy(a => 1);
var questionIds = answers.GroupBy(m => m.Question.Id).Select(m => m.Key).ToList();
foreach(var questionId in questionIds)
{
var questionAnswers = answers.Where(m => m.Question.Id == questionId).ToList();
if (!questionAnswers.Any()) continue;
var lowestPriority = questionAnswers.OrderByDescending(m => m.Priority).First().Priority;
var chosenQuestionAnswers = answers.Where(m => m.Active).ToList();
var count = chosenQuestionAnswers.Count;
var ordered = questionAnswers.OrderBy(a => 1);
// Sort by our chosen answers first, then by answer priority
if (chosenQuestionAnswers.Any(m => m.Priority.Equals(lowestPriority)))
{
switch (count)
{
case 1:
ordered = ordered.OrderByDescending(m => m.Priority);
break;
default:
ordered = ordered.OrderByDescending(m => m.Active).ThenByDescending(m => m.Priority);
break;
}
} else
{
ordered = ordered.OrderByDescending(m => m.Active).ThenBy(m => m.Priority);
}
var questionAnswerIds = ordered.Select(m => m.Id).ToList();
sortedAnswers = sortedAnswers.ThenBy(m => questionAnswerIds.IndexOf(m.Id));
}
// Once we have sorted by our answer priority, do a final sort on question priority and return the list
return sortedAnswers.OrderBy(m => m.Question.Priority).ToList();
}
and in answer to #mjwills, the code I supplied should have been enough for you to run locally. If you created a model AnswerRequestModel and a the SortAnswersByPriority method and passed in the list I used in my example, you should be able to execute it without issue.
I could have supplied my unit test:
[Test]
public void ShouldSortOnMultipleQuestionsWithOneChosenAnswerPerQuestion()
{
// Assemble
var services = SortContext.GivenServices();
var sortProvider = services.WhenCreateSortProvider();
var answers = new List<AnswerRequestModel>
{
new AnswerRequestModel
{
Id = 1,
Priority = 0,
Question = new QuestionRequestModel { Type = QuestionType.Two },
Text = "Very high",
Formulas = new List<AnswerFormula> { new AnswerFormula { Expression = "Very high", Operator = "=", Field = "quality"} }
},
new AnswerRequestModel
{
Id = 2,
Priority = 1,
Question = new QuestionRequestModel { Type = QuestionType.Two },
Text = "High",
Formulas = new List<AnswerFormula> { new AnswerFormula { Expression = "High", Operator = "=", Field = "quality"} }
},
new AnswerRequestModel
{
Id = 3,
Priority = 2,
Question = new QuestionRequestModel { Type = QuestionType.Two },
Text = "Medium",
Formulas = new List<AnswerFormula> { new AnswerFormula { Expression = "Medium", Operator = "=", Field = "quality"} }
},
new AnswerRequestModel
{
Id = 4,
Priority = 3,
Question = new QuestionRequestModel { Type = QuestionType.Two },
Text = "Low",
Formulas = new List<AnswerFormula> { new AnswerFormula { Expression = "Low", Operator = "=", Field = "quality"} }
},
new AnswerRequestModel
{
Id = 5,
Priority = 0,
Question = new QuestionRequestModel { Type = QuestionType.Two, Priority = 1},
Text = "Blacks",
Formulas = new List<AnswerFormula> { new AnswerFormula { Expression = "Blacks", Operator = "=", Field = "colour"} }
},
new AnswerRequestModel
{
Id = 6,
Priority = 1,
Question = new QuestionRequestModel { Type = QuestionType.Two, Priority = 1 },
Text = "Silvers",
Formulas = new List<AnswerFormula> { new AnswerFormula { Expression = "Silvers", Operator = "=", Field = "colour" } }
},
new AnswerRequestModel
{
Id = 7,
Priority = 2,
Question = new QuestionRequestModel { Type = QuestionType.Two, Priority = 1 },
Text = "Reds",
Formulas = new List<AnswerFormula> { new AnswerFormula { Expression = "Blues", Operator = "=", Field = "colour" } }
},
new AnswerRequestModel
{
Id = 8,
Priority = 3,
Question = new QuestionRequestModel { Type = QuestionType.Two, Priority = 1 },
Text = "Yellows",
Formulas = new List<AnswerFormula> { new AnswerFormula { Expression = "Yellows", Operator = "=", Field = "colour" } }
}
};
answers[1].Active = true;
answers[6].Active = true;
// Act
var sortedAnswers = sortProvider.SortAnswersByPriority(answers);
var firstAnswer = sortedAnswers[0];
var secondAnswer = sortedAnswers[1];
var thirdAnswer = sortedAnswers[2];
var forthAnswer = sortedAnswers[3];
var fifthAnswer = sortedAnswers[4];
var sixthAnswer = sortedAnswers[5];
var seventhAnswer = sortedAnswers[6];
var eigthAnswer = sortedAnswers[7];
// Assert
firstAnswer.Text.Should().Be("High");
secondAnswer.Text.Should().Be("Very high");
thirdAnswer.Text.Should().Be("Medium");
forthAnswer.Text.Should().Be("Low");
fifthAnswer.Text.Should().Be("Reds");
sixthAnswer.Text.Should().Be("Blacks");
seventhAnswer.Text.Should().Be("Silvers");
eigthAnswer.Text.Should().Be("Yellows");
}

Related

Change big collection into unique List of collections

I have a big list of objects and in this object there is a category ID something like:
var list = new List<Example>
{
new Example {CatId = 1, Value = new { }},
new Example {CatId = 1, Value = new { }},
new Example {CatId = 1, Value = new { }},
new Example {CatId = 2, Value = new { }},
new Example {CatId = 2, Value = new { }},
new Example {CatId = 3, Value = new { }}
// and so on
};
So I am looking for making this complicated list more organized like list of lists of unique elements
something like:
var result = new List<List<Example>>
{
new List<Example>
{
new Example {CatId = 1, Value = new { }},
new Example {CatId = 2, Value = new { }},
new Example {CatId = 3, Value = new { }}
},
new List<Example>
{
new Example {CatId = 1, Value = new { }},
new Example {CatId = 2, Value = new { }}
},
new List<Example>
{
new Example {CatId = 1, Value = new { }}
}
}
Problem is I do not what to use, group by will not fix my case, so how to do this in most efficient way.
So this is about partitioning, it's the sort of thing that is easy to do in a database query, but in c# you need to create some key with a partition number that you can then use to .GroupBy.
The partitioning itself is a grouping
var projected = list.GroupBy(x => x.CatId)
.SelectMany( g => g.Select( ( x, i ) => new { Item = x, rn = i + 1 } ) );
This gives you records that look like:
{"Item":{"CatId":1,"Value":{}},"rn":1}
{"Item":{"CatId":1,"Value":{}},"rn":2}
{"Item":{"CatId":1,"Value":{}},"rn":3}
{"Item":{"CatId":2,"Value":{}},"rn":1}
{"Item":{"CatId":2,"Value":{}},"rn":2}
{"Item":{"CatId":3,"Value":{}},"rn":1}
As you can see that rn ("row number") value can be used to group by:
var result = projected.GroupBy(x => x.rn, x => x.Item);
This gives us:
[{"CatId":1,"Value":{}},{"CatId":2,"Value":{}},{"CatId":3,"Value":{}}]
[{"CatId":1,"Value":{}},{"CatId":2,"Value":{}}]
[{"CatId":1,"Value":{}}]
So, all in 1 go:
var result = list.GroupBy(x => x.CatId)
.SelectMany( g => g.Select( ( x, i ) => new { Item = x, rn = i + 1 } ) )
.GroupBy(x => x.rn, x => x.Item);
Live example: https://dotnetfiddle.net/AlTfk8

System.Linq.Dynamic.Core cannot cast 'object' type to 'Tuple<T1, T2, T3>'

I'm using System.Linq.Dynamic.Core and trying to run a dynamic query with a model as below:
public class Index
{
public long Position { get; set; }
public object[] Values { get; set; }
}
And with a sample of data like this:
var indexes = new Dictionary<long, Index>();
indexes.Add(1, new Index { Position = 1000, Values = new object[3] { "Welly", "Chandra", Tuple.Create<int, int>(1, 2) } });
indexes.Add(2, new Index { Position = 1001, Values = new object[3] { "Darma", "Angelo", Tuple.Create<int, int>(3, 4) } });
indexes.Add(3, new Index { Position = 1002, Values = new object[3] { "Abby", "Yeremia", Tuple.Create<int, int>(5, 6)} });
indexes.Add(4, new Index { Position = 1003, Values = new object[3] { "Yonathan", "Gunawan", Tuple.Create<int, int>(7, 8)} });
indexes.Add(5, new Index { Position = 1004, Values = new object[3] { "Aldy", "Santoso", Tuple.Create<int, int>(11, 12)} });
var queryable = indexes.Values.AsQueryable();
var result = queryable.Where("Values[1].Equals(\"Yeremia\") || ((Tuple<int, int>) Values[2]).Item2.Equals(8)").ToList();
But it always throw an exception:
Exception: No property or field 'Tuple' exists in ...
Is it not possible to use type-casting while querying here?
I don't understand why you write string inside linq where clause.
Following is the completely working code at my end.
var indexes = new Dictionary<long, Index>();
indexes.Add(1, new Index { Position = 1000, Values = new object[3] { "Welly", "Chandra", Tuple.Create<int, int>(1, 2) } });
indexes.Add(2, new Index { Position = 1001, Values = new object[3] { "Darma", "Angelo", Tuple.Create<int, int>(3, 4) } });
indexes.Add(3, new Index { Position = 1002, Values = new object[3] { "Abby", "Yeremia", Tuple.Create<int, int>(5, 6) } });
indexes.Add(4, new Index { Position = 1003, Values = new object[3] { "Yonathan", "Gunawan", Tuple.Create<int, int>(7, 8) } });
indexes.Add(5, new Index { Position = 1004, Values = new object[3] { "Aldy", "Santoso", Tuple.Create<int, int>(11, 12) } });
var queryable = indexes.Values.AsQueryable();
var result = queryable.Where(cc=>cc.Values[1].Equals("Yeremia") || ((Tuple<int, int>) cc.Values[2]).Item2.Equals(8)).ToList();
UPDATE: This is working for me. Type conversion not required.
var indexes = new Dictionary<long, Index>();
indexes.Add(1, new Index { Position = 1000, Values = new object[3] { "Welly", "Chandra", Tuple.Create<int, int>(1, 2) } });
indexes.Add(2, new Index { Position = 1001, Values = new object[3] { "Darma", "Angelo", Tuple.Create<int, int>(3, 4) } });
indexes.Add(3, new Index { Position = 1002, Values = new object[3] { "Abby", "Yeremia", Tuple.Create<int, int>(5, 6) } });
indexes.Add(4, new Index { Position = 1003, Values = new object[3] { "Yonathan", "Gunawan", Tuple.Create<int, int>(7, 8) } });
indexes.Add(5, new Index { Position = 1004, Values = new object[3] { "Aldy", "Santoso", Tuple.Create<int, int>(11, 12) } });
var queryable = indexes.Values.AsQueryable();
var result = queryable.Where("Values[1].Equals(\"Yeremia\") || Values[2].Item2.Equals(8)").ToList();

comparison of the list in the list

I have a list of lists:
List<Product> productList = new List<Product>()
{
new Product()
{
Id = 1,
Model = "Phone",
TypeProd = new CheckTypes
{
ChTypes = new List<CHType>
{
new CHType
{
Id = 8,
IdName = "261"
},
new CHType
{
Id = 9 ,
IdName = "149"
}
}
}
},
new Product
{
Id = 1,
Model = "Printer",
TypeProd = new CheckTypes
{
ChTypes = new List<CHType>
{
new CHType
{
Id = 8,
IdName = null
},
new CHType
{
Id = 8,
IdName = "261"
}
}
}
}
};
And I want to get the first item of this list by comparing the IdName elements with a string[]:
string[] arrStr = new string[] { "261", "149" };
How can I do this better? Tried using foreach and by creating a temporary object that takes an array value and then uses intersect to compare.
You could do it pretty simply with LINQ:
var product = productList
.FindAll(x => x.TypeProd.ChTypes
.All(y => arrString.Contains(y.IdName));
This will give you all products whose TypeProd.ChTypes elements are all in arrString.
For faster performance, you may want to turn arrString into a HashSet<string>.

Linq query - List within List [duplicate]

This question already has answers here:
Group by in LINQ
(11 answers)
Closed 5 years ago.
I'm trying to select a list that contains Fund.Name and List<Investment>.
var funds = new List<Fund>
{
new Fund { Id = 1 , Name = "good" },
new Fund { Id = 2, Name = "bad" }
};
var investments = new List<Investment>
{
new Investment { Fund = funds[0], Value = 100 },
new Investment { Fund = funds[0], Value = 200 },
new Investment { Fund = funds[1], Value = 300 }
};
Then I'm trying to create the query with this:
var query = from f in funds
join i in investments
on f.Id equals i.Fund.Id
select new { f.Name, i };
I wanted something like this:
{ Name = good, {{ Id = 1, Value = 100 }, { Id = 1, Value = 200 }}},
{ Name = bad, { Id = 2, Value = 300 }}
But I'm getting something like this:
{ Name = good, { Id = 1, Value = 100 }},
{ Name = good, { Id = 1, Value = 200 }},
{ Name = bad, { Id = 2, Value = 300 }}
Try using GroupJoin.
var query = funds.GroupJoin(investments, f => f.Id, i => i.Fund.Id, (f, result) => new { f.Name, result });

Populating a highchart graph from a linq query

I am trying to populate a chart with data from my database. I'm using Entity framework and fairly new to asp.net.
What I'm trying to do is populate the chart from my linq query.
var totals = from s in db.ClassInstanceDetails.Include("ClassInstance")
where s.ClassInstance.ClassID == 2
group s by s.ClassInstance.Date into grouped
select new
{
CIDate = grouped.Key,
TotalStudentsInClass = grouped.Count(s => s.Attendance)
};
The linq query works fine, it counts all the students in a classinstance, groups them and counts them. My problem is how do extract the data and put it into the chart. When I debug I can see that the totals variable is
{System.Data.Objects.ObjectQuery<<>f__AnonymousType0<System.DateTime,int>>}
and I can see the results view held by totals as :
{CIDate = {04/09/2012}, TotalStudentsInClass = 5}
{CIDate = {05/09/2012}, TotalStudentsInClass = 7}
{CIDate = {06/09/2012}, TotalStudentsInClass = 14}
Which is great as the query works, it finds how many pupils attended a particular class instance. I'm trying to put this data into a line graph using highcharts. I've tried to separate the linq results into 2 arrays one array containing the dates and another array containing the TotalStudentsInClass value but having no luck as the types are different??? Is this even the right way to do this?
The example I found online pulls from an array I think
.SetSeries(new[]
{
new Series { Name = "Tokyo", Data = new Data(ChartsData.TokioData) },
new Series { Name = "New York", Data = new Data(ChartsData.NewYorkData) },
new Series { Name = "Berlin", Data = new Data(ChartsData.BerlinData) },
new Series { Name = "London", Data = new Data(ChartsData.LondonData) }
}
with the data coming from an object,
public static object[] TokioData = new object[] { 7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6 };
I've tried to run my linq query into an object but that throws me more errors than I know what to do with!!
Any help would be GREATLY appreciated!!
Chart
public static Highcharts TimeSeriesZoomable(Series[] Series, Number MinRange, Number PointInterval, DateTime PointStartDate, AxisTypes XAxisType = AxisTypes.Datetime, string Title = "", string SubTitle = "", string XAxisTitle = "", string YAxisTitle = "", string ToolTipFormat = "", string YAxisLabel = "")
{
Highcharts chart = new Highcharts("chart")
.SetOptions(new GlobalOptions { Global = new Global { UseUTC = false } })
.InitChart(new Chart { ZoomType = ZoomTypes.X, SpacingRight = 20, DefaultSeriesType = ChartTypes.Area, Height = 300, BorderRadius = 0 })
.SetTitle(new Title { Text = Title })
.SetSubtitle(new Subtitle { Text = SubTitle })
.SetXAxis(new XAxis
{
Type = XAxisType,
MinRange = MinRange,
Title = new XAxisTitle { Text = XAxisTitle }
})
.SetYAxis(new YAxis
{
Title = new YAxisTitle { Text = YAxisTitle },
Min = 0.6,
StartOnTick = false,
EndOnTick = false,
Labels = new YAxisLabels
{
Formatter = #"function() { return this.value +' " + YAxisLabel + "';}"
}
})
.SetTooltip(new Tooltip { Shared = true/*, Formatter = #"function() { return ''+ this.x +' - '+ this.y +' " + ToolTipFormat + "'; }" */})
.SetLegend(new Legend { Enabled = true, VerticalAlign = VerticalAligns.Top })
.SetPlotOptions(new PlotOptions
{
Line = new PlotOptionsLine
{
LineWidth = 3,
Marker = new PlotOptionsLineMarker
{
Enabled = false,
States = new PlotOptionsLineMarkerStates
{
Hover = new PlotOptionsLineMarkerStatesHover
{
Enabled = true,
Radius = 5
}
}
},
Shadow = false,
States = new PlotOptionsLineStates { Hover = new PlotOptionsLineStatesHover { LineWidth = 3 } },
PointInterval = PointInterval,
PointStart = new PointStart(PointStartDate)
},
Spline = new PlotOptionsSpline
{
LineWidth = 3,
Marker = new PlotOptionsSplineMarker
{
Enabled = false,
States = new PlotOptionsSplineMarkerStates
{
Hover = new PlotOptionsSplineMarkerStatesHover
{
Enabled = true,
Radius = 5
}
}
},
Shadow = false,
States = new PlotOptionsSplineStates { Hover = new PlotOptionsSplineStatesHover { LineWidth = 3 } },
PointInterval = PointInterval,
PointStart = new PointStart(PointStartDate)
},
Area = new PlotOptionsArea
{
//FillColor = new BackColorOrGradient(new Gradient
//{
// LinearGradient = new[] { 0, 0, 0, 300 },
// Stops = new object[,] { { 0, "rgb(116, 116, 116)" }, { 1, Color.Gold } }
//}),
LineWidth = 1,
Marker = new PlotOptionsAreaMarker
{
Enabled = false,
States = new PlotOptionsAreaMarkerStates
{
Hover = new PlotOptionsAreaMarkerStatesHover
{
Enabled = true,
Radius = 5
}
}
},
Shadow = false,
States = new PlotOptionsAreaStates { Hover = new PlotOptionsAreaStatesHover { LineWidth = 1 } },
PointInterval = PointInterval,
PointStart = new PointStart(PointStartDate)
}
})
.SetSeries(Series);
return chart;
}
Chart Data
public static Series GetTimeSeriesData(IQueryable<YourModel> model, ChartTypes ChartType)
{
List<Series> Series = new List<Series>();
var chartSeries = model.GroupBy(x => x.Name)
.Select(g => new
{
Name = g.Key,
Data = g.Select(x => x.Value).ToArray()
}).ToArray();
foreach (var item in chartSeries)
{
object[] data = item.Data.Cast<object>().ToArray();
Series localSeries = new Series { Name = item.Name, Data = new Data(data), Type = ChartType };
Series.Add(localSeries);
}
return Series;
}
Usage
IQueryable<YourModel> model;
ChartData chartData = new ChartData();
Highcharts chart = new HighChart("chart_time_series");
try
{
model = db.ClassInstanceDetails.AsQueryable();
chartData = GetTimeSeriesData(model, ChartTypes.Line);
chart = TimeSeriesZoomable(chartData.ToArray(), another_options);
}
catch (Exception e)
{
}
And full examples of charts : http://dotnethighcharts.codeplex.com/releases/view/85324
Are you using Highcharts.Net? If so, I'm not sure how much help I can be (I have only done it manually, creating my own objects and converting to JSON etc, which I found to give me complete control, albeit with more effort)
Anyway, this usually largely depends on how your X-axis needs to behave... it appears like it would just be discrete datetime values, (not automatically sequential), and so your object array probably needs to be composed of X- and Y-values, rather than just the Y-values, as it appears you have there.
This next part really depends on how your implementation works, so please excuse the pseudo-pseudo-code...
You either need a 2D array:
eg: data = [[1,1], [2,5], [3,4]...]
or something more concrete: I use a class which has an X and a Y property (amongst other things), but you could try anonymous types perhaps?
eg [{x=1, y=1}, {x=2, y=5}, {x=3, y=4}...] etc
Does this help at all?
Note: you will probably want to read up a bit on how to convert your datetime values for your x-axis - I had to calculate ticks from Epoch etc

Categories