Adding a gradient to a ColumnChart Google visualization

I am trying to add some pizazz to a Google ColumnChart by adding a gradient to the SVG rectangles that are drawn for the columns. The code below will add gradients to iframe svg> defs and correctly replace the fill the rects attribute in all browsers that concern me at the moment (later versions of Firefox, IE and Chrome).

My problem is that whenever I hang or select a panel (or legend), the reset color returns to its original color. I am an SVG noob, and I could not understand how, where and what color reset occurs.

So my question is: does anyone know how (using javascript / jquery) to stop, overwrite, or somehow manipulate code that resets colors? I would prefer, if possible, the "interactive" details intact (tooltip, etc.).

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <title>Google Visualization API Sample</title> <script type="text/javascript" src="http://www.google.com/jsapi"></script> <script type="text/javascript"> google.load('visualization', '1', {packages: ['corechart']}); google.load("jquery", "1.7.1"); </script> <script type="text/javascript"> function drawVisualization() { // Create and populate the data table. var data = new google.visualization.DataTable(); var rowData = [['Year', 'North', 'West', 'South'], ['2010', 197, 333, 298 ], ['2011', 167, 261, 381 ]]; var data = google.visualization.arrayToDataTable(rowData); visualization = new google.visualization.ColumnChart(document.getElementById('visualization')); google.visualization.events.addListener(visualization, 'ready', function(){ var svgns = "http://www.w3.org/2000/svg"; var gradients = [["red","#C0504D","#E6B8B7"], ["green","#9BBB59","#D8E4BC"], ["blue","#4F81BD","DCE6F1"]]; var svg_defs = $("#visualization iframe").contents().find('defs'); // add gradients to svg defs for(var i = 0; i < gradients.length; i++){ var grad = $(document.createElementNS(svgns, "linearGradient")). attr({id:gradients[i][0],x1:"0%",x2:"0%",y1:"0%",y2:"100%"}); var stopTop = $(document.createElementNS(svgns, "stop")). attr({offset:"0%","stop-color":gradients[i][1]}); var stopBottom = $(document.createElementNS(svgns, "stop")). attr({offset:"100%","stop-color":gradients[i][2]}); $(grad).append(stopTop).append(stopBottom); svg_defs.append(grad); } // #3366cc, #dc3912, #ff9900 - replace default colors with gradients $("#visualization iframe").contents().find('rect[fill="#3366cc"]').attr({'fill':'url(#blue)','stroke-width':0.4,'stroke':'#000000'}); $("#visualization iframe").contents().find('rect[fill="#dc3912"]').attr({'fill':'url(#blue)','stroke-width':0.4,'stroke':'#000000'}); $("#visualization iframe").contents().find('rect[fill="#ff9900"]').attr({'fill':'url(#blue)','stroke-width':0.4,'stroke':'#000000'}); }); // Create and draw the visualization. visualization.draw(data,{width:600, height:400}); } google.setOnLoadCallback(drawVisualization); </script> </head> <body style="font-family: Arial;border: 0 none;"> <div id="visualization" style="width: 600px; height: 400px;"></div> </body> </html> 

UPDATE

Therefore, looking through the DOM to find out if I can find where these color codes can be stored (and there, finding the functions that use them), I found them (which when the set will do what I want):

  //fill visualization.qa.le[0].Hm.O = "url(#blue)"; visualization.qa.le[1].Hm.O = "url(#red)"; visualization.qa.le[2].Hm.O = "url(#green)"; // stroke visualization.qa.le[0].Hm.Jb = "#000000"; visualization.qa.le[1].Hm.Jb = "#000000"; visualization.qa.le[2].Hm.Jb = "#000000"; // fill-opacity //visualization.qa.le[0].Hm.$b = 0.5; //visualization.qa.le[1].Hm.$b = 0.5; //visualization.qa.le[2].Hm.$b = 0.5; // stroke-width visualization.qa.le[0].Hm.H = 0.4; visualization.qa.le[1].Hm.H = 0.4; visualization.qa.le[2].Hm.H = 0.4; // stroke-opacity //visualization.qa.le[0].Hm.nc = 0.5; //visualization.qa.le[1].Hm.nc = 0.5; //visualization.qa.le[2].Hm.nc = 0.5; 

but this would only be a temporary solution, as Iโ€™m sure that the next time Google updates the visualization code, these variable names will change (I donโ€™t think that someone selects them specifically, and the compressor / obfuscator used will probably be choose different variable names next time - but then who knows - maybe it wonโ€™t).

So, if anyone knows a more permanent way that does not depend on manually searching and setting variable names, I would like it. Otherwise, this may be my best choice at the moment.

UPDATE2 (March 1, 2012)

Case in point. Now the variables are moved:

  //fill visualization.da.Cd[0].en.S = "url(#blue)"; 
+7
source share
1 answer

you can use MutationObserver to know when svg changes were made

move code from 'ready' event listener to observer
to rewrite code that resets colors

as in the next fragment ...

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <title>Google Visualization API Sample</title> <script type="text/javascript" src="http://www.google.com/jsapi"></script> <script type="text/javascript"> google.load('visualization', '1', {packages: ['corechart']}); google.load("jquery", "1.7.1"); </script> <script type="text/javascript"> function drawVisualization() { // Create and populate the data table. var data = new google.visualization.DataTable(); var rowData = [['Year', 'North', 'West', 'South'], ['2010', 197, 333, 298 ], ['2011', 167, 261, 381 ]]; var data = google.visualization.arrayToDataTable(rowData); var chartDiv = document.getElementById('visualization'); visualization = new google.visualization.ColumnChart(); // observe changes to the chart container var observer = new MutationObserver(function () { var svgns = "http://www.w3.org/2000/svg"; var gradients = [["red","#C0504D","#E6B8B7"], ["green","#9BBB59","#D8E4BC"], ["blue","#4F81BD","DCE6F1"]]; var svg_defs = $("#visualization iframe").contents().find('defs'); // add gradients to svg defs for(var i = 0; i < gradients.length; i++){ var grad = $(document.createElementNS(svgns, "linearGradient")). attr({id:gradients[i][0],x1:"0%",x2:"0%",y1:"0%",y2:"100%"}); var stopTop = $(document.createElementNS(svgns, "stop")). attr({offset:"0%","stop-color":gradients[i][1]}); var stopBottom = $(document.createElementNS(svgns, "stop")). attr({offset:"100%","stop-color":gradients[i][2]}); $(grad).append(stopTop).append(stopBottom); svg_defs.append(grad); } // #3366cc, #dc3912, #ff9900 - replace default colors with gradients $("#visualization iframe").contents().find('rect[fill="#3366cc"]').attr({'fill':'url(#blue)','stroke-width':0.4,'stroke':'#000000'}); $("#visualization iframe").contents().find('rect[fill="#dc3912"]').attr({'fill':'url(#blue)','stroke-width':0.4,'stroke':'#000000'}); $("#visualization iframe").contents().find('rect[fill="#ff9900"]').attr({'fill':'url(#blue)','stroke-width':0.4,'stroke':'#000000'}); }); observer.observe(chartDiv, { childList: true, subtree: true }); // Create and draw the visualization. visualization.draw(data,{width:600, height:400}); } google.setOnLoadCallback(drawVisualization); </script> </head> <body style="font-family: Arial;border: 0 none;"> <div id="visualization" style="width: 600px; height: 400px;"></div> </body> </html> 
0
source

All Articles