chartjs / Chart.js

Simple HTML5 Charts using the <canvas> tag
https://www.chartjs.org/
MIT License
64.56k stars 11.9k forks source link

Issue with tooltip: mode 'index' #8301

Closed bhavin00 closed 3 years ago

bhavin00 commented 3 years ago

Please check this code pen :- https://codepen.io/bhavin00-the-reactor/pen/abZqXWz

I used tooltip mode index. as I want only 1 tooltip item for each line, there is two line so I need 2 tooltip items (1 for each line).

When I used mode: index then It is displaying only 1 tooltip item for 1 line, but then there is issue with tooltip location some time..

I attached below image please check & help me to resolve this...

image

In above image, I am hovering before 3rd Jan place but tooltip is coming for 6th Jan...

Is there any other alternative right now. as It looks issue with mode: index

Expected Behavior

Current Behavior

Possible Solution

Steps to Reproduce

Context

Environment

kurkle commented 3 years ago

index mode works with the data index and for proper functionality each dataset has to have equal amount of data. The pen uses 2.7.3, but if you are really using 2.9.4 as you say, then you'd probably get the result you are looking for with mode: 'nearest', axis: 'x', intersect: false

edit: nvm, it only works correctly in v3.

bhavin00 commented 3 years ago

@kurkle , Is there any way to achieve this scenario in version 2.9.4?

mode: 'nearest', axis: 'x', intersect: false this is not working with 2.9.4 --> It display only 1line's tooltip not both line's

kurkle commented 3 years ago

Not sure. mode: 'x' could work.

bhavin00 commented 3 years ago

mode: 'x' is giving more than 1 tooltipItem for each line, but I need only 1 for 1 line. so mode: x is also not workaround for me....

LeeLenaleee commented 3 years ago

That is probably the same issue as #8293,

You can try to make sure both data arrays have the same x labels specified but have null values for the parts you dont want to show, should also work with mode index

bhavin00 commented 3 years ago

@LeeLenaleee , You can try to make sure both data arrays have the same x labels specified but have null values for the parts you dont want to show, should also work with mode index

---- This is very time taking in my case as there is alot of data

LeeLenaleee commented 3 years ago

You can try it with a small dataset and if it works you script it for the big one.

bhavin00 commented 3 years ago

Hey Guys,

I did 1 work around, I set, mode: x, so then there is many tooltipItems for same line,

to get only 1 tooltipItem for each line, I customized tooltip.body.

tooltips: {
        mode: 'x',
        axis: 'x',
        intersect: false,
        backgroundColor: '#FFFFFF',
        bodyFontSize: 13,
        bodyFontColor: '#333333',
        bodyFontFamily: 'Open Sans',
        titleFontColor: '#333333',
        titleFontFamily: 'Open Sans',
        titleFontStyle: 'bold',
        titleFontSize: 13,
        titleMarginBottom: 15,
        displayColors: true,
        xPadding: 15,
        yPadding: 15,
        bodySpacing: 12,
        callbacks: {
            label(tooltipItem, data) {
                let label = data.datasets[tooltipItem.datasetIndex].label || '';
                if (label) {
                    label += ' - ';
                }
                label += `${Math.round(tooltipItem.yLabel)}%`;

                return label;
            }
        },
        custom(tooltipModel) {
            if(get(tooltipModel, 'dataPoints.length', 0) > 1) {
                const dataPointIdexes = [];
                const result = [];
                const result1 = [];
                forEach(tooltipModel.dataPoints, (dp, index) => {
                    if(!includes(dataPointIdexes, dp.datasetIndex)) {
                        result.push(dp);
                        dataPointIdexes.push(dp.datasetIndex);
                        result1.push(tooltipModel.body[index]);
                    }
                });
                tooltipModel.dataPoints = result;
                tooltipModel.body = result1;
                tooltipModel.height = tooltipHeaderHeight + (tooltipItemHeight * tooltipModel.body.length);
            }
        }
    },
    hover: {
        mode: 'x',
        intersect: false
    }

Hope It will help someone.

I am closing this bug as It is already created. as per above message of @LeeLenaleee.