[Highcharts] Grote grafiek heel traag, oplossing?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • F.West98
  • Registratie: Juni 2009
  • Laatst online: 08:13

F.West98

Alweer 16 jaar hier

Topicstarter
Hallo,

Ik heb een probleem met Highcharts, ik voer bepaalde handelingen uit op een grafiek en die duren heel lang. Dat zou niet uitmaken ware het niet dat in die tijd de hele site hangt. Niets werkt meer, tot de JS klaar is. En aangezien de JS heel veel moet doen, namelijk ongeveer 30 lijnen (15 splines en 15 scatters) allemaal hiden duurt dit wel 5 seconden, niet gebruiksvriendelijk.

Wat ik wil:
Ik heb dus die ene grafiek met 30 items, omdat 15x een grafiek met 2 items teveel code is (PHP generated) en niet te doen met alle positionering. Daarom stop ik alles in één grafiek, laat ik NA het laden alle items hide en dmv clicks op items komt de grafiek en een bep. aantal items tevoorschijn. Nu kan ik het wel NIET gaan hiden, maar dan duurt de eerste klik heel lang.

Wat ik heb ontdekt:
Als ik de items in de maak-functie al hide, dan wordt de grafiek niet goed gerenderd.
Het hiden duurt 't langst (showen is no problem)

Een testitem:
http://jsfiddle.net/K7Cvs/
Hier zie je dat na het verschijnen van ed grafiek alles 'hangt' en daarna verder gaat.
Ik heb bewust veel data gedaan omdat het zo het makkelijkst te merken is.
Wat is zo langzaam? Dit:
JavaScript:
1
2
3
4
var series = chart2.series;
$.each(series, function() {
    this.hide();
});


Het doorzoeken duurt dus het langste.

Hoe krijg ik dit sneller?

2x Dell UP2716D | R9 7950X | 128GB RAM | 980 Pro 2TB x2 | RTX2070 Super
.oisyn: Windows is net zo slecht in commandline als Linux in GUI


Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 10-09 08:45
Je gebruikt nu jQuery om zelf het toggelen te doen. Is dit niet te doen via de enorm uitgebreide HighCharts-API?

Nu is mij wel bekend dat HighCharts erg traag kan worden op een gegeven moment, maar dat is wel met 1000x meer gegevens dan dit en zelfs daar zijn goede oplossingen voor.

edit: Blijkbaar is die this.hide() al een api-call en gebruik je alleen jQuery voor de each :)

[ Voor 100% gewijzigd door Bosmonster op 30-07-2012 14:36 ]


Acties:
  • 0 Henk 'm!

  • F.West98
  • Registratie: Juni 2009
  • Laatst online: 08:13

F.West98

Alweer 16 jaar hier

Topicstarter
Bosmonster schreef op maandag 30 juli 2012 @ 14:26:
Je gebruikt nu jQuery om zelf het toggelen te doen. Is dit niet te doen via de enorm uitgebreide HighCharts-API?

Nu is mij wel bekend dat HighCharts erg traag kan worden op een gegeven moment, maar dat is wel met 1000x meer gegevens dan dit en zelfs daar zijn goede oplossingen voor.

edit: Blijkbaar is die this.hide() al een api-call en gebruik je alleen jQuery voor de each :)
Zou het kunnen dat jQuery en Highcharts elkaar dan gaan tegenwerken?
Is de jQuery each niet erg traag? (wel zo makkelijk)

2x Dell UP2716D | R9 7950X | 128GB RAM | 980 Pro 2TB x2 | RTX2070 Super
.oisyn: Windows is net zo slecht in commandline als Linux in GUI


Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 10-09 08:45
F.West98 schreef op maandag 30 juli 2012 @ 14:35:
[...]

Zou het kunnen dat jQuery en Highcharts elkaar dan gaan tegenwerken?
Is de jQuery each niet erg traag? (wel zo makkelijk)
Dat lijkt me onwaarschijnlijk.

Is het niet doordat je ze 1-voor-1 hide't? Bij elke serie die je verbergt moet ie namelijk de complete chart opnieuw berekenen en renderen en dan pas gaat ie door met het hiden van de volgende volgens mij.

Kun je bij het initialiseren van de series niet de visible:false property gebruiken?

[ Voor 13% gewijzigd door Bosmonster op 30-07-2012 14:41 ]


Acties:
  • 0 Henk 'm!

  • F.West98
  • Registratie: Juni 2009
  • Laatst online: 08:13

F.West98

Alweer 16 jaar hier

Topicstarter
Bosmonster schreef op maandag 30 juli 2012 @ 14:37:
[...]


Dat lijkt me onwaarschijnlijk.

Is het niet doordat je ze 1-voor-1 hide't? Bij elke serie die je verbergt moet ie namelijk de complete chart opnieuw berekenen en renderen en dan pas gaat ie door met het hiden van de volgende volgens mij.
Dat lijkt mij inderdaad het probleem, maar nergens een optie te vinden die alle series in één keer hide

edit:
Ik heb iets gevonden wat lijkt te werken. chart.ignoreHiddenSeries op false, waardoor de grafiek niet opnieuw wordt gerendert, en daarna die setting op true en het werkt snel(ler). Alsnog duurt het laden van 60 series (2x een grafiek) erg lang...

edit2:
Kun je bij het initialiseren van de series niet de visible:false property gebruiken?
Nee helaas niet, dan wordt de hele grafiek niet gerenderd omdat alles onzichtbaar is. De oplossing hierboven lijkt wel te werken

[ Voor 38% gewijzigd door F.West98 op 30-07-2012 15:02 ]

2x Dell UP2716D | R9 7950X | 128GB RAM | 980 Pro 2TB x2 | RTX2070 Super
.oisyn: Windows is net zo slecht in commandline als Linux in GUI


Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
F.West98 schreef op maandag 30 juli 2012 @ 14:43:
Ik heb iets gevonden wat lijkt te werken. chart.ignoreHiddenSeries op false, waardoor de grafiek niet opnieuw wordt gerendert, en daarna die setting op true en het werkt snel(ler). Alsnog duurt het laden van 60 series (2x een grafiek) erg lang...
Wat dacht je er van om AJAX te gebruiken en on-demand extra series binnen te halen en te renderen zodra ze zichtbaar gemaakt worden? Hopelijk ligt dat niet buiten de afgebakende functionaliteit die de legendas in HighCharts je bieden.

Sowieso zou ik adviseren om een zinnigere library zoals D3.js te gebruiken. Initieel hogere development kosten, maar wel veel meer flexibiliteit en mogelijkheden zodra je iets moet hebben wat net buiten de normale maatvorm valt.

Je hebt dan weliswaar niet de VML fallback die HighCharts heeft, maar die fallback is vanwege de slechte performance van VML in verhouding tot SVG toch compleet zinloos bij grotere data sets.

Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 10-09 08:45
Waarschijnlijk omdat ie niet aan een van de tig eisen van D3 voldoet, zoals 99% van de projecten.

Namelijk weinig tijd, weinig wiskundige visualisatie kennis, hoge compatibiliteit gevraagd (IE).

D3.js is commercieel gezien zelden interessant.

Wat betreft het AJAX-stuk, ja dat kan, maar of het sneller is om een berg losse requests te doen? De vraag is hier simpel: Hoe krijg je een HighCharts-grafiek geladen met veel data op onzichtbaar in eerste instantie. Daar kunnen we wel gewoon antwoord op geven toch?

[ Voor 44% gewijzigd door Bosmonster op 30-07-2012 19:07 ]


Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
Bosmonster schreef op maandag 30 juli 2012 @ 19:03:
Waarschijnlijk omdat ie niet aan een van de tig eisen van D3 voldoet, zoals 99% van de projecten.

Namelijk weinig tijd, weinig wiskundige visualisatie kennis, hoge compatibiliteit gevraagd (IE).

D3.js is commercieel gezien zelden interessant.
Compatibiliteit met IE kun je bij complexe grafieken sowieso al vergeten, ook met HighCharts. De grote hoeveelheid data punten en de erbarmlijke performance van VML maken het toch compleet onbruikbaar voor gebruikers. (Zeker als je nagaat dat ook de JavaScript engine in IE8 en lager een stuk minder performant is.) Het is dan slechts een heel symbolisch vinkje wat je achter een item op je checklist kunt plaatsen: "het 'werkt'."

Wat betreft wiskundige achtergrond: D3 heeft een hele schare aan algoritmen voor grafiek layout beschikbaar die je zo kunt gebruiken. Je hebt alleen wiskundige kennis nodig als je zelf een compleet nieuwe layout strategie wilt maken.
Bosmonster schreef op maandag 30 juli 2012 @ 19:03:
Wat betreft het AJAX-stuk, ja dat kan, maar of het sneller is om een berg losse requests te doen? De vraag is hier simpel: Hoe krijg je een HighCharts-grafiek geladen met veel data op onzichtbaar in eerste instantie. Daar kunnen we wel gewoon antwoord op geven toch?
Wel als je die requests on demand uitvoert zodra een gebruiker een data serie voor het eerst zichtbaar maakt. Als geen van de data series initieel zichtbaar moet zijn, waarom moet alle data dan initieel wel gedownload worden, wel door HighCharts verwerkt worden, maar vervolgens explicieit niet gerenderd worden?
Als je al dat werk nou pas doet wanneer de gebruiker er expliciet om vraagt kun je op die manier al de load balanceren en de peak performance hit reduceren.

Acties:
  • 0 Henk 'm!

  • Feanathiel
  • Registratie: Juni 2007
  • Niet online

Feanathiel

Cup<Coffee>

Bij iedere actie wordt de grafiek opnieuw getekend (svg tekenen, css opnieuw toegepassen, etc.). Wat je zou kunnen doen is het renderen uit zetten om acceptabele performance te krijgen. Dit kan door de render functie/methode te overschrijven. Uiteraard niet weer vergeten terug te zetten nadat je klaar bent, zodat de laatste actuele status van de grafiek worden getekend. Zie fiddle. Ik heb het alleen gedaan bij de klikbare items. Voor het laden van de grafiek kun je dezelfde methode extrapoleren.

Tip: wellicht kun je een suspendLayout/resumeLayout prototype maken op de chart. Scheelt je weer wat complexiteit in je bestaande code.

Bron: http://stackoverflow.com/...-to-get-acceptable-perfor

[ Voor 31% gewijzigd door Feanathiel op 30-07-2012 22:08 ]


Acties:
  • 0 Henk 'm!

  • F.West98
  • Registratie: Juni 2009
  • Laatst online: 08:13

F.West98

Alweer 16 jaar hier

Topicstarter
AJAX is helaas niet mogelijk want dat duurt ook erg lang... Voor IE en mensen die geen grafieken willen komt er wel een optie om alles uit te schakelen, op mobiele apparaten standaard niet.

Het idee van Feanathiel is erg goed! (je vergat wel de code onderin)
Ik denk dat ik dat ga toepassen!

edit:
Het werkt echt heel snel, bedankt voor de tips allemaal!

[ Voor 37% gewijzigd door F.West98 op 31-07-2012 16:06 ]

2x Dell UP2716D | R9 7950X | 128GB RAM | 980 Pro 2TB x2 | RTX2070 Super
.oisyn: Windows is net zo slecht in commandline als Linux in GUI

Pagina: 1