简体   繁体   中英

RevealJS and Highchart Mouse position Tooltip Issue

I've just built my first RevealJS presentation and while all seemed to work at glance I ran into an game breaking issue with a HighChart that is caused by the way RevealJS scales/moves and elements and SVG related (at least I think so).

There's a similar issue report here, at least it seems related, though I've been unable to resolve my issue as the suggested code is not a drop-in and I'm my JS skills are lacking at best -> Mouse position in SVG and RevealJS

I was hoping someone could help me pinpoint a potential solution, maybe that of the other stack easily can be adapted (I do need the scaling function, I know I could initialize RevealJS with a percentage option, but that will effectively break scaling on any smaller devices).

This is the code part that seems related, in my case the second else if( scale > 1 && features.zoom ) { ... } is triggered and the scaling creates a bad offset depending on resolution.

var size = getComputedSlideSize();

        // Layout the contents of the slides
        layoutSlideContents( config.width, config.height );

        dom.slides.style.width = size.width + 'px';
        dom.slides.style.height = size.height + 'px';

        // Determine scale of content to fit within available space
        scale = Math.min( size.presentationWidth / size.width, size.presentationHeight / size.height );

        console.log("Size:"+size.presentationWidth);
        console.log("Size:"+size.width);


        console.log("1:"+scale);


        // Respect max/min scale settings
        scale = Math.max( scale, config.minScale );
        console.log("2:"+scale);
    scale = Math.min( scale, config.maxScale );
        console.log("3:"+scale);


        // Don't apply any scaling styles if scale is 1
        if( scale === 1 ) {
            dom.slides.style.zoom = '';
            dom.slides.style.left = '';
            dom.slides.style.top = '';
            dom.slides.style.bottom = '';
            dom.slides.style.right = '';
            transformSlides( { layout: '' } );
        }
        else {
            // Prefer zoom for scaling up so that content remains crisp.
            // Don't use zoom to scale down since that can lead to shifts
            // in text layout/line breaks.
            if( scale > 1 && features.zoom ) {
                dom.slides.style.zoom = scale;
                dom.slides.style.left = '';
                dom.slides.style.top = '';
                dom.slides.style.bottom = '';
                dom.slides.style.right = '';
                transformSlides( { layout: '' } );
            }
            // Apply scale transform as a fallback
            else {
                dom.slides.style.zoom = '';
                dom.slides.style.left = '50%';
                dom.slides.style.top = '50%';
                dom.slides.style.bottom = 'auto';
                dom.slides.style.right = 'auto';
                transformSlides( { layout: 'translate(-50%, -50%) scale('+ scale +')' } );
            }
        }

I've created a codepen to illustrate the issue, resize it from small to max size and check the mouse tooltip, there will be a small to massive offset between where the mouse is and what tooltip point shows except when the scale is 1:1.

https://codepen.io/anon/pen/MVLazG

Any and all help would be welcome. If there's a way to process the graph in a way that would retain a better mouse position I'd be grateful both suggestions and code (banged my head for a couple of hours on different approaches without luck).

It is caused by setting transform's scale on the wrapping div. You can read more about on Highcharts github here .

There is a workaround for this which seems to work in your example:

Highcharts.wrap(Highcharts.Pointer.prototype, 'normalize', function (proceed, event, chartPosition) {
    var e = proceed.call(this, event, chartPosition);

    var element = this.chart.container;
    if (element && element.offsetWidth && element.offsetHeight) {

        var scaleX = element.getBoundingClientRect().width / element.offsetWidth;
        var scaleY = element.getBoundingClientRect().height / element.offsetHeight;
        if (scaleX !== 1) {
            e.chartX = parseInt(e.chartX / scaleX, 10);
        }
        if (scaleY !== 1) {
            e.chartY = parseInt(e.chartY / scaleY, 10);
        }

    }
    return e;
});

live example: https://codepen.io/anon/pen/GxzPKq

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM