cal-heatmap icon indicating copy to clipboard operation
cal-heatmap copied to clipboard

Responsive cal-heatmap

Open mastef opened this issue 10 years ago • 11 comments

Not quite 'responsive' in the sense of displaying the same data on all widths, however it changes values based on screen width, destroys the old calendar, and draws a new one.

Basically if your window width is less than 768px, it will only show 6 subdomains, and if it's bigger it will show 12 ( or whatever you tell it to )

Let me know if the destroying / unsetting is wrong and could be done better - e.g. with update?


var sixMonthsAgo = function(){
    now = new Date();
    now.setMonth(now.getMonth() - 5);
    return now;
}

var oneYearAgo = function(){
    now = new Date();
    now.setYear(now.getFullYear() - 1);
    now.setMonth(now.getMonth() + 1);
    return now;
}

var responsiveCal = function( options ) {

    if( $(window).width() < 768 ) {
        options.start = sixMonthsAgo();
        options.range = 6;
    } else {
        options.start = oneYearAgo();
        options.range = 12;
    }

    if( typeof cal === "object" ) {
        $('#cal-heatmap').html('');
        cal = cal.destroy();
    }
    cal = new CalHeatMap();
    cal.init( options );

}

caloptions = {
    domain: 'month',
    subdomain: 'day',
    itemName:["action","actions"],
    maxDate: new Date(),
    data: your_data
};

// run first time, put in load if your scripts are in footer
responsiveCal( caloptions );

$(window).on("resize", function() {

    // run on resize
    responsiveCal( cal.options );

});

mastef avatar Jul 23 '14 08:07 mastef

Your implementation is destroying and rebuilding the calendar on each window resize.

Window resize is expensive, as its triggered from the moment you start to resize the window, until it completes: it fires for each intermediate window size. In sum, Resizing the window width from 1000px to 500 px will fire more than one window resize event.

You should add some check to destroy and rebuild the calendar only if necessary. Resizing from 1000px to 800px should not redraw the calendar.

wa0x6e avatar Jul 23 '14 15:07 wa0x6e

@kamisama I agree. That was simply my first initial implementation. In the second one I'm checking if the window resize actually goes beyond the breakpoints of e.g. 728px and only trigger it then.

Other than that, is that the right way to redraw the calendar?

mastef avatar Jul 23 '14 16:07 mastef

It is not the 'right' way, but there is currently no other way. You have to destroy and rebuild the calendar, there is no way to add or delete domain once the calendar is drawn.

wa0x6e avatar Jul 23 '14 16:07 wa0x6e

Yes, that's what I meant. Obviously it would nicer to have a .reload() or .redraw() feature

mastef avatar Jul 23 '14 17:07 mastef

Bump.

Requesting for some way to change options after init, without needing to replace existing heatmap.

pradyunsg avatar Jul 12 '15 12:07 pradyunsg

+1

TheoNolasco avatar Oct 09 '15 18:10 TheoNolasco

You can trigger your responsiveCal() function after the resizing is complete by creating an event:

resizeEnd:

$(window).resize(function() {
    if(this.resizeTO) clearTimeout(this.resizeTO);
    this.resizeTO = setTimeout(function() {
        $(this).trigger('resizeEnd');
    }, 500);
});

Use resizeEnd to run responsiveCal:

$(window).bind('resizeEnd', function() {
     responsiveCal( cal.options );
});

cagrimmett avatar May 20 '16 18:05 cagrimmett

See this blog post

scarroll32 avatar Aug 10 '18 23:08 scarroll32

See this blog post

The link is out of date, check this repo https://github.com/cagrimmett/jekyll-tools#posts-heatmap-calendar

svagier avatar Oct 12 '20 09:10 svagier

You can trigger your responsiveCal() function after the resizing is complete by creating an event:

resizeEnd:

$(window).resize(function() {
    if(this.resizeTO) clearTimeout(this.resizeTO);
    this.resizeTO = setTimeout(function() {
        $(this).trigger('resizeEnd');
    }, 500);
});

Use resizeEnd to run responsiveCal:

$(window).bind('resizeEnd', function() {
     responsiveCal( cal.options );
});

Thanks for this! I wanted to note that the resizeEnd event is superfluous. The responsiveCal function can be called directly by setTimeout in the resize event handler.

geospiza-fortis avatar Nov 26 '20 05:11 geospiza-fortis

A simple alternative that helped me was to override the main svg class "cal-heatmap-container". This will keep the structure initially defined!

.cal-heatmap-container{
    width: 100% !important;
}

fabjordan avatar Apr 04 '21 01:04 fabjordan

v4 can now update calendar settings without destroying and redrawing the calendar. For now, you may now add an event listener on your window, and update the calendar range on demand.

Will see later if this option should be included in the code directly

wa0x6e avatar Nov 28 '22 19:11 wa0x6e