¿Cómo puedo acceder a un gráfico Highcharts a través de un contenedor DOM?

85

Cuando renderizo un highcharts-chart en un contenedor div, ¿cómo puedo acceder al objeto del gráfico a través del div-Container? No quiero que la variable del gráfico sea global.

        var chart = new Highcharts.Chart({
            chart: {
                renderTo: "testDivId",
                                ...

Quiero acceder al gráfico fuera del contexto anterior como este (pseudocódigo), para llamar a funciones:

var chart = Highcharts.Chart("testDivId"); //access from id
chart.redraw();
Manuel
fuente

Respuestas:

139

Highcharts 3.0.1

Los usuarios pueden usar el complemento highcharts

var chart=$("#container").highcharts();

Highcharts 2.3.4

Lea de la matriz Highcharts.charts , para la versión 2.3.4 y posteriores, el índice del gráfico se puede encontrar a partir de los datos en el<div>

 var index=$("#container").data('highchartsChart');
 var chart=Highcharts.charts[index];

Todas las versiones

Seguimiento de gráficos en un objeto / mapa global por ID de contenedor

var window.charts={}; 
function foo(){
  new Highcharts.Chart({...},function(chart){  
      window.charts[chart.options.chart.renderTo] = chart;
  });
}

function bar(){
  var chart=window.charts["containerId"];
}

Consejos para el modo de lectura @ Highcharts: acceso al objeto de gráfico desde un ID de contenedor

PD

Se hicieron algunas adiciones en las versiones más nuevas de Highcharts desde que escribí esta respuesta y se han tomado de las respuestas de @davertron, @Moes y @Przy, por favor, vote sus comentarios / respuestas, ya que merecen el crédito por estos. Agregarlos aquí, ya que esta respuesta aceptada estaría incompleta sin estos

Jugal Thakkar
fuente
10
Parece que a partir de la versión 2.3.4 Highcharts realiza un seguimiento de todos los gráficos de la página: api.highcharts.com/highcharts#Highcharts
davertron
@davertron gracias por la actualización ... es una buena característica tener, no creo que se requiera mucho código / esfuerzo para tener esto ...
Jugal Thakkar
+1 para $ ("# contenedor"). Data ('highchartsChart') como índice de highcharts. es muy útil, gracias!
Shahar
1
¿Algún método similar que pueda usar para highstock?
tnkh
45

Puedes hacerlo

var chart = $("#testDivId").highcharts();

ver ejemplo en el violinista

Nerdroid
fuente
No funcionó para mí, tuve que usar la respuesta @Frzy. Estoy usando la versión 4.1.4
David Torres
no estoy seguro de por qué no funcionó para usted, el ejemplo del violín usa v4.2.3
Nerdroid
1
Está devolviendo el elemento contenedor en lugar del gráfico, y es por eso que la respuesta de @Frzy funcionó. Además, encontré otra solución:$("#testDivId").highcharts({...}, function(chart) {...});
David Torres
definitivamente está devolviendo el objeto jsfiddle.net/abbasmhd/86hLvc5s verifique la salida de la consola después de hacer clic en el botón
Nerdroid
1
Sí, en el jsfiddle está haciendo eso, estoy de acuerdo. Pero no para todos está trabajando igual, como puede ver en los 11 votos a favor de la respuesta de @Frzy
David Torres
22
var $chartCont = $('#container').highcharts({...}),
    chartObj = Highcharts.charts[$chartCont.data('highchartsChart')];

chartCont es un objeto jQuery. chartObj es un objeto de gráfico Highchart.

Esto está usando Highcharts 3.01

Frzy
fuente
10

Simplemente con JS puro:

var obj = document.getElementById('#container')
    Highcharts.charts[obj.getAttribute('data-highcharts-chart')];
elo
fuente
9

Encontré otra forma de hacerlo ... principalmente porque estoy usando Highcharts que están incrustados en la plataforma OutSystems, y no tengo una forma de controlar la forma en que se crean los gráficos.

La forma que encontré fue la siguiente:

  1. Dar una clase de identificación al gráfico usando classNameatributo

    chart: {
        className: 'LifeCycleMasterChart'
    }
    
  2. Defina una función auxiliar para obtener el gráfico por nombre de clase

    function getChartReferenceByClassName(className) {
    var cssClassName = className;
    var foundChart = null;
    
    $(Highcharts.charts).each(function(i,chart){    
        if(chart.container.classList.contains(cssClassName)){
            foundChart = chart;
            return;
        }
    });
    
    return foundChart;
    

    }

  3. Utilice la función auxiliar donde la necesite

    var detailChart = getChartReferenceByClassName('LifeCycleDetailChart');
    

¡Espero que te ayude!

Pedro Cardoso
fuente
5

Sin jQuery (vainilla js):

let chartDom = document.getElementById("testDivId");
let chart = Highcharts.charts[Highcharts.attr(chartDom, 'data-highcharts-chart')]
Tauka Kunzhol
fuente
4
var chart1; // globally available
$(document).ready(function() {
      chart1 = new Highcharts.Chart({
         chart: {
            renderTo: 'container',
            type: 'bar'
         },
         title: {
            text: 'Fruit Consumption'
         },
         xAxis: {
            categories: ['Apples', 'Bananas', 'Oranges']
         },
         yAxis: {
            title: {
               text: 'Fruit eaten'
            }
         },
         series: [{
            name: 'Jane',
            data: [1, 0, 4]
         }, {
            name: 'John',
            data: [5, 7, 3]
         }]
      });
   });

El var chart1 es global, por lo que puede usarlo para acceder al objeto highchart, no importa cuál sea el contenedor

chart1.redraw();
manuerumx
fuente
2

... y con la ayuda de un colega ... una mejor forma de hacerlo es ...

getChartReferenceByClassName(className) {
    var foundChart = $('.' + className + '').eq(0).parent().highcharts();

    return foundChart;
}
Pedro Cardoso
fuente
1

La respuesta de @elo es correcta y votó a favor, aunque tuve que ordenarla un poco para que quede más clara:

const myChartEl = document.getElementById('the-id-name');
const myChart = Highcharts.charts[myChartEl.getAttribute('data-highcharts-chart')];

myChartluego se convierte en un objeto Highcharts en vivo que expone todos los accesorios actuales presentes en el gráfico que se representa en el myChartEl. Dado que myChartes un objeto de Highcharts , uno puede encadenar métodos de prototipo inmediatamente después, extenderlo o hacer referencia a él.

myChart.getTable();
myChart.downloadXLS();
setTimeout(() => Highcharts.fireEvent(myChart, "redraw"), 10);

También se puede obtener myCharta través .highcharts(), que es un jQueryplugin:

var myChart = $("#the-id-name").highcharts();

El enfoque del jQuerycomplemento anterior requiere jQueryque se cargue antes de que se use el complemento y, por supuesto, el complemento en sí. Fue la ausencia de este complemento lo que me llevó a buscar formas alternativas de lograr lo mismo con JavaScript puro.

Al utilizar el enfoque JS puro, pude hacer lo que necesitaba (el segundo fragmento de código) sin tener que depender dejQuery :

Wallace Sidhrée
fuente