Highstock | Tooltip displacement | Tooltip content picks previous day's data on current day tooltip when zoomed in

☆樱花仙子☆ 提交于 2019-12-12 02:17:36

问题


Expected behaviour

Tooltip content on a particular day should remain same even if the content is zoomed in or zoomed out.

Actual behaviour

Tooltip content on same day is different when graph is zoomed in and zoomed out.

Live demo with steps to reproduce

https://jsfiddle.net/aveohsdr/8/

Github Issue Link

https://github.com/highcharts/highcharts/issues/6241

Affected browser(s)

Firefox / Chrome

Description

Check tool-tip content for date 4th June 2016, and then change dates from range selector i.e 1 June 2016 to 30th June 2016, mouse hover on to 4th June tool-tip, now tool-tip has different content. Something's wrong with my code or may be at Highchart's end and I'm unable to figure out what.

Code is below

var seriesOptions = [];
$(function() {
var html = '';
var groupingButtons = {
        "Day": "day",
        "Week": "week",
        "Month":"month",
        "3M":"quater",
        "6M":"half"
};
for (var i in groupingButtons) {
    html += '<button class="btn btn-default dateWiseCriteria" data-criteria="' + groupingButtons[i] + '">' + i + '</button>';
}

$('.dateWiseCriteriaContainer').html(html);
var options = {};
$.extend(options, {
    units: [
        ['week', [1]]
    ]
});
drawAnalyticalStockChart(getSeries(), options);
$(document).on('click', '.dateWiseCriteria', function() {
    var options = {};
    var criteria = $(this).data('criteria') == 'quater' ? 'month' : $(this).data('criteria');
    criteria = $(this).data('criteria') == 'half' ? 'month' : criteria;
    var value = $(this).data('criteria') == 'quater' ? 3 : 1;
    value = $(this).data('criteria') == 'half' ? 6 : value;
    $.extend(options, {
        units: [
            [criteria, [value]]
        ]
    });
    drawAnalyticalStockChart(getSeries(), options);
});
});

function drawAnalyticalStockChart(series, options) {
Highcharts.stockChart('container', {
    chart: {
        zoomType: 'x',
    },
    credits: {
        enabled: false
    },
    rangeSelector: {
        selected: 4
    },

    legend: {
        enabled: true
    },

    scrollbar: {
        showFull: false
    },

    xAxis: [{
        crosshair: true,
    }],

    yAxis: [{ // Primary yAxis
        type: 'datetime',
        dateTimeLabelFormats: { //force all formats to be hour:minute:second
            second: '%H:%M:%S',
            minute: '%H:%M:%S',
            hour: '%H:%M:%S',
            day: '%H:%M:%S',
            week: '%H:%M:%S',
            month: '%H:%M:%S',
            year: '%H:%M:%S'
        },
        labels: {
            formatter: function() {
                //get the timestamp
                var time = this.value;
                return _format_date(time, 1);
                //now manipulate the timestamp as you wan using data functions
            },
            style: {
                color: Highcharts.getOptions().colors[2]
            },
            x: 42
        },
        title: {
            text: 'Average Resolution Time',
            style: {
                color: Highcharts.getOptions().colors[2]
            },
            margin: 53
        },
        opposite: true

    }, { // Secondary yAxis
        gridLineWidth: 0,
        title: {
            text: 'Cases',
            style: {
                color: Highcharts.getOptions().colors[0]
            }
        },
        labels: {
            format: '{value} Cases',
            style: {
                color: Highcharts.getOptions().colors[0]
            }
        },
        allowDecimals: false,
        opposite: false

    }, { // Tertiary yAxis
        gridLineWidth: 0,
        title: {
            text: 'Average Response Time',
            style: {
                color: Highcharts.getOptions().colors[3]
            }
        },
        labels: {
            formatter: function() {
                //get the timestamp
                var time = this.value;
                return _format_date(time, 0, 1);
                //now manipulate the timestamp as you wan using data functions
            },
            style: {
                color: Highcharts.getOptions().colors[3]
            }
        },
        type: 'datetime',
        dateTimeLabelFormats: { //force all formats to be hour:minute:second
            second: '%H:%M:%S',
            minute: '%H:%M:%S',
            hour: '%H:%M:%S',
            day: '%H:%M:%S',
            week: '%H:%M:%S',
            month: '%H:%M:%S',
            year: '%H:%M:%S'
        },
    }],
    tooltip: {
        formatter: function() {
            var points = this.points;
            var groupingFormat = points[0].series.options.dataGrouping.dateTimeLabelFormats[points[0].series.currentDataGrouping.unitName][0];
            var headerFormat = '<span style="font-size: 10px">' + Highcharts.dateFormat(groupingFormat, this.x) + '</span><br/>';

            var pointFormat = '',
                currentYear;

            var isAllPointsHaveData = [];
            points.forEach(function(point) {
                if(point.y > 0) {
                    isAllPointsHaveData.push(1);
                }
            });

            points.forEach(function(point) {
                var name = point.series.name,
                    part;
                var finalValue = point.y;
                var showOnTooltip = true;
                if (name === 'Current Year') {
                    currentYear = part = new Date(point.x).getFullYear();
                } else if (name === 'Previous Year') {
                    part = new Date(point.x).getFullYear() - 1
                } else if (name === 'Average Response Time') {
                    finalValue = _format_date(point.y, 0, 1, 1);
                    part = (typeof currentYear !== 'undefined' ?  name + ' ('+currentYear+')' : name );
                } else {
                    finalValue = _format_date(point.y, 1, 1, 1);
                    part = (typeof currentYear !== 'undefined' ?  name + ' ('+currentYear+')' : name );
                }
                if(!$.isEmptyObject(isAllPointsHaveData)) {
                    pointFormat += '<span style="color:' + point.color + '">\u25CF</span> <p style="color:' + point.color + '">' + part + '</p>: <b>' + finalValue + ' ' + point.series.tooltipOptions.valueSuffix + '</b><br/>';
                }
            });
            return headerFormat + pointFormat;
        },
    },
    plotOptions: {
        series: {
            showInNavigator: true,
            dataGrouping: {
                dateTimeLabelFormats: {
                    millisecond: ['%A, %b %e, %H:%M:%S.%L', '%A, %b %e, %H:%M:%S.%L', '-%H:%M:%S.%L'],
                    second: ['%A, %b %e, %H:%M:%S', '%A, %b %e, %H:%M:%S', '-%H:%M:%S'],
                    minute: ['%A, %b %e, %H:%M', '%A, %b %e, %H:%M', '-%H:%M'],
                    hour: ['%A, %b %e, %H:%M', '%A, %b %e, %H:%M', '-%H:%M'],
                    day: ['%A, %b %e, %Y', '%A, %b %e', '-%A, %b %e, %Y'],
                    week: ['Week from %A, %b %e, %Y', '%A, %b %e', '-%A, %b %e, %Y'],
                    month: ['%B %Y', '%B', '-%B %Y'],
                    year: ['%Y', '%Y', '-%Y']
                },
                enabled: true,
                forced: true,
                units: options.units,
                smoothed: true,
            }
        }
    },

    series: getSeries()
});
}
function getSeries() {
seriesOptions = [{
    name: 'Previous Year',
    type: 'column',
    yAxis: 1,
    tooltip: {
        valueSuffix: ' Case(s)',
    },
    data: [],
    "dataGrouping": {
        "approximation": "sum"
    },
    "color": "#8085E9"
}, {
    name: 'Current Year',
    type: 'column',
    yAxis: 1,
    tooltip: {
        valueSuffix: ' Case(s)',
    },
    data: [],
    "dataGrouping": {
        "approximation": "sum"
    },
    "color": "#F45B5B"
}, {
    name: 'Average Response Time',
    type: 'spline',
    yAxis: 2,
    tooltip: {
        valueSuffix: '',
    },
    data: [],
    "dataGrouping": {
        approximation: function(arr) {
            var groupedData = [];
            var xyDataWithTimestamps = [];
            var t = this;
            this.xData.forEach(function(xd, i) {
                xyDataWithTimestamps.push([
                    xd,
                    t.yData[i]
                ]);
            });

            var groupedDataWithTimestamps = [];
            for(var i in arr) {
                var arr1 = jQuery.grep(xyDataWithTimestamps, function( a ) {
                      return a[1] == arr[i];
                });
                groupedDataWithTimestamps.push([
                    arr1[0][0],
                    arr1[0][1]
                ]);
            }

            var len = arr.length;
            var seconds = [], cases = [];
            var finalArrayWithData = [];
            for(var i in groupedDataWithTimestamps) {
                if(groupedDataWithTimestamps[i][1] > 0) {
                    var date = _format_date(arr[i], 1, 1, 1, true);
                    seconds.push((((date.d * 24) * 60) * 60) + ((date.h * 60) * 60) + (date.m * 60));
                    var arr2 = jQuery.grep(seriesOptions[1].data, function( a ) {
                      return a[0] == groupedDataWithTimestamps[i][0];
                    });
                    cases.push(arr2[0][1]);
                    finalArrayWithData['s'] = seconds;
                    finalArrayWithData['cases'] = cases;
                }
            }
            var sumTopS = 0;
            var sumBottom = 0;
            console.log(finalArrayWithData);
            for (var i in finalArrayWithData['cases']) {
                if(finalArrayWithData['s'][i] > 0) {
                    sumTopS += finalArrayWithData['cases'][i] * finalArrayWithData['s'][i];
                    sumBottom += finalArrayWithData['cases'][i];
                }
            }

            var averageS = 0;
            if ($.isNumeric(sumTopS) && sumBottom) {
                averageS = Math.round(sumTopS / sumBottom);
            }

            _dts = Date.UTC(1970, 0, 1, 0, 0, averageS) / 1000;
            return _dts;
        }
    },
    "color": "#8BA6C7"
}];
return seriesOptions;
}
function _format_date(ts, d = 0, h = 0, m = 0, getArray = false) {
var date_now = 0;
var label = '';
var date_future = ts * 1000;
var dateArray = [];
// get total seconds between the times
var delta = Math.abs(date_future - date_now) / 1000;

// calculate (and subtract) whole days
var days = Math.floor(delta / 86400);
var finalValue = '';
if (d) {
    label = days > 1 ? ' days ' : ' day ';
    dateArray['d'] = days;
    finalValue += days + label;
}

delta -= days * 86400;

// calculate (and subtract) whole hours
var hours = Math.floor(delta / 3600) % 24;
if (h) {
    if (d == 0) {
        var totalHours = hours + (days * 24);
        label = totalHours > 1 ? ' hours ' : ' hour ';
        dateArray['h'] = totalHours;
        finalValue += totalHours + label;
    } else {
        label = hours > 1 ? ' hours ' : ' hour ';
        dateArray['h'] = hours;
        finalValue += hours + label;
    }
}

// calculate (and subtract) whole minutes
var minutes = Math.floor(delta / 60) % 60;
delta -= minutes * 60;

if (m) {
    label = minutes > 1 ? ' minutes ' : ' minute ';
    dateArray['m'] = minutes;
    finalValue += minutes + label;
}

if(getArray) {
    return dateArray;
}
return finalValue;
}

回答1:


Answer to this question from github is:

smoothed = false;

click here for reference



来源:https://stackoverflow.com/questions/41633144/highstock-tooltip-displacement-tooltip-content-picks-previous-days-data-on

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!