如何将动态json数据用于Google甘特图?

时间:2020-07-28 13:01:57

标签: javascript json charts google-visualization gantt-chart

我在Google Gantt图表中有问题。

现在,通过给出所有值的硬编码值,我得到了正常的甘特图,其开始日期和结束日期,草稿日期(三角形)作为里程碑。

我想要通过动态输入json数据来获取图表,并且应该从中动态获取草稿日期(里程碑)。

我还需要“任务名称”列作为超链接。

 google.charts.load('current', {
  packages:['gantt']
}).then(function () {
  var container = document.getElementById('gantt');
  var chart = new google.visualization.Gantt(container);

  var dataTable = new google.visualization.DataTable();
      dataTable.addColumn('string', 'Task ID');
      dataTable.addColumn('string', 'Task Name');
      dataTable.addColumn('string', 'Resource');
      dataTable.addColumn('date', 'Start Date');
      dataTable.addColumn('date', 'End Date');
     dataTable.addColumn('number', 'Duration');
     dataTable.addColumn('number', 'Percent Complete');
     dataTable.addColumn('string', 'Dependencies');

      dataTable.addRows([
        ['2014Spring', 'Model 1', 'spring',
         new Date(2020, 1, 22), new Date(2020, 2, 20), null, 100, null],
       ['2014Autumn', 'Model 3', 'autumn',
         new Date(2020, 3, 21), new Date(2020, 4, 20), null, 100, null],
         ['2014Winter', 'Model 4', 'winter',
         new Date(2020, 4, 21), new Date(2020, 8, 21), null, 100, null]
   ]);

  var dateRangeStart = dataTable.getColumnRange(3);
  var dateRangeEnd = dataTable.getColumnRange(4);
  var formatDate = new google.visualization.DateFormat({
    pattern: 'MM/dd/yyyy'
  });
  var rowHeight = 45;

  var options = {
    height: ((dataTable.getNumberOfRows() * rowHeight) + rowHeight),
    gantt: {
    palette: [
      {
        "color": "#3e77ca",
        "dark": "#4cc9ac",
        "light": "#3e77ca"
      }
    ]
      
    }
    
    
    
  };

 

  function drawChart() {
    chart.draw(dataTable, options);
  }

  function addMarker(markerRow, markerDate) {
    var baseline;
    var baselineBounds;
    var chartElements;
    var marker;
    var markerSpan;
    var rowLabel;
    var svg;
    var svgNS;
    var gantt;
    var ganttUnit;
    var ganttWidth;
    var timespan;
    var xCoord;
    var yCoord;

    // initialize chart elements
    baseline = null;
    gantt = null;
    rowLabel = null;
    svg = null;
    svgNS = null;
    chartElements = container.getElementsByTagName('svg');
    if (chartElements.length > 0) {
      svg = chartElements[0];
      svgNS = svg.namespaceURI;
    }
    chartElements = container.getElementsByTagName('rect');
    if (chartElements.length > 0) {
      gantt = chartElements[0];
    }
    chartElements = container.getElementsByTagName('path');
    if (chartElements.length > 0) {
      Array.prototype.forEach.call(chartElements, function(path) {
        if ((baseline === null) && (path.getAttribute('fill') !== 'none')) {
          baseline = path;
        }
      });
    }
    chartElements = container.getElementsByTagName('text');
    if (chartElements.length > 0) {
      Array.prototype.forEach.call(chartElements, function(label) {
        if (label.textContent === markerRow) {
          rowLabel = label;
        }
      });
    }
    if ((svg === null) || (gantt === null) || (baseline === null) || (rowLabel === null) ||
        (markerDate.getTime() < dateRangeStart.min.getTime()) ||
        (markerDate.getTime() > dateRangeEnd.max.getTime())) {
      return;
    }

    // calculate placement
    ganttWidth = parseFloat(gantt.getAttribute('width'));
    baselineBounds = baseline.getBBox();
    timespan = dateRangeEnd.max.getTime() - dateRangeStart.min.getTime();
    ganttUnit = (ganttWidth - baselineBounds.x) / timespan;
    markerSpan = markerDate.getTime() - dateRangeStart.min.getTime();

    // add marker
    marker = document.createElementNS(svgNS, 'polygon');
    marker.setAttribute('fill', 'transparent');
    marker.setAttribute('stroke', '#ffeb3b');
    marker.setAttribute('stroke-width', '3');
    xCoord = (baselineBounds.x + (ganttUnit * markerSpan) - 4);
    yCoord = parseFloat(rowLabel.getAttribute('y'));
    marker.setAttribute('points', xCoord + ',' + (yCoord - 10) + ' ' + (xCoord - 5) + ',' + yCoord + ' ' + (xCoord + 5) + ',' + yCoord);
    svg.insertBefore(marker, rowLabel.parentNode);
  }
 function addLiner(markerDate) {
    var baseline;
    var baselineBounds;
    var chartElements;
    var markerLabel;
    var markerLine;
    var markerSpan;
    var svg;
    var timeline;
    var timelineUnit;
    var timelineWidth;
    var timespan;

    baseline = null;
    timeline = null;
    svg = null;
    markerLabel = null;
    chartElements = container.getElementsByTagName('svg');
    if (chartElements.length > 0) {
      svg = chartElements[0];
    }
    chartElements = container.getElementsByTagName('rect');
    if (chartElements.length > 0) {
      timeline = chartElements[0];
    }
    chartElements = container.getElementsByTagName('path');
    if (chartElements.length > 0) {
      baseline = chartElements[0];
    }
    chartElements = container.getElementsByTagName('text');
    if (chartElements.length > 0) {
      markerLabel = chartElements[0].cloneNode(true);
    }
    if ((svg === null) || (timeline === null) || (baseline === null) || (markerLabel === null) ||
        (markerDate.getTime() < dateRangeStart.min.getTime()) ||
        (markerDate.getTime() > dateRangeEnd.max.getTime())) {
      return;
    }

    // calculate placement
    timelineWidth = parseFloat(timeline.getAttribute('width'));
    baselineBounds = baseline.getBBox();
    timespan = dateRangeEnd.max.getTime() - dateRangeStart.min.getTime();
    timelineUnit = (timelineWidth - baselineBounds.x) / timespan;
    markerSpan = markerDate.getTime() - dateRangeStart.min.getTime();

    // add label
    markerLabel.setAttribute('fill', '#e91e63');
    markerLabel.setAttribute('y', options.height);
    markerLabel.setAttribute('x', (baselineBounds.x + (timelineUnit * markerSpan) - 4));
    markerLabel.textContent = "Today";
    svg.appendChild(markerLabel);

    // add line
    markerLine = timeline.cloneNode(true);
    markerLine.setAttribute('y', 0);
    markerLine.setAttribute('x', (baselineBounds.x + (timelineUnit * markerSpan)));
    markerLine.setAttribute('height', options.height);
    markerLine.setAttribute('width', 1);
    markerLine.setAttribute('stroke', 'none');
    markerLine.setAttribute('stroke-width', '0');
    markerLine.setAttribute('fill', '#e91e63');
    svg.appendChild(markerLine);
  }
  google.visualization.events.addListener(chart, 'ready', function () {
    // add marker for current date
    addMarker('Model 1', new Date(2020, 2, 8));
    addMarker('Model 3', new Date(2020, 4, 10));
    addMarker('Model 4', new Date(2020, 5, 15));

 addLiner(new Date()); 
  });

  window.addEventListener('resize', drawChart, false);
  drawChart();
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="gantt"></div>

预期输出应采用以下格式:

  1. “ Y轴应为超链接。”
  2. “所有数据均应从JSON以以下格式动态加载

{"startDate":"10-Jan-2020", "endDate":"30-Jan-2020", "draftDate":"15-Jan-2020", "ModelId":1134 } "

  1. 起草日期应为里程碑格式(来自JSON的动态输入)。

Refer the below image:

1 个答案:

答案 0 :(得分:0)

在脚本底部,
我认为您希望替换以下几行...

  window.addEventListener('resize', drawChart, false);
  drawChart();

并在其中添加ajax调用。
日期将需要转换为实际的日期对象。
并假设数据将来自数组中的ajax,
您可能想做类似以下的事情...

$.ajax({
  url: 'get_data.url',
  dataType: 'JSON'
}).done(function (data) {

  data.forEach(function (row) {
    dataTable.addRow([
      row.ModelId,              // 'Task ID'
      row.Task,                 // 'Task Name'
      row.Resource,             // 'Resource'
      new Date(row.startDate),  // 'Start Date'
      new Date(row.endDate),    // 'End Date'
      null,                     // 'Duration'
      row.Percent,              // 'Percent Complete'
      null                      // 'Dependencies'
    ]);
  });

  window.addEventListener('resize', drawChart, false);
  drawChart();
});

但是,我看不到其他字段,例如“任务名称和资源”,
在示例JSON中发布。