Google时间线图表的Javascript代码包含错误

时间:2017-01-18 01:45:50

标签: javascript charts google-visualization

我有谷歌时间线图表的这个JavaScript代码,但我无法修复错误。

这应该是图表应该是这样的:

  1. 酒吧颜色取决于课程(例如IT)
  2. 工具提示有链接
  3. HAxis将位于图表上方
  4. HAxis将替换为字符串而不是日期(例如10月6日至第1周)
  5. 我认为1-3很好但是当我从@ WhiteHat的建议中添加#4时,它包含一个错误(参见下面的代码片段)。
    我试图解决它无济于事 我的javascript是知识有限,处于初级水平。

    能不能帮我解决这个问题,请向我解释我弄错了什么 建议和建议非常感谢。

    提前致谢!

        google.charts.load("current", {packages:["timeline"], callback: drawChart});
    
    function drawChart() {
    var container = document.getElementById('chart_div');
    var chart = new google.visualization.Timeline(container);
    
    // hAxis put on top
    google.visualization.events.addListener(chart, 'ready', afterDraw); 
    
    // Link in tooltip
    google.visualization.events.addListener(chart, 'select', function(e) { 
      var tooltip = document.querySelector('.google-visualization-tooltip:not([clone])');
      if (chart.ttclone) {
        chart.ttclone.parentNode.removeChild(chart.ttclone)
      }
      chart.ttclone = tooltip.cloneNode(true);
      chart.ttclone.setAttribute('clone', true);
      chart.ttclone.style.pointerEvents = 'auto';
      tooltip.parentNode.insertBefore(chart.ttclone, chart.tooltip);
    });
    
    var dataTable = new google.visualization.DataTable();
    dataTable.addColumn({ type: 'string', id: 'Name' });
    // for colorMap
    dataTable.addColumn({ type: 'string', id: 'Course' }); 
    dataTable.addColumn({ type: 'string', id: 'Subject' });
    dataTable.addColumn({ type: 'string', id: 'ToolTip', role: 'tooltip', p:{html:true} });
    dataTable.addColumn({ type: 'date', id: 'Start' });
    dataTable.addColumn({ type: 'date', id: 'End' });
    dataTable.addRows([
    	
    	// Timeline Start 
    	['Student 1', 'ENGR', 'Trigonometry', '<a href="link_to_subj_desc" target="_blank">Trigonometry</a>', new Date(2016, 9, 30), new Date(2016, 10, 06)],
    	['Student 2', 'IT', 'DB Management', '<a href="link_to_subj_desc" target="_blank">DB Management</a>', new Date(2016, 9, 30), new Date(2016, 10, 13)],
    	['Student 3', 'CS', 'Introduction to Programming', '<a href="link_to_subj_desc" target="_blank">Introduction to Programming</a>', new Date(2016, 9, 30), new Date(2016, 10, 27)],
    ]);  
    	
    var colors = [];
    var colorMap = {
    	ENGR:	'#2ECC71',	// Green
    	IT:	'#E67E22',	// Brown
    	CS:	'#9B59B6',	// Violet
    }
    
    for (var i = 0; i < dataTable.getNumberOfRows(); i++) {
    	colors.push(colorMap[dataTable.getValue(i, 1)]);
    }
    
    var rowHeight = 41;
    var chartHeight = (dataTable.getNumberOfRows() + 1) * rowHeight;
    	
    var options = {
    	timeline: { 
    		groupByRowLabel: true,
    		rowLabelStyle: {
    			fontName: 'Century Gothic',
    			fontSize: 14,
    			color: '#333333',
    			bold: 'true',
    		},
    		barLabelStyle: {
    			fontName: 'Century Gothic',
    fontSize: 11,
    },
    showRowLabels: true,
    showBarLabels: true,
    }, 
    hAxis: {
    minValue: new Date(2016, 9, 30),
    maxValue: new Date(2017, 9, 28),
    },
    avoidOverlappingGridLines: true,
    height: chartHeight,
    width: '100%',
    colors: colors,
    };
    
    
    
    // use a DataView to hide the category column from the Timeline
    var view = new google.visualization.DataView(dataTable);
    view.setColumns([0, 2, 3, 4, 5]);
    
    // Change HAxis labels to Week
    google.visualization.events.addListener(chart, 'ready', function () {
      var rowIndex = 0;      // data table row index
      var weekLabel = null;  // clone of text node - keep font settings, y-coord, etc...
    
      // remove haxis labels
      var labels = container.getElementsByTagName('text');
      while (labels.length > dataTable.getNumberOfRows()) {
        // ignore "category" labels
        if (dataTable.getFilteredRows([{column: 5, value: labels[labels.length - 1].innerHTML}]).length === 0) {
          if (weekLabel === null) {
            weekLabel = labels[labels.length - 1].cloneNode(true);
          }
          labels[labels.length - 1].parentNode.removeChild(labels[labels.length - 1]);
        }
      }
    
      
    
        // use timeline bars to find x coordinate for week labels
         rowIndex = 0;
          var svgParent = container.getElementsByTagName('svg')[0];
          Array.prototype.forEach.call(container.getElementsByTagName('rect'), function(bar) {
            var bounds;  // bounding box of text element
    
            // ignore rect if not a timeline bar
            if (parseFloat(bar.getAttribute('x')) > 0) {
              weekLabel = weekLabel.cloneNode(true);
              weekLabel.innerHTML = 'WW 70' + (rowIndex + 1);
              svgParent.appendChild(weekLabel);
              bounds = weekLabel.getBBox();
              weekLabel.setAttribute('x', parseFloat(bar.getAttribute('x')) + bounds.width);
              rowIndex++;
            }
          }); 
        });
    	
    	chart.draw(
    		view,
    		options, 
    		dataTable, {
    			tooltip: {
    				isHtml: true,
    			},
    			timeline: {
    				showBarLabels: false,
    			}
    	});
    }
    
    // hAxis put on top
        function afterDraw() {
    	var g = document.getElementsByTagName("svg")[0].getElementsByTagName("g")[1];
    	document.getElementsByTagName("svg")[0].parentNode.style.top = '40px';
    	document.getElementsByTagName("svg")[0].style.overflow = 'visible';
    	var height = Number(g.getElementsByTagName("text")[0].getAttribute('y')) + 15;
    	g.setAttribute('transform','translate(0,-'+height+')');
    	g = null;
    }
    <script src="https://www.gstatic.com/charts/loader.js"></script>
    <div id="chart_div"></div>

1 个答案:

答案 0 :(得分:0)

错误发生在// remove haxis labels部分。您的过滤器中的value是“编程简介”(即图表的最后<text>内容),但您要过滤第5列,即日期,这是导致错误的原因。

没有必要尝试进入<svg>来更改标签(无论如何它都是徒劳的,因为标签将不再与条形图匹配)。

请使用:

hAxis: {
  minValue: new Date(2016, 9, 29),
  maxValue: new Date(2016, 10, 28),
},

google.charts.load("current", {
  packages: ["timeline"],
  callback: drawChart
});

function drawChart() {
  var container = document.getElementById('chart_div');
  var chart = new google.visualization.Timeline(container);

  // hAxis put on top
  google.visualization.events.addListener(chart, 'ready', afterDraw);

  // Link in tooltip
  google.visualization.events.addListener(chart, 'select', function(e) {
    var tooltip = document.querySelector('.google-visualization-tooltip:not([clone])');
    if (chart.ttclone) {
      chart.ttclone.parentNode.removeChild(chart.ttclone)
    }
    chart.ttclone = tooltip.cloneNode(true);
    chart.ttclone.setAttribute('clone', true);
    chart.ttclone.style.pointerEvents = 'auto';
    tooltip.parentNode.insertBefore(chart.ttclone, chart.tooltip);
  });

  var dataTable = new google.visualization.DataTable();
  dataTable.addColumn({
    type: 'string',
    id: 'Name'
  });
  // for colorMap
  dataTable.addColumn({
    type: 'string',
    id: 'Course'
  });
  dataTable.addColumn({
    type: 'string',
    id: 'Subject'
  });
  dataTable.addColumn({
    type: 'string',
    id: 'ToolTip',
    role: 'tooltip',
    p: {
      html: true
    }
  });
  dataTable.addColumn({
    type: 'date',
    id: 'Start'
  });
  dataTable.addColumn({
    type: 'date',
    id: 'End'
  });
  dataTable.addRows([

    // Timeline Start 
    ['Student 1', 'ENGR', 'Trigonometry', '<a href="link_to_subj_desc" target="_blank">Trigonometry</a>', new Date(2016, 9, 30), new Date(2016, 10, 06)],
    ['Student 2', 'IT', 'DB Management', '<a href="link_to_subj_desc" target="_blank">DB Management</a>', new Date(2016, 9, 30), new Date(2016, 10, 13)],
    ['Student 3', 'CS', 'Introduction to Programming', '<a href="link_to_subj_desc" target="_blank">Introduction to Programming</a>', new Date(2016, 9, 30), new Date(2016, 10, 27)]
  ]);

  var colors = [];
  var colorMap = {
    ENGR: '#2ECC71', // Green
    IT: '#E67E22', // Brown
    CS: '#9B59B6', // Violet
  };

  for (var i = 0; i < dataTable.getNumberOfRows(); i++) {
    colors.push(colorMap[dataTable.getValue(i, 1)]);
  }

  var rowHeight = 41;
  var chartHeight = (dataTable.getNumberOfRows() + 1) * rowHeight;

  var options = {
    timeline: {
      groupByRowLabel: true,
      rowLabelStyle: {
        fontName: 'Century Gothic',
        fontSize: 14,
        color: '#333333',
        bold: 'true',
      },
      barLabelStyle: {
        fontName: 'Century Gothic',
        fontSize: 11,
      },
      showRowLabels: true,
      showBarLabels: true,
    },
    hAxis: {
      minValue: new Date(2016, 9, 29),
      maxValue: new Date(2016, 10, 28),
    },
    avoidOverlappingGridLines: true,
    height: chartHeight,
    width: '100%',
    colors: colors,
  };



  // use a DataView to hide the category column from the Timeline
  var view = new google.visualization.DataView(dataTable);
  view.setColumns([0, 2, 3, 4, 5]);

  chart.draw(
    view,
    options,
    dataTable, {
      tooltip: {
        isHtml: true,
      },
      timeline: {
        showBarLabels: false,
      }
    });
}

// hAxis put on top
function afterDraw() {
  var g = document.getElementsByTagName("svg")[0].getElementsByTagName("g")[1];
  document.getElementsByTagName("svg")[0].parentNode.style.top = '40px';
  document.getElementsByTagName("svg")[0].style.overflow = 'visible';
  var height = Number(g.getElementsByTagName("text")[0].getAttribute('y')) + 15;
  g.setAttribute('transform', 'translate(0,-' + height + ')');
  g = null;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>