Search code examples
javascriptchartschart.jslinechartchartjs-2.6.0

Mouse-over function behaving weird in Chart.js


1) I have a website where user can filter values from a drop-down, based on that the data is called to display on the graph (uses ChartJS).

At this stage the code calls a JavaScript function where the values are passed in (x, y axis labels and values, etc). The User can then mouse-over (internal function call from Chart.js) on the graph and get the values as a pop up.

2) Then when user selects some other value from the drop down and then mouseover on the coordinates again to see the pop up values, the graph switches back to old data (1st drop down value - 2019) until few seconds and changes back to its original data (currently being passed from drop down - 2020).

Question 1. How is it able to pass the old data even though I am not saving it in JSON or cookie or something else.

Note: I have checked my "console.log" what values are being passed from the drop down -> which is correct. Kept a debugging point which tells me current dataset values which are being passed to the graph -> which are correct, no two dataset values are being passed.

Question 2. Is this the Chart.JS plugin issue? Since I am not calling any mouseover event in my JS.

If yes, how should I fix it?

Question 3. Overall, what could be the Solution to this?

enter image description here

Following is the JS code for it.

var initialize = function ()
{
    canvas = document.getElementById('wo-chart');
    searchBox = document.getElementById('wo-widget-search');

    allTimeLabel = document.getElementById('wo-billed-total');
    currentLabel = document.getElementById('wo-billed-current');
    selectedDateLabel = document.getElementById('selected-wo-date');
    selectedProblemLabel = document.getElementById('selected-wo-problem');
    selectedTradeLabel = document.getElementById('selected-wo-trade');

    dateSelectors = document.querySelectorAll('[data-wo-date]');



    search();

    // performs a new search when a different start date is selected
    $(dateSelectors).click(function (event)
    {
        event.preventDefault();
        console.log("Function Date Selectors Test! " + this.getAttribute('data-wo-date'));

        selectedDateLabel.innerHTML = this.innerHTML;
        selectedStartDate = this.getAttribute('data-wo-date');

        search();
    });

    // performs a new search when a different problem is selected

};

return { initialize: initialize };

/**
 * Performs a new search for WorkOrder chart data.
 * @function
 */
function search()
{
    otx.spinner(currentLabel, 'span');
    otx.spinner(allTimeLabel, 'span');

    var data = profile.getCurrentEntityInfoAsObject();



    if (selectedStartDate !== null && selectedStartDate !== '')
    {
        data.rangeStartDate = selectedStartDate;
    }


    $.post('/Maintenance/MaintenanceWidget/GetWorkOrderChartData', data, function (result)
    {
        if (!result || result.DataSets.length < 2)
        {
            otx.alerts.error('We were unable to load Work Order chart data.');
            return;
        }

        allTimeLabel.innerHTML = result.WorkOrdersAllTime;
        currentLabel.innerHTML = result.WorkOrdersInPeriod;

        $(canvas).siblings('iframe').remove();

        workOrderChart = new Chart(canvas.getContext('2d'), {
            type: 'line',
            data: {
                labels: result.Labels,
                datasets: [
                    {
                        // ReSharper disable once PossiblyUnassignedProperty
                        label: result.DataSets[0].Label,
                        fill: true,
                        lineTension: 0.3,
                        backgroundColor: 'rgba(238,144,197,0.4)',
                        borderColor: 'rgba(238,144,197,1)',
                        borderWidth: 2,
                        borderCapStyle: 'butt',
                        borderDash: [],
                        borderDashOffset: 0.0,
                        borderJoinStyle: 'round',
                        pointBorderColor: 'rgba(238,144,197,1)',
                        pointBackgroundColor: '#fff',
                        pointBorderWidth: 1,
                        pointHoverRadius: 5,
                        pointHoverBackgroundColor: 'rgba(238,144,197,1)',
                        pointHoverBorderColor: 'rgba(238,144,197,1)',
                        pointHoverBorderWidth: 2,
                        pointRadius: 1,
                        pointHitRadius: 10,
                        // ReSharper disable once PossiblyUnassignedProperty
                        data: result.DataSets[0].Data,
                        spanGaps: false
                    },
                    {
                        // ReSharper disable once PossiblyUnassignedProperty
                        label: result.DataSets[1].Label,
                        fill: true,
                        lineTension: 0.3,
                        backgroundColor: 'rgba(0,160,209,0.4)',
                        borderColor: 'rgba(0,160,209,1)',
                        borderWidth: 2,
                        borderCapStyle: 'butt',
                        borderDash: [],
                        borderDashOffset: 0.0,
                        borderJoinStyle: 'round',
                        pointBorderColor: 'rgba(0,160,209,1)',
                        pointBackgroundColor: '#fff',
                        pointBorderWidth: 1,
                        pointHoverRadius: 5,
                        pointHoverBackgroundColor: 'rgba(0,160,209,1)',
                        pointHoverBorderColor: 'rgba(0,160,209,1)',
                        pointHoverBorderWidth: 2,
                        pointRadius: 1,
                        pointHitRadius: 10,
                        // ReSharper disable once PossiblyUnassignedProperty
                        data: result.DataSets[1].Data,
                        spanGaps: false
                    }
                ]
            },
            options: {
                maintainAspectRatio: false,
                responsive: true,
                scales: {
                    yAxes: [{ ticks: { beginAtZero: true } }]
                }
            }
        });
        result = null;
    });
}})(jQuery, companyName, ProfileHelpers);

This is the listener where it calls the mouseover functionality under Chart.js:

function createEvent(type, chart, x, y, nativeEvent) {
    return {
        type: type,
        chart: chart,
        native: nativeEvent || null,
        x: x !== undefined? x : null,
        y: y !== undefined? y : null,
    };
}

function fromNativeEvent(event, chart) {
    var type = eventTypeMap[event.type] || event.type;
    var pos = helpers.getRelativePosition(event, chart);
    return createEvent(type, chart, pos.x, pos.y, event);
}

Following is the code for .NET side

public async Task<JsonResult> GetWorkOrderChartData(int targetId, TargetType targetType, int? problemId = null, DateTime? rangeStartDate = null, string search = null,
        int? tradeId = null)
    {
        JsonResult result = await JsonValidateLoginAsync(ModuleClaimTypes.Maintenance).ConfigureAwait(false);
        if (result != null)
        {
            return result;
        }

        try
        {
            // GetWorkOrderChartDataAsync calls a method in Service Class which extracts the data from DB according to the paramters passed. 
            return Json(await new MaintenanceWidgetReadService(DbContext, User)
                .GetWorkOrderChartDataAsync(new TargetInfo(targetId, targetType), problemId, search, rangeStartDate, tradeId)
                .ConfigureAwait(false));
        }
        catch (Exception ex)
        {
            await ex.LogAsync(HttpContext);
            return Json(false);
        }
    }

Solution

  • Fixed my hover issue. It was happening due to another canavas overlapping on each other.

    Had to remove the old canvas and reload the partial with a new canvas.

    Here is a reference to what I did in my JS.

    $(dateSelectors).click(function (event)
            {
                event.preventDefault();
    
                selectedDateLabel.innerHTML = this.innerHTML;
                selectedStartDate = this.getAttribute('data-wo-date');
    
    
                let canvas = $('#wo-chart');
                canvas.remove();
                 $('#graph-container').append('<canvas id="wo-chart"></canvas>');
    
    
    
                search();
            });