I'm trying to add some pizazz to a Google ColumnChart by adding a gradient to the SVG rects that are drawn for the columns. The code below will add gradients to the iframe svg>defs and replace the fill attribute of the rects correctly in all the browsers I care about at this moment (later versions of Firefox, IE and Chrome).
My problem is that whenever I hover over or select a bar (or the legend), the color is reset back to the original color. I'm an SVG noob and I haven't been able to figure how, where or what is resetting the color.
So my question is does anyone know how (using javascript/jquery) to stop, overwrite or someway manipulate the code that resets the colors? I would prefer to keep the 'interactive' parts intact (tooltip, etc.) if possible.
<!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
So while looking through the DOM to see if I could find where these color codes might be stored (and there by find the functions that are using them), I did find these (which when set will do what I want):
//fill
visualization.qa.l.e[0].Hm.O = "url(#blue)";
visualization.qa.l.e[1].Hm.O = "url(#red)";
visualization.qa.l.e[2].Hm.O = "url(#green)";
// stroke
visualization.qa.l.e[0].Hm.Jb = "#000000";
visualization.qa.l.e[1].Hm.Jb = "#000000";
visualization.qa.l.e[2].Hm.Jb = "#000000";
// fill-opacity
//visualization.qa.l.e[0].Hm.$b = 0.5;
//visualization.qa.l.e[1].Hm.$b = 0.5;
//visualization.qa.l.e[2].Hm.$b = 0.5;
// stroke-width
visualization.qa.l.e[0].Hm.H = 0.4;
visualization.qa.l.e[1].Hm.H = 0.4;
visualization.qa.l.e[2].Hm.H = 0.4;
// stroke-opacity
//visualization.qa.l.e[0].Hm.nc = 0.5;
//visualization.qa.l.e[1].Hm.nc = 0.5;
//visualization.qa.l.e[2].Hm.nc = 0.5;
but this would be only a temporary solution as I'm sure the next time Google updates the Visualization code, these variable names will change (I don't think someone choose these on purpose and the compressor/obfuscator used would probably pick different variable names next time - but then who knows - maybe it won't).
So if anyone knows of a more permanent way that doesn't depend on manually finding and setting the variable names, I would love it. Otherwise, this may be my best bet for now.
UPDATE2 (March 1, 2012)
Case in point. The variables are now moved:
//fill
visualization.da.C.d[0].en.S = "url(#blue)";
MutationObserver
– Berman