web-dev-qa-db-fra.com

Highcharts Series - souhaitez afficher / masquer toutes les séries sélectionnées SAUF (inversion de la logique par défaut)

Par défaut, Highcharts vous permet de cliquer sur un ensemble de séries de données pour le masquer/afficher.

Une approche beaucoup plus utile consisterait à faire la logique inverse - c'est-à-dire à n'afficher que la série sélectionnée et à masquer/afficher les éléments non sélectionnés.

En regardant l'exemple ici ( http://jsfiddle.net/t2MxW/14/ ), il est clair que l'on peut "intercepter" l'événement "legendItemClick", je ne suis tout simplement pas sûr de savoir comment mettre en œuvre la logique requise

On peut remplacer le script ci-dessous pour obtenir 3 ensembles de données.

SCÉNARIO DÉSIRÉ: pouvoir cliquer sur 'pommes' et afficher/masquer 'poires' et 'oranges' par exemple.

================= PASTE START =============================== ========

var chart = new Highcharts.Chart({
    chart: {
        renderTo: 'container'
    },
    xAxis: {
        categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    },

    plotOptions: {
        series: {
            events: {
                legendItemClick: function(event) {
                    var visibility = this.visible ? 'visible' : 'hidden';
                    if (!confirm('The series is currently '+ 
                                 visibility +'. Do you want to change that?')) {
                        return false;
                    }
                }
            }
        }
    },

    series:[{name: 'apples',
            data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]},
    {name:'pears',
    data: [19.9, 81.5, 96.4, 119.2, 124.0, 166.0, 155.6, 138.5, 116.4, 144.1, 95.6, 54.4]},

           {name:'oranges',
    data: [119.9, 181.5, 46.4, 219.2, 24.0, 66.0, 255.6, 238.5, 16.4, 44.1, 95.6, 54.4]}
           ]   

});
28
Ian

Chaque événement dans HighCharts contient this valeur qui contient l'élément actuel (série dans ce cas). Vous pouvez sélectionner toutes les séries à l'aide de this.chart.series et gérez-les comme vous le souhaitez. Essayez cette fonction.

legendItemClick: function(event) {
    if (!this.visible)
        return false;

    var seriesIndex = this.index;
    var series = this.chart.series;

    for (var i = 0; i < series.length; i++)
    {
        if (series[i].index != seriesIndex)
        {
            series[i].visible ?
            series[i].hide() :
            series[i].show();
        } 
    }
    return false;
}

violon: https://jsfiddle.net/t2MxW/21971/

46
Igor Dymov

Je voulais faire quelque chose de similaire ... Je voulais l'avoir pour que si vous contrôlez-cliquez (ou cliquez sur cmd) un élément de légende, il cacherait TOUS LES AUTRES éléments. (Mais laissez les clics normaux comme comportement par défaut).

plotOptions: {
    series: {
        events: {
            legendItemClick: function(e) {
                // Upon cmd-click of a legend item, rather than toggling visibility, we want to hide all other items.
                var hideAllOthers = e.browserEvent.metaKey;
                if (hideAllOthers) {
                    var seriesIndex = this.index;
                    var series = this.chart.series;

                    for (var i = 0; i < series.length; i++) {
                        // rather than calling 'show()' and 'hide()' on the series', we use setVisible and then
                        // call chart.redraw --- this is significantly faster since it involves fewer chart redraws
                        if (series[i].index === seriesIndex) {
                            if (!series[i].visible) series[i].setVisible(true, false);
                        } else {
                            if (series[i].visible) series[i].setVisible(false, false);
                        }
                    }
                    this.chart.redraw();
                    return false;
                }
            }
        }
    }
}
9
philfreo

Le simple partage de la réponse de @ igor ne fonctionne pas sur moi, j'ai donc fait des ajustements, voici le violon (tiré de la réponse de @ igor)

http://jsfiddle.net/index/Nkeep/

2
index

Si vous souhaitez conserver les fonctionnalités normales tout en étant capable de tout afficher/masquer, créez un bouton ou un lien pour une méthode show_all()/hide_all() javascript.

cette méthode initialise un compteur et démarre l'affichage/masquage:

counter = 0;
setTimeout(process_hide, 1);

function process_hide()
{
    your_chart.series[counter].hide();
    counter+=1;
    if (counter < read_chart.series.length) {
        setTimeout(process_hide, 1);
    }
}

La raison pour laquelle vous faites cela au lieu de simplement faire $.each(your_chart, function(i,v){v.hide()}) est qu'elle verrouille l'interface utilisateur - en utilisant le délai d'attente, vous verrez en fait la série cachée une par une - et si vous souhaitez modifier autre chose - comme un compteur de processus, cela fonctionnera réellement.

1
Bjorn

Réponse de l'index fourchu et fonctionnalité ajoutée pour avoir des bascules individuelles pour chaque série. http://jsfiddle.net/c4Zd8/1/

$.each(allSeries, function(index, series) {
    if (selected == index) {
        if (series.visible == true) {
            series.hide();
        }
        else {
            series.show();
        }
    }
});
1
IceWarrior353

Forked parce que je voulais que le comportement change. À l'origine, lorsqu'un utilisateur sélectionnait deux séries, puis tentait d'en désélectionner une ... toute la série échangerait la visibilité. Je vérifie si toutes les autres séries sont "tout le reste visible" ou "tout le reste non visible" avant d'échanger la visibilité de la série.

http://jsfiddle.net/nd0dcdmz/3/

legendItemClick: function(e) {
    var seriesIndex = this.index;
    var series = this.chart.series;

    // test for if all other series besides one selected are visible or not visible
    var allElseVisible = series.every(
      s => (s.index == seriesIndex ? true : s.visible),
    );
    var allElseNotVisible = series.every(
      s => (s.index == seriesIndex ? true : !s.visible),
    );

    // if everything else is deselected or selected ... swap visibility
    // else swap the visibility of selected object.
    if (allElseVisible || allElseNotVisible) {
      series.map(s => {
        if (s.index != seriesIndex) {
          s.visible ? s.hide() : s.show();
        }
      });
    } else {
      return true;
    }

    return false; // overrides default behavior
},
0
Cyrus Dukart