Currently the highcharts_render function builds up the render array and returns the output of passing that render array into drupal_render. My suggested patch is just adding a new function highcharts_render_array which will return the render array while avoiding duplication.

My reason for needing this function is that I am using the #cache settings on a custom render array which contains a highcart when including it just a string the caching system cannot properly build the #attached list to be included on serving the content from the cache. (before storing the content in the cache it iterates through all children building up a complete list of #attached actions to be re-run after a cache hit)

I apologize for there being a bit of noise in patch I just have phpstorm following Drupal standards so it changed some white-space.
Thanks!

CommentFileSizeAuthor
#5 highcharts-2106763.patch2.19 KBASupinski
highcharts.patch4.56 KBASupinski

Comments

boabjohn’s picture

G'Day @asupinski,
Your post looks interesting. Not being a coder, I'm not sure if it's relevant to our issue though.

We have a query running over about 1500 nodes. THe query seems to run fast enough (tested in MySQL workbench) but the chart (a stacked bar chart) is taking about 25secs to render on the page. We take the chart off and the page renders in 2secs.

That sounds to me like HighCharts+Drupal is going through a lot of overhead, and your patch seems related.

Any thoughts?
Shall we just try your patch?

After patching the HighCharts module, do I just edit the function call to highcharts_render?

Here's what we currently have:

    $block['content'] = highcharts_render($options, $attributes);
    return $block;

So that would become:

    $block['content'] = highcharts_render_array($options, $attributes);
    return $block;

Have I got that right?
Thanks in advance!

ASupinski’s picture

Sorry for taking a while to respond here the patch allows you to access the render array and because of that allows you to set #cache settings on that render array which would allow you to cache the output of the render array for however much time you want. I don't know if this will help you though if the content is being produced quickly you might just have so many data points that the javascript takes a long time to render them all on your graph. You might consider changing how much data you are using if that is the case as I cannot imagine many single charts which are useful with 1500 data points. Don't know if that helps but perhaps.

scottrigby’s picture

@boabjohn caching the render array in highcharts_render() won't buy you much because there's no expensive code happening there (if there were, we'd do that in a #pre_render function).

@ASupinski interesting use case... We could add caching options to highcharts_render(), but in the meantime I agree we could change this to a new function - but I'd call it something like highcharts_renderable(). If so, implementations would do something like drupal_render(highcharts_render($options, $attributes)) (unless passed to another function that does rendering automatically, like page callbacks or hook_block_view() 'content' return value).

About the patch noise - please change your phpstorm settings - there is no standardization on continuing array indentation settings (see https://drupal.org/coding-standards#indenting), however I'm following the pattern in Drupal core by sticking with 2. Also the @link comment reference was correct as it was - inline @link references are fine as long as it doesn't extend beyond 80 characters (in which case it needs to be on it's own line - see https://drupal.org/coding-standards/docs#link), and AFAIK there is no error using @link within @param (though if you find documentation on this topic please let me know). A new patch would be welcome :)

scottrigby’s picture

Issue summary: View changes
Status: Active » Needs work
ASupinski’s picture

Status: Needs work » Needs review
StatusFileSize
new2.19 KB

Here is the patch cleaned up as you desired. Thanks!

boabjohn’s picture

G'Day @asupinski,
Thanks for the thoughts. I'm learning about this stuff as best I'm able, and am always concerned that I've missed some big conceptual logic step...
This line of yours caught my attention:

you might consider changing how much data you are using if that is the case as I cannot imagine many single charts which are useful with 1500 data points.

Right, so, can I just explain what we're doing and then you might be able to say "Whoa, that's all wrong!" or, basically we're on the right track?
The 1500 rows of data are being queried, grouped, counted and sorted.
The array that is passed to HighCharts is only 10 rows with 3 columns.
So the chart is not dealing with 1500 "data points", that's in the MySQL query.
Problem is, MySQL should be running that query without 25secs of drama. When I run the query on Workbench locally it only takes about 4sec. Still long, but bearable.
So if the query is natively ok, and Highcharts is only dealing with 10 rows x 3 columns...where should I be looking for the performance loss?
Thanks in advance!
JB

ASupinski’s picture

... Well I would probably cache the Mysql portion as well since 4 seconds it still way too long for any reasonable web page in my estimation but I'm afraid I don't have any hidden knowledge here, I would just debug/instrument your code to see what is taking so long, you could look in developer tools on your browser and see what request is blocking or see if it is javascript blocking the page load.