Несколько базовых линий с двойной осью Y Google Chart
Я использую API визуализации Google для простой диаграммы продаж, которая имеет две серии: количество продаж и стоимость продаж, которые я показываю на столбчатой диаграмме с двумя вертикальными осями. Значение продаж может быть отрицательным, например, для возвратов, но это приводит к тому, что на графике отображаются две разные базовые линии. Нулевой базовый показатель количества продаж соответствует наименьшему значению продаж. Вот пример кода с некоторыми примерами данных:
google.load('visualization', '1.0', { 'packages': ['corechart'] });
google.setOnLoadCallback(drawSalesChart);
function drawSalesChart() {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn('string', 'Order Source');
dataTable.addColumn('number', 'Num Sales');
dataTable.addColumn('number', 'Sales Value');
dataTable.addRows([
['Web (Order)', 300, 31000],
['Call Centre (Order)', 700, 61000],
['Call Centre (Return)', 50, -4100],
['Call Centre (Exchange)', 10, 800]
]);
var options = {
title: 'Sales by Order Source',
hAxis: { title: 'Order Source' },
series: {
0: { targetAxisIndex: 0 },
1: { targetAxisIndex: 1 },
},
vAxes: {
0: { title: 'Num Sales' },
1: { title: 'Sales Value' }
}
};
new google.visualization.ColumnChart(
document.getElementById('livesales-chart-container')).draw(dataTable, options);
}
Я ознакомился с документацией по API, поскольку есть информация по настройке базовой линии, но, похоже, нет способа связать ноль каждого vAxis с одной и той же точкой. Я пробовал искать в Google и Stackru, и у меня есть похожие вопросы, но я не вижу, чтобы у кого-то была эта проблема.
Как я могу или даже могу показать одну базовую линию в нуле для обеих серий?
1 ответ
С точки зрения визуализации, может быть намного лучше создать две отдельные диаграммы друг на друге, поскольку предоставленные данные сильно отличаются как по объему, так и по тому, что они объясняют.
<!--
You are free to copy and use this sample in accordance with the terms of the
Apache license (http://www.apache.org/licenses/LICENSE-2.0.html)
-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>
Google Visualization API Sample
</title>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load('visualization', '1', {packages: ['corechart']});
</script>
<script type="text/javascript">
function drawSalesChart() {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn('string', 'Order Source');
dataTable.addColumn('number', 'Num Sales');
dataTable.addColumn('number', 'Sales Value');
dataTable.addRows([
['Web (Order)', 300, 31000],
['Call Centre (Order)', 700, 61000],
['Call Centre (Return)', 50, -4100],
['Call Centre (Exchange)', 10, 800]
]);
var dataView1 = new google.visualization.DataView(dataTable);
dataView1.setColumns([0,1]);
var dataView2 = new google.visualization.DataView(dataTable);
dataView2.setColumns([0,2]);
var options1 = {
title: 'Sales by Order Source',
hAxis: { title: 'Order Source' },
vAxis: { title: 'Num Sales' }
};
var options2 = {
title: null,
hAxis: { title: null, textPosition: 'none' },
vAxis: { title: 'Sales Value' }
};
new google.visualization.ColumnChart(
document.getElementById('chart1')).draw(dataView1, options1);
new google.visualization.ColumnChart(
document.getElementById('chart2')).draw(dataView2, options2);
}
google.setOnLoadCallback(drawSalesChart);
</script>
</head>
<body style="font-family: Arial;border: 0 none;">
<div id="chart1" style="width: 600px; height: 300px;"></div>
<div id="chart2" style="width: 600px; height: 100px;"></div>
</body>
</html>
Конечно, для того, чтобы графики правильно выстроились в ряд, и чтобы цвета работали так, как вам нужно, потребуется некоторое времяпровождение, но таким образом вы можете сосредоточиться на основных данных, которые вы хотите показать, сохраняя при этом другую информацию. поблизости в качестве ссылки.
Если вы настаиваете на том, чтобы делать их на одном графике, вам нужно написать функцию, чтобы можно было рассчитать, где должны располагаться линии сетки (или выяснить, как это делает Google, но я не смог найти ее в веб-поиске.).
Чтобы выяснить, какие максимальные / минимальные значения должны быть на графике, "простой" способ - это взять разницу между минимальным и максимальным значениями, сосчитать количество линий сетки, которые у вас будут (по умолчанию для Google это 5), округлить до ближайшей значащей цифры вашего наибольшего числа и используйте их в качестве разделителей линий сетки.
например, принимая ваш первый столбец: 300, 700, 50, 10
Max Value: 700
Min Value: 10
Exponent: LEN(Max)-1 = 2 = 10^2, nearest 100
Grid Lines: 5 - 1 = 4 (assuming you want the bottom value to serve as the floor at the same rounding, you need 4 more iterations to go over the top value)
Difference Between Max and Min: 690
Required Interval: 690 / 4 = 172.5
Rounded up to the nearest 100: 200
Min Value: FLOOR(Min,200) = 0
Max Value: CEILING(Max,200) = 800
Grid Line 1: 0
Grid Line 2: 200
Grid Line 3: 400
Grid Line 4: 600
Grid Line 5: 800
Обратите внимание, это соответствует тому, что показывает ваш график. Тем не менее, это не будет работать для отрицательных значений, потому что математика становится немного сложнее.
Сначала вам нужно выяснить отношение отрицательных значений к общей разнице в минимальных и максимальных значениях.
например, учитывая ваши данные столбца 2: 31000, 61000, -4100, 800
Min Value: -4100
Max Value: 61000
Difference: 65100
Negative Ratio: 6.3%
Так что 6,3% вашего диапазона находится в отрицательной части. Учитывая 5 линий сетки, это означает, что одна линия сетки должна быть ниже 0, и у вас есть только 4 линии сетки для положительной части. Поскольку отрицательная часть меньше положительной, положительная часть будет определять расстояния между линиями сетки.
Итак, теперь у вас есть 4 линии сетки для покрытия положительной части (0 - 61000), что означает, что у вас есть 3 сегмента от 0 до 61000.
Это означает 61000 / 3, округленное до 4 значащих цифр, или 30000.
Это делает ваши линии сетки:
-30,000
0
30,000
60,000
90,000
По совпадению, это то, что вы получили в своем графике.
Теперь, когда вы знаете, что вторая серия имеет 1 отрицательную линию сетки, вам нужно будет перенастроить свою первую серию, чтобы она соответствовала второй. Таким образом, вместо 5 линий сетки (0 и 4 выше), теперь у вас есть 1 отрицательная линия сетки, 1 0, а затем 3 выше нуля, которые должны достичь 700. Таким образом, вы берете 700 положительных значений, которые у вас есть, разделите на 3, для 233,333,
Округлите это до ближайших 100, и вы получите 300.
Таким образом, ваш первый график max/min будет перенастроен на -300 и 900 для следующих линий сетки:
-300
0
300
600
900
Это установит ту же базовую линию.
Это решит вашу проблему - все, что вам нужно сделать, это код этой логики в Javascript! Дайте нам знать, если вы это сделаете, я уверен, что у кого-то еще будет та же проблема в будущем.