Google Charts: временная шкала переместить текст rowLabel в другой div - PullRequest
1 голос
/ 21 марта 2019

Какой правильный элемент SVG на графике для шкалы времени rowLabel?

Я пытаюсь поместить метку строки (имена строк) в div слева от диаграммы и удалить фактическую метку строки. Я могу легко удалить строку с:

timeline: { groupByRowLabel: true, showrowLabels: false}

Но я не могу найти способ переместить фактические метки влево в отдельном элементе div, чтобы огромная горизонтальная прокрутка удерживала метки строк в замороженном состоянии влево.

function afterDraw() {

//trying to move the rowlabelhere

 var header = document.getElementById('rowlabel');
header.innerHTML = '';
 var svg = document.getElementsByTagName('svg')[0];
 var g = svg.getElementsByTagName('g')[0];
 var gtext = g.getElementsByTagName('text')[0];
 var svgNew = header.appendChild(svg.cloneNode());
 var gNew = svgNew.appendChild(gtext.cloneNode(true));
 var height = parseFloat(gNew.getElementsByTagName('text')[0].getAttribute('y')) - 25;
 gNew.setAttribute('transform','translate(60,-'+height+')');
 }

Вот кодекс с вопросом:

https://codepen.io/anon/pen/bZmKpo

1 Ответ

1 голос
/ 21 марта 2019

вы можете удалить метки, как вы описали,
затем используйте метод group () , чтобы извлечь метки из таблицы данных,
и добавьте их в контейнер слева от графика.

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

var group = google.visualization.data.group(
  data,
  [0, 1],
  [{
    column: 0,
    type: 'number',
    label: data.getColumnLabel(0),
    aggregation: google.visualization.data.count
  }]
);
group.sort([{column: 1}]);

но это приведет к повторению некоторых меток,
так что мы можем использовать массив для фильтрации,
как мы добавляем их в контейнер.

var rowLabels = [];
var rowElements = [];
var labels = document.getElementById('labels');
for (var i = 0; i < group.getNumberOfRows(); i++) {
  var team = group.getValue(i, 0);
  if (rowLabels.indexOf(team) === -1) {
    rowLabels.push(team);
    var label = labels.appendChild(document.createElement('div'));
    label.className = 'label';
    label.innerHTML = team;
    rowElements.push(label);
  }
}

затем на событии 'ready' мы можем отрегулировать высоту метки,
чтобы соответствовать строкам диаграммы.

var rows = container.getElementsByTagName('rect');
var rowIndex = -1;
Array.prototype.forEach.call(rows, function(rect) {
  if (rect.getAttribute('x') === '0') {
    rowIndex++;
    if (rowIndex < rowElements.length) {
      var rowHeight = (parseFloat(rect.getAttribute('height')) - 1) + 'px';
      rowElements[rowIndex].style.height = rowHeight;
      rowElements[rowIndex].style.lineHeight = rowHeight;
    }
  }
});

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

google.charts.load('current', {
  packages:['timeline']
}).then(function () {
  var data = new google.visualization.DataTable({
    cols: [
      {id: 'team', label: 'Team', type: 'string'},
      {id: 'start', label: 'Season Start Date', type: 'date'},
      {id: 'end', label: 'Season End Date', type: 'date'}
    ],
    rows: [
      {c: [{v: 'Baltimore Ravens'},     {v: 'Date(2000, 8, 5)'}, {v: 'Date(2001, 1, 5)'}]},
      {c: [{v: 'New England Patriots'}, {v: 'Date(2001, 8, 5)'}, {v: 'Date(2002, 1, 5)'}]},
      {c: [{v: 'Tampa Bay Buccaneers'}, {v: 'Date(2002, 8, 5)'}, {v: 'Date(2003, 1, 5)'}]},
      {c: [{v: 'New England Patriots'}, {v: 'Date(2003, 8, 5)'}, {v: 'Date(2004, 1, 5)'}]},
      {c: [{v: 'New England Patriots'}, {v: 'Date(2004, 8, 5)'}, {v: 'Date(2005, 1, 5)'}]},
      {c: [{v: 'Pittsburgh Steelers'},  {v: 'Date(2005, 8, 5)'}, {v: 'Date(2006, 1, 5)'}]},
      {c: [{v: 'Indianapolis Colts'},   {v: 'Date(2006, 8, 5)'}, {v: 'Date(2007, 1, 5)'}]},
      {c: [{v: 'New York Giants'},      {v: 'Date(2007, 8, 5)'}, {v: 'Date(2008, 1, 5)'}]},
      {c: [{v: 'Pittsburgh Steelers'},  {v: 'Date(2008, 8, 5)'}, {v: 'Date(2009, 1, 5)'}]},
      {c: [{v: 'New Orleans Saints'},   {v: 'Date(2009, 8, 5)'}, {v: 'Date(2010, 1, 5)'}]},
      {c: [{v: 'Green Bay Packers'},    {v: 'Date(2010, 8, 5)'}, {v: 'Date(2011, 1, 5)'}]},
      {c: [{v: 'Green Bay Packers'},    {v: 'Date(2010, 8, 5)'}, {v: 'Date(2011, 1, 5)'}]},
      {c: [{v: 'New England Patriots'}, {v: 'Date(2001, 8, 5)'}, {v: 'Date(2002, 1, 5)'}]},
      {c: [{v: 'Tampa Bay Buccaneers'}, {v: 'Date(2002, 8, 5)'}, {v: 'Date(2003, 1, 5)'}]},
      {c: [{v: 'New England Patriots'}, {v: 'Date(2003, 8, 5)'}, {v: 'Date(2004, 1, 5)'}]},
      {c: [{v: 'New England Patriots'}, {v: 'Date(2004, 8, 5)'}, {v: 'Date(2005, 1, 5)'}]},
      {c: [{v: 'Pittsburgh Steelers'},  {v: 'Date(2005, 8, 5)'}, {v: 'Date(2006, 1, 5)'}]},
    ]
  });

  var group = google.visualization.data.group(
    data,
    [0, 1],
    [{
      column: 0,
      type: 'number',
      label: data.getColumnLabel(0),
      aggregation: google.visualization.data.count
    }]
  );
  group.sort([{column: 1}]);

  var rowLabels = [];
  var rowElements = [];
  var labels = document.getElementById('labels');
  for (var i = 0; i < group.getNumberOfRows(); i++) {
    var team = group.getValue(i, 0);
    if (rowLabels.indexOf(team) === -1) {
      rowLabels.push(team);
      var label = labels.appendChild(document.createElement('div'));
      label.className = 'label';
      label.innerHTML = team;
      rowElements.push(label);
    }
  }

  var options = {
    height: 650,
    timeline: {
      groupByRowLabel: true,
      showRowLabels: false
    },
    width: 1000
  };

  var container = document.getElementById('chart');
  var chart = new google.visualization.Timeline(container);
  google.visualization.events.addListener(chart, 'ready', afterDraw);
  chart.draw(data, options);
  window.addEventListener('resize', function () {
    chart.draw(data, options);
  });

  function afterDraw() {
    var header = document.getElementById('header');
    header.innerHTML = '';
    var svg = document.getElementsByTagName('svg')[0];
    var g = svg.getElementsByTagName('g')[1];
    var svgNew = header.appendChild(svg.cloneNode());
    var gNew = svgNew.appendChild(g.cloneNode(true));
    var height = parseFloat(gNew.getElementsByTagName('text')[0].getAttribute('y')) - 25;
    gNew.setAttribute('transform','translate(0,-'+height+')');
    g.parentNode.removeChild(g);

    var rows = container.getElementsByTagName('rect');
    var rowIndex = -1;
    Array.prototype.forEach.call(rows, function(rect) {
      if (rect.getAttribute('x') === '0') {
        rowIndex++;
        if (rowIndex < rowElements.length) {
          var rowHeight = (parseFloat(rect.getAttribute('height')) - 1) + 'px';
          rowElements[rowIndex].style.height = rowHeight;
          rowElements[rowIndex].style.lineHeight = rowHeight;
        }
      }
    });
  }
});
#header {
  height: 56px;
}

#labels {
  border: 1px solid #b7b7b7;
  margin-top: 56px;
}

.label {
  border-top: 1px solid #b7b7b7;
  font-family: Arial;
  font-size: 13px;
  text-align: right;
  padding-left: 8px;
  padding-right: 8px;
}

.label:first-child {
  border: none;
}

.label:nth-child(even) {
	background-color: #e6e6e6;
}

.label:nth-child(odd) {
	background-color: #ffffff;
}

.scroll {
  width: 800px;
  overflow-x: scroll;
}

.inline {
  display: inline-block;
  vertical-align: top;
}

.nowrap {
  white-space: nowrap;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div class="nowrap">
  <div class="inline" id="labels"></div>
  <div class="inline scroll">
    <div id="header"></div>
    <div id="chart"></div>
  </div>
</div>
...