Google 图表,如何在甘特图上添加自定义点?
Google charts, how to add custom points on Gantt Charts?
我正在尝试在甘特图上添加一些自定义点。但我没有看到任何正式的方式来做到这一点。
有人知道我该怎么做吗?
我试着在下面添加一些点,比如三角形
没有添加自定义点的标准选项,
但我们可以手动添加图表的 'ready'
事件。
请参阅以下工作片段,
函数 addMarker
将在图表中添加一个三角形。
传递行标签参数和点放置日期,例如
addMarker('Find sources', new Date(2019, 0, 3));
addMarker('Outline paper', new Date(2019, 0, 5, 12));
addMarker('Write paper', new Date(2019, 0, 8));
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([
['Research', 'Find sources', null, new Date(2019, 0, 1), new Date(2019, 0, 5), null, 100, null],
['Write', 'Write paper', 'write', null, new Date(2019, 0, 9), daysToMilliseconds(3), 25, 'Research,Outline'],
['Cite', 'Create bibliography', 'write', null, new Date(2019, 0, 7), daysToMilliseconds(1), 20, 'Research'],
['Complete', 'Hand in paper', 'complete', null, new Date(2019, 0, 10), daysToMilliseconds(1), 0, 'Cite,Write'],
['Outline', 'Outline paper', 'write', null, new Date(2019, 0, 6), daysToMilliseconds(1), 100, 'Research']
]);
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: {
criticalPathEnabled: true,
criticalPathStyle: {
stroke: '#e64a19',
strokeWidth: 5
}
}
};
function daysToMilliseconds(days) {
return days * 24 * 60 * 60 * 1000;
}
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);
}
google.visualization.events.addListener(chart, 'ready', function () {
// add marker for current date
addMarker('Find sources', new Date(2019, 0, 3));
addMarker('Outline paper', new Date(2019, 0, 5, 12));
addMarker('Write paper', new Date(2019, 0, 8));
});
window.addEventListener('resize', drawChart, false);
drawChart();
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="gantt"></div>
更新
标记的大小在多边形元素的 'points'
属性中指定。
在 addMarker
函数的底部,
查看 --> marker.setAttribute('points', ...
行
'points'
的值应该是三组x,y坐标。
分别为上、左、右。
注意:添加四组 x,y 坐标会添加一个矩形标记。
变量 xCoord
和 yCoord
是计算出的标记放置位置的 x,y 坐标,应该是标记的中心。
因此,为了绘制三角形...
顶部 = xCoord + ',' + (yCoord - 10)
左 = (xCoord - 5) + ',' + yCoord
右 = (xCoord + 5) + ',' + yCoord
综上所述,为了改变标记的大小,
我们更改对变量 xCoord
& yCoord
所做的修饰符
将标记的大小减半,
我们将按如下方式更改坐标...
顶部 = xCoord + ',' + (yCoord - 5)
左 = (xCoord - 2.5) + ',' + yCoord
右 = (xCoord + 2.5) + ',' + yCoord
例如
marker.setAttribute('points', xCoord + ',' + (yCoord - 5) + ' ' + (xCoord - 2.5) + ',' + yCoord + ' ' + (xCoord + 2.5) + ',' + yCoord);
我正在尝试在甘特图上添加一些自定义点。但我没有看到任何正式的方式来做到这一点。
有人知道我该怎么做吗?
我试着在下面添加一些点,比如三角形
没有添加自定义点的标准选项,
但我们可以手动添加图表的 'ready'
事件。
请参阅以下工作片段,
函数 addMarker
将在图表中添加一个三角形。
传递行标签参数和点放置日期,例如
addMarker('Find sources', new Date(2019, 0, 3));
addMarker('Outline paper', new Date(2019, 0, 5, 12));
addMarker('Write paper', new Date(2019, 0, 8));
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([
['Research', 'Find sources', null, new Date(2019, 0, 1), new Date(2019, 0, 5), null, 100, null],
['Write', 'Write paper', 'write', null, new Date(2019, 0, 9), daysToMilliseconds(3), 25, 'Research,Outline'],
['Cite', 'Create bibliography', 'write', null, new Date(2019, 0, 7), daysToMilliseconds(1), 20, 'Research'],
['Complete', 'Hand in paper', 'complete', null, new Date(2019, 0, 10), daysToMilliseconds(1), 0, 'Cite,Write'],
['Outline', 'Outline paper', 'write', null, new Date(2019, 0, 6), daysToMilliseconds(1), 100, 'Research']
]);
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: {
criticalPathEnabled: true,
criticalPathStyle: {
stroke: '#e64a19',
strokeWidth: 5
}
}
};
function daysToMilliseconds(days) {
return days * 24 * 60 * 60 * 1000;
}
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);
}
google.visualization.events.addListener(chart, 'ready', function () {
// add marker for current date
addMarker('Find sources', new Date(2019, 0, 3));
addMarker('Outline paper', new Date(2019, 0, 5, 12));
addMarker('Write paper', new Date(2019, 0, 8));
});
window.addEventListener('resize', drawChart, false);
drawChart();
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="gantt"></div>
更新
标记的大小在多边形元素的 'points'
属性中指定。
在 addMarker
函数的底部,
查看 --> marker.setAttribute('points', ...
'points'
的值应该是三组x,y坐标。
分别为上、左、右。
注意:添加四组 x,y 坐标会添加一个矩形标记。
变量 xCoord
和 yCoord
是计算出的标记放置位置的 x,y 坐标,应该是标记的中心。
因此,为了绘制三角形...
顶部 = xCoord + ',' + (yCoord - 10)
左 = (xCoord - 5) + ',' + yCoord
右 = (xCoord + 5) + ',' + yCoord
综上所述,为了改变标记的大小,
我们更改对变量 xCoord
& yCoord
将标记的大小减半,
我们将按如下方式更改坐标...
顶部 = xCoord + ',' + (yCoord - 5)
左 = (xCoord - 2.5) + ',' + yCoord
右 = (xCoord + 2.5) + ',' + yCoord
例如
marker.setAttribute('points', xCoord + ',' + (yCoord - 5) + ' ' + (xCoord - 2.5) + ',' + yCoord + ' ' + (xCoord + 2.5) + ',' + yCoord);