2

I am writing a report in R Markdown, it contains multiple animated highcharts.

The animations work fine, however they all run when the html page loads (after knitting), instead of when the user scrolls to it, so essentially the animation is pointless as the user never sees it.

An example of an animated chart is at the bottom of this question.

Is there a way to make it animate when it appears? All the examples I have found use jsfiddle and I am using R Markdown.

Many thanks

library(dplyr)
library(stringr)
library(purrr)

n <- 5

set.seed(123)

df <- data.frame(x = seq_len(n) - 1) %>% 
  mutate(
    y = 10 + x + 10 * sin(x),
    y = round(y, 1),
    z = (x*y) - median(x*y),
    e = 10 * abs(rnorm(length(x))) + 2,
    e = round(e, 1),
    low = y - e,
    high = y + e,
    value = y,
    name = sample(fruit[str_length(fruit) <= 5], size = n),
    color = rep(colors, length.out = n),
    segmentColor = rep(colors2, length.out = n)
  )


hcs <- c("line")  %>% 
  map(create_hc) 

hcs
Nicholas
  • 3,517
  • 13
  • 47
  • 86
  • In pure JS it would be really simple and you can find thousands or even more examples online, e.g. this one https://stackoverflow.com/questions/21561480/trigger-event-when-user-scroll-to-specific-element-with-jquery But I don't know how the Markdown works. – raf18seb Nov 26 '19 at 13:42
  • Yep. Found lots of examples of it online in JS, but spent hours last night trying to find out how I can wrap the R code inside JS and am turning up blanks!... :/ – Nicholas Nov 26 '19 at 13:43
  • 1
    If you don't get the answer here, I suggest trying on another forum more related to R. – raf18seb Nov 26 '19 at 13:46
  • Thank you. Appreciate it. I am in no rush as I have many more pages to write for the report, but would be good to know both for this piece of work and for anything else I decide to do in R Markdown! – Nicholas Nov 26 '19 at 13:47

1 Answers1

2

Ok, I worked out how to do it myself, going to post the answer here in case someone stumbles across this post in the future.

First of all, I found NOTHING on how to do this in R.

So, I decided to do this in JS, AFTER I had knitted the R Markdown document to HTML, as it wouldn't work in R Markdown.

Once it is a HTML file, open it in TextEdit or Notepad, and add the following code just before one of the charts:

<script>
(function (H) {

    var pendingRenders = [];

    // https://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport/7557433#7557433
    function isElementInViewport(el) {

        var rect = el.getBoundingClientRect();

        return (
            rect.top >= 0 &&
            rect.left >= 0 &&
            rect.bottom <= (
                window.innerHeight ||
                document.documentElement.clientHeight
            ) &&
            rect.right <= (
                window.innerWidth ||
                document.documentElement.clientWidth
            )
        );
    }

    H.wrap(H.Series.prototype, 'render', function deferRender(proceed) {
        var series = this,
            renderTo = this.chart.container.parentNode;

        // It is appeared, render it
        if (isElementInViewport(renderTo) || !series.options.animation) {
            proceed.call(series);

        // It is not appeared, halt renering until appear
        } else  {
            pendingRenders.push({
                element: renderTo,
                appear: function () {
                    proceed.call(series);
                }
            });
        }
    });

    function recalculate() {
        pendingRenders.forEach(function (item) {
            if (isElementInViewport(item.element)) {
                item.appear();
                H.erase(pendingRenders, item);
            }
        });
    }

    if (window.addEventListener) {
        ['DOMContentLoaded', 'load', 'scroll', 'resize']
            .forEach(function (eventType) {
                addEventListener(eventType, recalculate, false);
            });
    }

}(Highcharts));
</script>

The charts then animate when you scroll to them, rather than when you open the HTML file.

Note: The JSFIDDLE I got the code from was from here:

https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/studies/appear/

Nicholas
  • 3,517
  • 13
  • 47
  • 86