Reputation: 3827
I am using an MVC Razor foreach
to render charts, sometimes over 150.
This is how I generate the script:
@{chartCount = 0;}
@foreach (var item in Model.ChartRows.Where(m => !m.SummaryRow))
{
$('#container_@(chartCount)').highcharts({
//code removed for brevity
});
chartCount++;
}
And then in my HTML I use this to render the containers:
@for (int i = 0; i < chartCount; i++)
{
<div id="container_@(i)"></div><br />
}
However, when there are 100's of items in ChartRows
, the page can take a long time to load before suddenly all of the charts appear.
I have taken a look on the HighCharts website and have found a chart type called "Sparkline" and the jsFiddle example shows a way that the rendering can be delayed using a setTimout
with it then rendering them in "chunks".
For me to make this work the way that I would need, I would have to remove all of the data from the script (or at least anything being populated from item.
) and instead add 7+ data attributes onto each of the HTML containers and use jQuery to get those data attributes to populate the chart data. I'm not really excited about this approach as it could make troubleshooting a bit of a nightmare.
Does anyone know if it is possible to add each of the charts being rendered into some kind of queue so that they get rendered 1 at a time instead of the browser doing them all at the same time?
Upvotes: 2
Views: 837
Reputation: 3827
This is how I did it:
<script>
var chartFunctions = [];
@foreach (var item in Model.ChartRows.Where(m => !m.SummaryRow))
{
var chart_@(item.ID) = function () {
$('#container_@(item.ID)').highcharts({
//code removed for brevity
});
}
//add this function into the array
chartFunctions.push(chart_@(item.ID));
}
function renderCharts() {
var time = +new Date(),
len = chartFunctions.length;
for (i = 0; i < len; i += 1) {
//call each function in the function array
chartFunctions[i]();
// If the process takes too much time
if (new Date() - time > 500) {
chartFunctions.splice(0, i + 1);
setTimeout(renderCharts, 0);
break;
}
}
}
renderCharts();
</script>
And I also needed to use a foreach
to match up the chartID and the containerID:
@foreach (var item in Model.ChartRows.Where(m => !m.SummaryRow))
{
<div id="container_@(item.ID)"></div><br />
}
Upvotes: 1