Добавление градиента в Google-визуализацию ColumnChart - PullRequest
7 голосов
/ 09 февраля 2012

Я пытаюсь добавить некоторые стили в Google ColumnChart, добавив градиент к строкам SVG, которые нарисованы для столбцов. Приведенный ниже код добавит градиенты в iframe svg> defs и правильно заменит атрибут fill для rects во всех браузерах, которые мне нужны в данный момент (более поздние версии Firefox, IE и Chrome).

Моя проблема в том, что всякий раз, когда я наводю курсор мыши или выбираю полосу (или легенду), цвет сбрасывается обратно к исходному цвету. Я новичок SVG, и я не смог понять, как, где или что сбрасывает цвет.

Итак, мой вопрос: кто-нибудь знает, как (используя javascript / jquery) остановить, перезаписать или каким-либо образом манипулировать кодом, который сбрасывает цвета? Я бы предпочел сохранить «интерактивные» части без изменений (всплывающие подсказки и т. Д.), Если это возможно.

<!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

Поэтому, просматривая DOM, чтобы посмотреть, смогу ли я найти, где эти цветовые коды могут храниться (и там найти функции, которые их используют), я нашел их (которые при установке будут делать то, что я хочу):

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

но это было бы только временным решением, так как я уверен, что в следующий раз, когда Google обновит код визуализации, эти имена переменных изменятся (я не думаю, что кто-то выберет их специально, и используемый компрессор / обфускатор, вероятно, выберет другие имена переменных в следующий раз, но кто знает, может, и не будет).

Так что, если кто-нибудь знает о более постоянном способе, который не зависит от ручного поиска и установки имен переменных, мне бы это понравилось. В противном случае, это может быть моим лучшим выбором на данный момент.

ОБНОВЛЕНИЕ2 (1 марта 2012 г.)

Показательный пример. Переменные теперь перемещены:

      //fill
      visualization.da.C.d[0].en.S = "url(#blue)";

1 Ответ

0 голосов
/ 19 ноября 2016

вы можете использовать MutationObserver, чтобы узнать, когда были внесены изменения в svg

, переместить код из прослушивателя событий 'ready' в observer
на , перезаписатькод, который сбрасывает цвета

, как в следующем фрагменте ...

<!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>
...