charts - 向折线图添加区域
问题描述
我正在尝试绘制一个折线图,其中 X 轴是日期(请参阅此链接)。
var totalChartOptions = {
chart : {title : 'Total cases'},
curveType : 'function',
legend : {position : 'none'},
axes : {x : {0 : {side : 'top'}}},
hAxis : {title : '', format : "dd/MM"},
colors : [ 'orange', 'green', 'red' ],
pointSize : 20,
pointShape : 'diamond',
}
totalData.addColumn("date", "Date");
totalData.addColumn("number", "Confirmed");
totalData.addColumn("number", "Recovered");
totalData.addColumn("number", "Deaths");
... foreach (...)
totalData.addRow([ date, confirmed, recovered, deaths, null ]);
... var chart = new google.charts.Line(totalElement);
chart.draw(totalData, google.charts.Line.convertOptions(vm.totalChartOptions));
对于“今天”,我想添加一个彩色区域以显示数据尚未最终确定。
但是,我不希望该区域是用户交互的(添加另一个图表),只是现有区域的特定背景。我怎么做?
解决方案
材料图表不支持组合图表,
因此无法混合使用线和区域系列'
还有几个不支持的配置选项,
请参阅材料图表特征奇偶校验的跟踪问题...
和经典图表没有在顶部显示 x 轴的选项。但是,我们可以手动修改事件
图表。
为了解决这个问题,我们使用经典图表,并手动将 x 轴标签移动到顶部。 'ready'
使用ComboChart
,我们可以将第四个系列添加为一个区域。
totalData.addColumn('date', 'Date');
totalData.addColumn('number', 'Confirmed');
totalData.addColumn('number', 'Recovered');
totalData.addColumn('number', 'Deaths');
totalData.addColumn('number', 'Today'); // <-- area series
并添加以下选项,将主要系列类型设置为线,
并将第四系列更改为区域。
seriesType: 'line',
series: {
3: {
type: 'area',
color: 'yellow',
pointSize: 0
}
}
为了将该区域显示为图表区域的整个高度,
我们需要找到图表上显示的最大值(或对其进行硬编码)。
// calculate y-axis range
var range = {
min: null,
max: null
};
for (var i = 1; i < totalData.getNumberOfColumns(); i++) {
var colRange = totalData.getColumnRange(i);
range.min = Math.min(range.min, colRange.min);
range.max = Math.max(range.max, colRange.max);
}
并且该区域至少需要两个行值,
在以下代码段中,我们使用带有今天日期的行,
并添加一个额外的日期,否则为空白值。
// add area series data
var colIndex = totalData.getNumberOfColumns() - 1;
totalData.setValue(totalData.getNumberOfRows() - 2, colIndex, range.max);
totalData.setValue(totalData.getNumberOfRows() - 1, colIndex, range.max);
请参阅以下工作片段...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var totalData = new google.visualization.DataTable();
totalData.addColumn('date', 'Date');
totalData.addColumn('number', 'Confirmed');
totalData.addColumn('number', 'Recovered');
totalData.addColumn('number', 'Deaths');
totalData.addColumn('number', 'Today');
// simulate data
totalData.addRow([new Date(2020, 2, 18), 1900, 0, 1, null]);
totalData.addRow([new Date(2020, 2, 20), 1900, 0, 10, null]);
totalData.addRow([new Date(2020, 2, 22), 4000, 2000, 100, null]);
totalData.addRow([new Date(2020, 2, 24), 4000, 2000, 100, null]);
totalData.addRow([new Date(2020, 2, 26), 2400, 0, 100, null]);
totalData.addRow([new Date(2020, 2, 28), 3000, 1000, 110, null]);
totalData.addRow([new Date(2020, 2, 30), 4000, 1000, 90, null]);
totalData.addRow([new Date(2020, 3, 1), 4300, 5000, 20, null]);
totalData.addRow([new Date(2020, 3, 3), 0, 0, 0, null]);
totalData.addRow([new Date(2020, 3, 4), null, null, null, null]);
// calculate y-axis range
var range = {
min: null,
max: null
};
for (var i = 1; i < totalData.getNumberOfColumns(); i++) {
var colRange = totalData.getColumnRange(i);
range.min = Math.min(range.min, colRange.min);
range.max = Math.max(range.max, colRange.max);
}
// add area series data
var colIndex = totalData.getNumberOfColumns() - 1;
totalData.setValue(totalData.getNumberOfRows() - 2, colIndex, range.max);
totalData.setValue(totalData.getNumberOfRows() - 1, colIndex, range.max);
var totalChartOptions = {
chartArea: {
top: 60
},
title : 'Total cases',
curveType: 'function',
legend: {position : 'none'},
hAxis: {title : '', format : 'dd/MM'},
colors: ['orange', 'green', 'red', 'yellow'],
pointSize: 20,
pointShape: 'diamond',
vAxis: {
viewWindow: range
},
seriesType: 'line',
series: {
3: {
type: 'area',
color: 'yellow',
pointSize: 0
}
},
theme: 'material'
}
var chart = new google.visualization.ComboChart(document.getElementById('chart_div'));
// move x-axis to top
google.visualization.events.addListener(chart, 'ready', function () {
var chartLayout = chart.getChartLayoutInterface();
var chartBounds = chartLayout.getChartAreaBoundingBox();
var labels = chart.getContainer().getElementsByTagName('text');
var fontSize;
var yCoord;
Array.prototype.forEach.call(labels, function(label) {
fontSize = parseFloat(label.getAttribute('font-size'));
switch (label.getAttribute('text-anchor')) {
// chart title
case 'start':
yCoord = parseFloat(label.getAttribute('y'));
label.setAttribute('y', yCoord - fontSize);
break;
// x-axis labels
case 'middle':
label.setAttribute('y', chartBounds.top - (fontSize / 2));
break;
// y-axis labels
default:
// ignore
}
});
});
chart.draw(totalData, totalChartOptions);
});
#chart_div {
height: 400px;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
推荐阅读
- netsuite - 休息项目组自定义价格
- constructor - 未设置可靠性值
- javascript - 修改用 jQuery 创建的数组
- c - 是否包含头文件
- javascript - jQuery onclick 方法不起作用两次
- dns - Ubuntu 16.04 上的邮件服务器
- memory-profiling - 如何知道我是否也必须进行内存分析?
- python - 为什么“tf.constant(tf.random_normal((10, 4)))”会导致错误?
- google-chrome-extension - Chrome 扩展程序不显示已发布的程序
- reactjs - Enzyme 无法找到在 React Apollo Query 组件中呈现的子项