Generating 30+ charts on one page has bad performance
- Dominant language
- JavaScript
- Stars
- 9.3k
- Forks
- 1.4k
- Avg merge
- 6d 16h
- Merged PRs (30d)
- 1
Description
I have made a page which generates combined bar and line graphs from a JSON file. Unfortunately I can't share the page itself but I hope someone can point me in the right direction with the info I can give.
Almost all html elements and the graphs themselves are created with JQuery and javascript, the data is fetched with one JSON file. On Chrome everythings works fine but in IE10 and IE9 the page doesn't load for a minute or so and in FireFox it takes that long it gives a warning that a script is not responding. After clicking ok, the page loads correct, but this is not user friendly of course.
Can somebody say something about the way I build the page? What I can get from developer tools is that it really are the graphs that are taking the time. It seems that the more graphs, the time goes up exponentially. It's like Chrome is making them all at once and FF is doing one at a time, taking more time for each graphs that is added.
We are talking about 30 graphs here with 24 data points. That shouldn't be a problem right?
This is an example of the JSON data for one graphs, note all necessary data for all graphs is fetch at once:
`"Name": "ResourceA",
"Roles": [
{
"Name": "RoleA",
"ValuesA": [
-1.0,
0.3,
0.7,
0.7,
0.7,
0.7,
0.1,
0.1,
0.1,
0.1,
0.1,
0.1,
0.0
],
"ValuesB": [
-2.0,
4.0,
4.0,
4.0,
4.0,
4.0,
4.0,
4.0,
4.0,
4.0,
4.0,
4.0,
4.0
]
}
]
},`
This is my complete javascript file, which is responsible for creating all graphs and the elements in which they resides:
`$(document).ready(function() {
'use strict';
var resourceCenterTitleClass = "resourceCenterTitle";
var roleTitleClass = "roleTitle";
var roleGraphClass = "roleGraph";
var roleContainerClass = "roleContainer";
var resourceCenterClass = "resourceCenter";
var JSON = 'json/test.json';
var months = [];
loadJSON(JSON);
```
$('#resourcePicker').change(function() {
JSON = this.value;
if (this.value === 'json/chartData.json') {
$('#lblTitle').html('Title1');
} else {
$('#lblTitle').html('Title2');
}
$(".resourceCenterContainer").remove();
$('
'class': "row resourceCenterContainer",
}).appendTo('.container-fluid');
loadJSON(JSON);
});
function loadJSON(JSON) {
// Get JSON object + Process data
$.getJSON(JSON, function(view) {
months = view.MonthNames;
$.each(view.ResourceCenters, function(index, resourceCenter) {
createResourcePanel(index, resourceCenter);
});
layoutElements();
});
}
function createResourcePanel(index, resourceCenter) {
// Create panel-title
var panelTitle = $('
', {
'class': "panel-title",
html: resourceCenter.Name
});
// Create panel-heading
var panelHeading = $('
'class': "panel-heading",
html: $(panelTitle).prop('outerHTML')
});
// Create panel body div
var panelBodyDiv = $('
'class': "",
'id': "resourceCenter" + index
});
// Create panel itself
var panelDiv = $('
'class': "panel panel-master",
html: $(panelHeading).prop('outerHTML') + $(panelBodyDiv).prop('outerHTML')
})
// Resourcecenter div with panel included
$('
'class': "col col-xs-12 col-sm-6 col-md-4 col-lg-3" + " " + resourceCenterClass + " grid-sizer ",
html: $(panelDiv).prop('outerHTML')
}).appendTo('.resourceCenterContainer');
createResourceCenter(index, resourceCenter);
}
function createResourceCenter(index, resourceCenter) {
var rcName = "resourceCenter" + index;
var first = true;
// graph divs
$.each(resourceCenter.Roles, function(roleIndex, role) {
var roleId = "role" + index + roleIndex;
// roleContainer
var roleContainer = $('
'class': roleContainerClass,
'id': roleId
});
// role title
$('', {
'class': "",
html: role.Name
}).appendTo(roleContainer);
// role graph div
$('
'class': roleGraphClass,
'id': roleId + "Graph"
}).appendTo(roleContainer);
$(roleContainer).appendTo($('#' + rcName));
console.log('create graph');
//setTimeout(function() {
createGraph(roleId, role);
//}, 2000);
if (!first) {
$('
}
first = false;
});
}
function createGraph(roleId, role) {
var roleName = role.name;
var moreOrLess = [];
for (var i = 1; i < 13; i++) {
var moreorless = role.AssignedValues[i] > role.CapacityValues[i];
moreOrLess.push(moreorless);
}
var lbl1 = "lbl1";
var lbl2 = "lbl2";
var lbl3 = "lbl3";
var chart = c3.generate({
bindto: "#" + roleId + "Graph",
size: {
height: 200,
width: 300
},
transition: {
duration: 0
},
interaction: {
enabled: false
},
data: {
columns: [
role.AssignedValues,
role.CapacityValues,
],
type: 'bar',
types: {
'-1': 'bar',
'-2': 'area-step'
},
names: {
'-2': lbl1,
'-1': lbl2
},
color: function(color, d) {
if (moreOrLess[d.index] && (d.id === '-1')) {
color = '#d9534f' // danger danger
}
return color;
}
},
color: {
pattern: ['#04aeef', '#5cb85c']
},
axis: {
x: {
type: 'category',
categories: months,
tick: {
format: function(x) {
var str = months[Math.round(x)];
return str.charAt(0);
}
}
},
y: {
label: {
text: lbl3,
position: 'outer-middle'
}
}
},
tooltip: {
format: {
title: function(d) { return months[d]; }
}
},
});
//setTimeout(function() {
console.log('graph created');
// }, 2000);
}
function layoutElements() {
$('.resourceCenterContainer').masonry({
itemSelector: '.resourceCenter', // use a separate class for itemSelector, other than .col-
columnWidth: '.grid-sizer',
percentPosition: true,
});
}
```
});`
Contributor guide
Assessment
This issue has not been assessed yet.