Как написать собственный модуль форматирования для Google DataTables (для использования в API визуализации)

Я хочу отформатировать свои данные, в которых я заменяю числа значками.

Насколько я могу судить, у Google в настоящее время нет средства форматирования:

http://code.google.com/apis/chart/interactive/docs/reference.html#formatters

В документах есть краткое упоминание о пользовательских форматтерах, но я не могу найти никаких документов о том, как начать писать пользовательские форматеры.

Может кто-то указать мне верное направление?

В StackOverflow есть аналогичный вопрос: Напишите собственный форматтер для Google Charts Api. . Однако вопрос был решен просто с помощью встроенных средств форматирования (которые я думаю не могу использовать).


person Alex KeySmith    schedule 02.09.2011    source источник
comment
Пользовательские средства форматирования, упомянутые в документации, вероятно, относятся к пользовательским шаблонам форматирования. Код пользовательского формата см. в ответах ниже.   -  person PaulH    schedule 07.06.2016


Ответы (3)


Я не думаю, что вы сможете заставить текущие средства форматирования делать то, что вам нужно, но вы сможете достаточно легко создать свое собственное средство форматирования. Я собрал iconFormatter ниже для примера - его можно настроить так, чтобы он делал все, что вам действительно нужно.

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
    <script type="text/javascript">
      google.load('visualization', '1', {packages: ['table']});
    </script>
    <script type="text/javascript">
      /**
      * Gviz icon formatter
      * @param {Object<Number, String>} Map of numbers to icon URIs
      */
      var iconFormatter = function(iconMap) {
        this.iconMap = iconMap;
      }
      /**
       * Formats a gviz DataTable column
       * @param {Object} dt DataTable to format
       * @param {Number} column index number
       */
      iconFormatter.prototype.format = function(dt, column) {
        for (var i=0;i<dt.getNumberOfRows();i++) {
          var formattedValue = this.iconMap[dt.getValue(i, column)];
          var htmlString = "<img src="+formattedValue+" />";
          dt.setFormattedValue(i, column, htmlString);
          // underlying value preserved
          console.log(dt.getValue(i, column)); 
        }
      }
    </script>
    <script>
      function drawVisualization() {
        // Create and populate the data table.
        var data = new google.visualization.DataTable();
        data.addColumn('string', 'Name');
        data.addColumn('number', 'Height');
        data.addRows(3);
        data.setCell(0, 0, 'Tong Ning mu');
        data.setCell(1, 0, 'Huang Ang fa');
        data.setCell(2, 0, 'Teng nu');
        data.setCell(0, 1, 174);
        data.setCell(1, 1, 523);
        data.setCell(2, 1, 86);

        var iconMap = {
          174: "http://farm1.static.flickr.com/76/buddyicons/[email protected]?1149480603",
          523: "http://farm1.static.flickr.com/28/buddyicons/[email protected]?1129271399",
          86: "http://farm3.static.flickr.com/2698/buddyicons/[email protected]?1303489082"
          // other numbers
        }

        // Create and draw the visualization.
        visualization = new google.visualization.Table(document.getElementById('table'));
        // apply our formatter, just like normal
        var formatter = new iconFormatter(iconMap);
        formatter.format(data, 1);
        // allow html, just like any html formatter will require
        visualization.draw(data, {allowHtml: true});
      }
      google.setOnLoadCallback(drawVisualization);
    </script>
  </head>
  <body>
    <div id="table"></div>
  </body>
</html>

Надеюсь, это поможет.

person oli    schedule 14.09.2011
comment
Выглядит мило! Спасибо за подробный ответ! - person Alex KeySmith; 14.09.2011
comment
Привет @oli, спасибо, это сработало! Просто небольшой дополнительный вопрос (надеюсь, вы не возражаете), я пытался адаптировать ваш пример, чтобы иметь возможность также обернуть значок с помощью href (если href передается), но я не мог показаться чтобы понять это. Любые подсказки о том, как начать? - person Alex KeySmith; 04.10.2011
comment
Рад, что это сработало @AlexKey. Вы должны иметь возможность изменить переменную htmlString, включив в нее тег a, позволяющий использовать ссылку. var htmlString = "<a href='http://www.google.com' target='_blank'><img src="+formattedValue+" /></a>"; - person oli; 14.10.2011
comment
Спасибо @oli, я опубликую свой код, как только у меня будет шанс, на случай, если он кому-нибудь поможет. Спасибо за вашу помощь. - person Alex KeySmith; 14.10.2011
comment
Спасибо @нефть! это прекрасно работает, только один вопрос. Он не применяет формат к меткам на оси (я использую его с LineChart), знаете ли вы, возможно ли это? - person Chango; 02.11.2011

Встроенные средства форматирования DataTable в настоящее время позволяют настраивать только строки форматирования (шаблоны). Кастомизация с функцией обратного вызова не поддерживается. Вот класс форматирования, который поддерживает функцию обратного вызова.

/**
 * Custom formatter class for Google Visualization DataTable
 * Can be used like a built-in formatters when they are not enough. 
 * https://developers.google.com/chart/interactive/docs/reference#formatters
 * Changes the displayed/formatted value. The value itself remains unchanged.
 *
 * @param function() custom value conversion function
 *  this function 
 *  - takes one value as input (the original value) and 
 *  - returns the formatted value
 */
var CustomFormatter = function(formatValue) {
  this.formatValue = formatValue;
}

/**
 * Formats a Google DataTable column
 * @param {Object} dt DataTable to format
 * @param {Number} column index number
 */
CustomFormatter.prototype.format = function(dt, column) {
  for (var i = 0; i < dt.getNumberOfRows(); i++) {
    var value = dt.getValue(i, column);
    dt.setFormattedValue(i, column, this.formatValue(value));
  }
}

Этот класс можно использовать как встроенные функции форматирования, но с функцией обратного вызова в конструкторе, такой как эта, которая преобразует число в формат ЧЧ:ММ:СС.

var customFormatter = new CustomFormatter(function(value) {
    var hours = parseInt(value / 3600) % 24;
    var minutes = parseInt(value / 60) % 60;
    var seconds = value % 60;
    return (hours < 10 ? "0" + hours : hours) +
      ":" + (minutes < 10 ? "0" + minutes : minutes) +
      ":" + (seconds < 10 ? "0" + seconds : seconds);
});
customFormatter.format(dataTable, 1);

Вот рабочая демонстрационная скрипта: http://jsfiddle.net/o5tdt2r8/10/

В качестве альтернативы используйте addColumn в DataView, как описано в другом ответе.

Спасибо @oli's за оригинальный ответ. Я отделил пользовательскую функцию форматирования обратного вызова от универсального средства форматирования.

person PaulH    schedule 06.06.2016
comment
Хороший, хороший совет, Павел. Сейчас я нахожусь в другом мире, поэтому не могу проверить это, но мне нравится, спасибо, что поделились. - person Alex KeySmith; 06.06.2016
comment
Потрясающая работа @PaulH, спасибо, отлично работает! - person user692942; 12.01.2017

В отличие от таблицы данных, представление данных позволяет определять вычисляемые столбцы с помощью SetColumns

google.charts.load('current', {'packages':['table']});

google.charts.setOnLoadCallback(function() {
  // Create and populate the data table.
  var dataTable = new google.visualization.DataTable();
  dataTable.addColumn('string', 'Name');
  dataTable.addColumn('number', 'Icon Nr');
  dataTable.addRow(['Tong Ning mu', 174]);
  dataTable.addRow(['Huang Ang fa', 523]);
  dataTable.addRow(['Teng nu', 86]);

  // Create and define the data view with custom formatter in the calc property
  var dataView = new google.visualization.DataView(dataTable);
  dataView.setColumns([0, {
    type: 'string',
    label: 'Icon',
    calc: function(dataTable, rowNr) {
      var iconMap = {
        174: "http://farm1.static.flickr.com/76/buddyicons/[email protected]?1149480603",
        523: "http://farm1.static.flickr.com/28/buddyicons/[email protected]?1129271399",
        86: "http://farm3.static.flickr.com/2698/buddyicons/[email protected]?1303489082"
      }
      var value = dataTable.getValue(rowNr, 1); // 1 is the column
      var formattedValue = iconMap[value]; // convert
      var htmlString = "<img src=" + formattedValue + " />"; // wrap
      // console.log(rowNr, value, formattedValue); // debug
      return htmlString;
    }
  }]);

  // Create and draw the visualization.
  visualization = new google.visualization.Table(document.getElementById('table'));
  visualization.draw(dataView, {
    allowHtml: true // allow html, just like any html formatter will require
  });
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="table"></div>

person PaulH    schedule 08.06.2016
comment
Снова еще один отличный ответ! - person user692942; 12.01.2017