2011-07-07 34 views
21

De manera predeterminada, Highcharts le permite hacer clic en un conjunto de series de datos para ocultarlo/mostrarlo.Serie Highcharts: quiere mostrar/ocultar todas EXCEPTO las series seleccionadas (inversión de la lógica predeterminada)

Un enfoque mucho más útil sería hacer la lógica inversa, es decir, mostrar solo las series seleccionadas y ocultar/mostrar las no seleccionadas.

Mirando el ejemplo aquí (http://jsfiddle.net/t2MxW/14/), es una clara puede 'intercepción' caso de que el del 'legendItemClick', simplemente no estoy seguro de cómo implementar el requerir la lógica

Uno puede sustituir a la secuencia de comandos siguiente para obtener 3 conjuntos de datos.

ESCENARIO DESEADO: para poder hacer clic en 'manzanas' y mostrar/ocultar 'peras' y 'naranjas', por ejemplo.

================= PASTE COMIENZO ======================== ============

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]} 
      ] 

}); 

Respuesta

44

Cada evento en Highcharts contiene this valor que contiene elemento actual (serie en este caso). Puede seleccionar todas las series usando this.chart.series y manejarlas de la forma que desee. Prueba esta función.

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; 
} 

violín: http://jsfiddle.net/t2MxW/12908/

+0

Veo que tienes si devuelve true (this.visible!); Esto no parece funcionar: puedo hacer clic en una serie 'oculta'. – Ian

+0

CORREGIDO - si (! This.visible) devuelve FALSO; Gracias a un millón: ¡la solución es brillante! :) – Ian

+0

Creo que 'return true' es el comportamiento correcto –

2

Sólo compartir respuesta causa de @ Igor no funciona en mí, así que hizo ajustes, aquí está el violín (en forma de horquilla de la respuesta de la @ de Igor)

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

+2

He arreglado el violín mencionado en esta respuesta, con la nueva ubicación para highcharts.js http://jsfiddle.net/philfreo/Nkeep/85/ – philfreo

+0

@philfreo Sería mejor si pudiéramos ver todos los datos al inicio y poder alternar. – dresh

1

Si desea mantener la funcionalidad normal pero también poder mostrar/ocultar todo, cree un botón o un enlace para un método de show_all()/hide_all() javascript.

este método inicializa un contador y comienza la proyección/ocultación:

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 razón de hacer esto en vez de hacer $.each(your_chart, function(i,v){v.hide()}) es que encierra la interfaz de usuario - usando el tiempo de espera en realidad se verá el las series se ocultan una a una, y si quiere modificar algo más, como un medidor de proceso, en realidad funcionará.

1

La respuesta del índice bifurcado y la funcionalidad añadida para tener alternadores individuales para cada serie. http://jsfiddle.net/c4Zd8/1/

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

¿no estás simplemente replicando la funcionalidad incorporada? – philfreo

7

que quería hacer algo similar ... Yo quería tenerlo de manera que si el control de clic (o cmd clic) un elemento de leyenda, sería ocultar todos los demás elementos. (Pero deje clics normales como su comportamiento predeterminado).

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; 
       } 
      } 
     } 
    } 
} 
+4

Funciona perfectamente gracias! Utilicé 'e.browserEvent.metaKey || e.browserEvent.ctrlKey' para incluir usuarios de Windows – satyadeepk

+0

nice, funciona perfectamente !! – dresh

+1

actualizado para incluir @satyadeepk además https://jsfiddle.net/derekrezek/Nkeep/109/ – dresh

0

Bifurcado porque quería cambiar el comportamiento. Originalmente, cuando un usuario seleccionaba dos series y luego intentaba deseleccionar una ... toda la serie intercambiaba visibilidad. Compruebo para ver si todas las demás series son "todo lo demás visible" o "todo lo demás no visible" primero antes de intercambiar la visibilidad de la serie.

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 
}, 
Cuestiones relacionadas