tipos personalizar google configurar columns chart javascript web google-visualization

javascript - configurar - personalizar google chart



Insertar enlaces en los datos de API de Google Charts? (6)

He estado jugando un poco con los gráficos de Google en el juego de cartas de Google aquí:

Enlazar

El código con el que he estado jugando es este:

function drawVisualization() { // Create and populate the data table. var data = google.visualization.arrayToDataTable([ [''Year'', ''Austria''], [''2003'', 1336060], [''2004'', 1538156], [''2005'', 1576579], [''2006'', 1600652], [''2007'', 1968113], [''2008'', 1901067] ]); // Create and draw the visualization. new google.visualization.BarChart(document.getElementById(''visualization'')). draw(data, {title:"Yearly Coffee Consumption by Country", width:600, height:400, vAxis: {title: "Year"}, hAxis: {title: "Cups"}} ); }

y eso me da un buen cuadro que se ve así:

Estoy intentando que esta tabla se ajuste a las necesidades de mi sitio web, y para hacer esto, necesito hacer que los nombres de las barras estén en los enlaces de la izquierda de otra página. Entonces, por ejemplo, 2003 sería un enlace en el que el usuario puede hacer clic, así como 2004, etc.

Traté de hacer algo como esto:

function drawVisualization() { // Create and populate the data table. var data = google.visualization.arrayToDataTable([ [''Year'', ''Austria''], [''<a href="url">Link text</a>'', 1336060], [''2004'', 1538156], [''2005'', 1576579], [''2006'', 1600652], [''2007'', 1968113], [''2008'', 1901067] ]); // Create and draw the visualization. new google.visualization.BarChart(document.getElementById(''visualization'')). draw(data, {title:"Yearly Coffee Consumption by Country", width:600, height:400, vAxis: {title: "Year"}, hAxis: {title: "Cups"}} ); }

Pero solo podía esperar que fuera así de fácil y no lo fue. ¿Alguien sabe si esto es posible?


Dado que la ruta de inserción de SVG es (comprensiblemente) demasiado peluda para que la quieras mezclar, probemos un enfoque completamente diferente. Suponiendo que tenga la flexibilidad de alterar un poco su especificación funcional, de manera que se pueda hacer clic en las barras , no en las etiquetas , aquí hay una solución mucho más simple que funcionará.

Busque la alert en este fragmento, esa es la parte que personalizará para hacer la redirección.

function drawVisualization() { // Create and populate the data table. var rawData = [ [''Year'', ''Austria''], [''2003'', 1336060], [''2004'', 1538156], [''2005'', 1576579], [''2006'', 1600652], [''2007'', 1968113], [''2008'', 1901067] ]; var data = google.visualization.arrayToDataTable(rawData); // Create and draw the visualization. var chart = new google.visualization.BarChart(document.getElementById(''visualization'')); chart.draw(data, {title:"Yearly Coffee Consumption by Country", width:600, height:400, vAxis: {title: "Year"}, hAxis: {title: "Cups"}} ); var handler = function(e) { var sel = chart.getSelection(); sel = sel[0]; if (sel && sel[''row''] && sel[''column'']) { var year = rawData[sel[''row''] + 1][0]; alert(year); // This where you''d construct the URL for this row, and redirect to it. } } google.visualization.events.addListener(chart, ''select'', handler); }


Esto no es trivial porque la salida que está viendo es SVG, no HTML. Esas etiquetas en su ejemplo ("2004", "2005", etc.) están incrustadas dentro de los nodos de texto SVG, por lo que insertar el marcado HTML sin procesar no se representará como HTML.

La solución es buscar los nodos de texto que contienen los valores objetivo (de nuevo, "2004", "2005", etc.) y reemplazarlos con elementos ForeignObject . ForeignObject elementos ForeignObject pueden contener HTML normal. Estos deben posicionarse más o menos donde habían estado los nodos originales de texto SVG.

Aquí hay un fragmento de muestra que ilustra todo esto. Está sintonizado para su ejemplo específico, por lo que cuando cambie a la representación sean cuales sean sus datos reales, querrá modificar y generalizar este fragmento en consecuencia.

// Note: You will probably need to tweak these deltas // for your labels to position nicely. var xDelta = 35; var yDelta = 13; var years = [''2003'',''2004'',''2005'',''2006'',''2007'',''2008'']; $(''text'').each(function(i, el) { if (years.indexOf(el.textContent) != -1) { var g = el.parentNode; var x = el.getAttribute(''x''); var y = el.getAttribute(''y''); var width = el.getAttribute(''width'') || 50; var height = el.getAttribute(''height'') || 15; // A "ForeignObject" tag is how you can inject HTML into an SVG document. var fo = document.createElementNS("http://www.w3.org/2000/svg", "foreignObject") fo.setAttribute(''x'', x - xDelta); fo.setAttribute(''y'', y - yDelta); fo.setAttribute(''height'', height); fo.setAttribute(''width'', width); var body = document.createElementNS("http://www.w3.org/1999/xhtml", "BODY"); var a = document.createElement("A"); a.href = "http://yahoo.com"; a.setAttribute("style", "color:blue;"); a.innerHTML = el.textContent; body.appendChild(a); fo.appendChild(body); // Remove the original SVG text and replace it with the HTML. g.removeChild(el); g.appendChild(fo); } });

Nota menor, hay un poco de jQuery allí por conveniencia, pero puede reemplazar $(''text'') con document.getElementsByTagName("svg")[0].getElementsByTagName("text") .


Aparentemente, no tengo suficientes puntos de reputación para comentar directamente una respuesta anterior, así que mis disculpas por hacerlo como una nueva publicación. La sugerencia de manzoid es genial, pero tiene un problema que encontré, y parece que Mark Butler podría haberse encontrado con el mismo problema (o haberlo eludido sin saberlo).

if (sel && sel[''row''] && sel[''column'']) {

Esa línea evita que se pueda hacer clic en el primer punto de datos. Lo usé en un gráfico de barras de enero a diciembre, y solo se pudo hacer clic en febrero-diciembre. Al eliminar sel [''row''] de la condición, Jan puede trabajar. Sin embargo, no sé si la condición if () es realmente necesaria.


La respuesta de Manzoid es buena, pero "todavía se necesita algún ensamblaje", ya que solo muestra un cuadro de alerta en lugar de seguir el enlace. Aquí hay una respuesta más completa PERO hace que las barras se puedan hacer clic en lugar de las etiquetas. Creo un DataTable que incluye los enlaces y luego creo un DataView para seleccionar las columnas que quiero mostrar. Luego, cuando se produce el evento select, simplemente recupero el enlace de la DataTable original.

<html> <head> <script type="text/javascript" src="https://www.google.com/jsapi"></script> <script type="text/javascript"> google.load("visualization", "1", {packages:["corechart"]}); google.setOnLoadCallback(drawChart); function drawChart() { var data = google.visualization.arrayToDataTable([ [''Year'', ''link'', ''Austria''], [''2003'', ''http://en.wikipedia.org/wiki/2003'', 1336060], [''2004'', ''http://en.wikipedia.org/wiki/2004'', 1538156], [''2005'', ''http://en.wikipedia.org/wiki/2005'', 1576579], [''2006'', ''http://en.wikipedia.org/wiki/2006'', 1600652], [''2007'', ''http://en.wikipedia.org/wiki/2007'', 1968113], [''2008'', ''http://en.wikipedia.org/wiki/2008'', 1901067] ]); var view = new google.visualization.DataView(data); view.setColumns([0, 2]); var options = {title:"Yearly Coffee Consumption by Country", width:600, height:400, vAxis: {title: "Year"}, hAxis: {title: "Cups"}}; var chart = new google.visualization.BarChart( document.getElementById(''chart_div'')); chart.draw(view, options); var selectHandler = function(e) { window.location = data.getValue(chart.getSelection()[0][''row''], 1 ); } google.visualization.events.addListener(chart, ''select'', selectHandler); } </script> </head> <body> <div id="chart_div" style="width: 900px; height: 900px;"></div> </body> </html>


Deberías usar formateadores .

Si reemplaza el valor con HTML, la clasificación no funcionará correctamente.


Aquí hay otra solución que envuelve cada etiqueta de texto para etiqueta con etiqueta de anclaje.

  • no ForeignObject
  • etiqueta que se puede hacer clic
  • estilo por css (efecto de desplazamiento)

Aquí hay un ejemplo: https://jsfiddle.net/tokkonoPapa/h3eq9m9p/

/* find the value in array */ function inArray(val, arr) { var i, n = arr.length; val = val.replace(''…'', ''''); // remove ellipsis for (i = 0; i < n; ++i) { if (i in arr && 0 === arr[i].label.indexOf(val)) { return i; } } return -1; } /* add a link to each label */ function addLink(data, id) { var n, p, info = [], ns = ''hxxp://www.w3.org/1999/xlink''; // make an array for label and link. n = data.getNumberOfRows(); for (i = 0; i < n; ++i) { info.push({ label: data.getValue(i, 0), link: data.getValue(i, 2) }); } $(''#'' + id).find(''text'').each(function(i, elm) { p = elm.parentNode; if (''g'' === p.tagName.toLowerCase()) { i = inArray(elm.textContent, info); if (-1 !== i) { /* wrap text tag with anchor tag */ n = document.createElementNS(''hxxp://www.w3.org/2000/svg'', ''a''); n.setAttributeNS(ns, ''xlink:href'', info[i].link); n.setAttributeNS(ns, ''title'', info[i].label); n.setAttribute(''target'', ''_blank''); n.setAttribute(''class'', ''city-name''); n.appendChild(p.removeChild(elm)); p.appendChild(n); info.splice(i, 1); // for speeding up } } }); } function drawBasic() { var data = google.visualization.arrayToDataTable([ [''City'', ''2010 Population'', {role: ''link''}], [''New York City, NY'', 8175000, ''hxxp://google.com/''], [''Los Angeles, CA'', 3792000, ''hxxp://yahoo.com/'' ], [''Chicago, IL'', 2695000, ''hxxp://bing.com/'' ], [''Houston, TX'', 2099000, ''hxxp://example.com''], [''Philadelphia, PA'', 1526000, ''hxxp://example.com''] ]); var options = {...}; var chart = new google.visualization.BarChart( document.getElementById(''chart_div'') ); chart.draw(data, options); addLink(data, ''chart_div''); }