Oliver
Oliver

Reputation: 111

How can I trigger the hover mode from outside the chart with charts.js 2?

I would like to reproduce the hover behavior on multiple charts at the same time by clicking a button. I was thinking of putting the equivalent button id to the graphic labels.

How it will look like

For example, by clicking on the orange button (Cf. attached image), I get his ID and I would like to trigger the event hover in each orange item of each chart (which having a label identical to button's id).

I can detect which item has a label equivalent to my id, but I do not know how to replicate the hover's behavior on it.

Is there a way to force to set the hover mode active on an items in charts?

MY HTML:

<div class="graph">
  <canvas id="ctx"></canvas>
  <button type="button" class="btn btn-primary" id="OCG">Test</button>
</div>

MY JS:

var ctx = document.getElementById('ctx').getContext('2d');
var ocacolor = '#EE8B54',
    ocbcolor = '#C2B49B',
    ocbacolor = '#AECF86',
    ocgcolor = '#E97676',
    ocpcolor = '#088DA5';
var backgroundcolor = [ocacolor, ocbcolor, ocbacolor, ocgcolor, ocpcolor]

data = {
    datasets: [{
        data: [1, 1, 1, 4, 1],
        backgroundColor: backgroundcolor
    }],
    labels: [
        'OCA',
        'OCB',
        'OCBA',
        'OCG',
        'OCP'
    ]
};

//CREATING CHART
var myDoughnutChart = new Chart(ctx, {
    type: 'doughnut',
    data: data,
    options: {
        legend: {
            display: false
        },
        onClick : function(evt,dataset){
            //I GET THE LABEL TEXT OF THE CLICKED ITEM
          console.log(dataset[0]._model.label);
        }
    }
});

$("#OCG").click(function(){
  var plop = this.id
  myDoughnutChart.data.labels.forEach(function(element) {
    if (element == plop) {
      //GET THIS ITEM ID AND PUT IT ON HOVER MODE
    }
  });
})

Here's a fiddle with the code: https://jsfiddle.net/8wye9vL4/28/

Upvotes: 5

Views: 3551

Answers (1)

gaetanoM
gaetanoM

Reputation: 42044

If you are looking for a way to show a tooltip for a specific element by clicking on a button you may take a look to github or SO

I changed a bit the code I found there just to let you show a tooltip on button click.

I added a property to your options in Chartjs:

showMyTooltips: '',

This must contain the index of the tooltip to be shown. This value is used inside the registered plugin like in the example code whose links are reported in this answer.

Here is the snippet:

Chart.pluginService.register({
    beforeRender: function (chart) {
        if (!!chart.config.options.showMyTooltips && chart.config.options.showMyTooltips.trim().length != 0) {
            chart.pluginTooltips = [];
            chart.config.options.showMyTooltips.trim().split(',').forEach(function (ele, idx) {
                var sector = chart.getDatasetMeta(0).data[ele];
                chart.pluginTooltips.push(new Chart.Tooltip({
                    _chart: chart.chart,
                    _chartInstance: chart,
                    _data: chart.data,
                    _options: chart.options.tooltips,
                    _active: [sector]
                }, chart));
            });
        }
    },
    afterDraw: function (chart, easing) {
        if (chart.config.options.showMyTooltips) {
            // we don't want the permanent tooltips to animate, so don't do anything till the animation runs atleast once
            if (!chart.allTooltipsOnce) {
                if (easing !== 1)
                    return;
                chart.allTooltipsOnce = true;
            }
            Chart.helpers.each(chart.pluginTooltips, function (tooltip) {
                tooltip.initialize();
                tooltip.update();
                // we don't actually need this since we are not animating tooltips
                tooltip.pivot();
                tooltip.transition(easing).draw();
            });
        }
    }
});

var ctx = document.getElementById('ctx').getContext('2d');
var ocacolor = '#EE8B54',
        ocbcolor = '#C2B49B',
        ocbacolor = '#AECF86',
        ocgcolor = '#E97676',
        ocpcolor = '#088DA5';
var backgroundcolor = [ocacolor, ocbcolor, ocbacolor, ocgcolor, ocpcolor]

data = {
    datasets: [{
        data: [5, 2, 3, 9, 2],
        backgroundColor: backgroundcolor
    }],
    labels: [
        'OCA',
        'OCB',
        'OCBA',
        'OCG',
        'OCP'
    ]
};
//CREATING CHART
var myDoughnutChart = new Chart(ctx, {
    type: 'doughnut',
    data: data,
    options: {
        legend: {
            display: false
        },
        showMyTooltips: '',
        onClick: function (evt, dataset) {
            //I GET THE LABEL TEXT OF THE CLICKED ITEM
            console.log(dataset[0]._model.label);
        }
    }
});

$(":radio").on('change', function (e) {
    myDoughnutChart.options.showMyTooltips = myDoughnutChart.data.labels.indexOf(this.id).toString();
    myDoughnutChart.update(true);
})
.graph{
    height: 500px;
    width: 500px;
    text-align: center;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>


<div class="graph">
    <canvas id="ctx"></canvas>
    <div class="btn-group btn-group-toggle" data-toggle="buttons">
        <label class="btn btn-secondary">
            <input type="radio" name="options" id="OCA" autocomplete="off"> Test OCA
        </label>
        <label class="btn btn-secondary">
            <input type="radio" name="options" id="OCB" autocomplete="off"> Test OCB
        </label>
        <label class="btn btn-secondary">
            <input type="radio" name="options" id="OCBA" autocomplete="off"> Test OCBA
        </label>
        <label class="btn btn-secondary">
            <input type="radio" name="options" id="OCG" autocomplete="off"> Test OCG
        </label>
        <label class="btn btn-secondary">
            <input type="radio" name="options" id="OCP" autocomplete="off"> Test OCP
        </label>
    </div>
</div>

Upvotes: 2

Related Questions