Google Chart Calendar如何用-svg中的圆圈标记日期

时间:2018-02-20 02:28:30

标签: svg google-visualization

我正在使用Google Chart库中的日历。当某个日期有鼠标悬停时,我想在接下来的x天画一个红色圆圈 - 表示逗留的天数。

enter image description here

我设法通过使用此脚本获取mouseover上的rect标记:

google.visualization.events.addListener(chart, 'onmouseover', function(selection) {
  if (selection) {
    var dayNumber = new Date(selection.date).getDOY();
    var selectedRect = $('#calendar-fare rect[width="16"][height="16"]').get(dayNumber + 1);
    var y = parseInt($(selectedRect).attr("y"));
    var x = parseInt($(selectedRect).attr("x"));
    $(selectedRect).after( "<circle cx='" + (x + 8) + "' cy='" + (y + 8) +"' r='2' fill='red'></circle>");
  }
});

我还设法绘制了一个圆圈,但它没有按预期工作。只有当我修改源代码时,圆圈才会出现 - 我还尝试将其包装在标签内,但它似乎会自动添加一些标签。

如何在日期中绘制可见的圆圈? Here is example

1 个答案:

答案 0 :(得分:1)

使用svg命名空间添加新元素...

var svg = container.getElementsByTagName('svg')[0];
var svgNS = svg.namespaceURI;
var circle = document.createElementNS(svgNS, 'circle');
svg.appendChild(circle);

请参阅以下工作代码段...

google.charts.load('current', {
  packages: ['calendar']
}).then(function () {
  var dataTable = new google.visualization.DataTable();
  dataTable.addColumn({type: 'date', id: 'Date'});
  dataTable.addColumn({type: 'number', id: 'Activity'});
  dataTable.addRows([
    [new Date(2017, 10, 3), 1],
    [new Date(2017, 10, 16), 2],
    [new Date(2017, 11, 6), 3],
    [new Date(2017, 11, 15), 4],
    [new Date(2017, 11, 25), 5],
    [new Date(2018, 0, 3), 1],
    [new Date(2018, 0, 16), 2],
    [new Date(2018, 1, 6), 3],
    [new Date(2018, 1, 15), 4],
    [new Date(2018, 1, 25), 5],
  ]);
  var options = {
    calendar: {
      focusedCellColor: {
        stroke: '#c62828',
        strokeOpacity: 1,
        strokeWidth: 1
      }
    },
    width: 1000
  };
  var container = document.getElementById('chart_div');
  var chart = new google.visualization.Calendar(container);

  google.visualization.events.addListener(chart, 'onmouseover', function (sender) {
    setSelection('mouseover', new Date(sender.date));
  });
  google.visualization.events.addListener(chart, 'onmouseout', function () {
    setSelection('mouseout');
  });

  var dateRange = dataTable.getColumnRange(0);
  var selectedDate = null;
  function setSelection(eventType, eventDate) {
    var calendarRects = $('#chart_div rect[width="16"][height="16"]');
    var svg = container.getElementsByTagName('svg')[0];
    var svgNS = svg.namespaceURI;

    if (selectedDate !== null) {
      svg.removeChild(selectedDate);
      selectedDate = null;
    }

    if (eventType === 'mouseover') {
      var dayNumber = eventDate.getDOY() + 1;
      if (eventDate.getFullYear() !== dateRange.min.getFullYear()) {
        dayNumber = dayNumber + Math.floor(365.25 * (eventDate.getFullYear() - dateRange.min.getFullYear()));
      }
      var selectedRect = calendarRects.get(dayNumber);
      var coordX = parseInt(selectedRect.getAttribute('x'));
      var coordY = parseInt(selectedRect.getAttribute('y'));
      var circle = document.createElementNS(svgNS, 'circle');
      circle.setAttribute('cx', (coordX + 8));
      circle.setAttribute('cy', (coordY + 8));
      circle.setAttribute('r', 4);
      circle.setAttribute('fill', '#c62828');
      selectedDate = svg.appendChild(circle);
    }
  }

  chart.draw(dataTable, options);
});

Date.prototype.isLeapYear = function() {
  var year = this.getFullYear();
  if((year & 3) != 0) return false;
  return ((year % 100) != 0 || (year % 400) == 0);
};

Date.prototype.getDOY = function() {
  var dayCount = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
  var mn = this.getMonth();
  var dn = this.getDate();
  var dayOfYear = dayCount[mn] + dn;
  if(mn > 1 && this.isLeapYear()) dayOfYear++;
  return dayOfYear;
};
html, body {
  height: 100%;
}

#chart_div {
  height: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>