Google 条形图 - 未显示水平基线
Google BarChart - the horizontal base line is not appearing
首先,很抱歉将多个问题合并为一个问题。唯一的原因是它们都(希望)与一种特定的图表类型相关。
问题 1:未显示水平基线。
实际
要求
问题 2:分数值。
有没有办法只显示整数?我不需要网格线中的分数值。请看上面的截图。
问题 3:垂直线注释文本放置。
垂直黑色粗线的注释文本位于它的右侧,因此被剪切了。请看下面截图中的第二张图表
这实际上需要这样显示(在行的底部,注释文本需要稍微低于基线标签)。请看下面的截图
这是不可能的吗,有没有办法将注释文本放在该行的左侧,这样它就不会被剪切并且整个注释文本都留在图表中?
下面是我使用的图表脚本:
google.charts.load('current', {packages: ['corechart', 'bar']});
google.charts.setOnLoadCallback(drawHorizontalChart_portal_name_stella_york_horz_month_points);
function drawHorizontalChart_portal_name_stella_york_horz_month_points() {
var data = google.visualization.arrayToDataTable([
["", "Goal Achieved", {role: 'style'}, "GOAL 13.1 points", {role: 'style'}, {role: 'annotation'}],
["", 1.5, "opacity: .75;", 13.1, "opacity: 0;", "GOAL 13.1 points"]
]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation"
}, 3, 4, 5]);
var options = {
title: '',
width: '100%',
height: 120,
chartArea: {
width: '90%',
height: 70
},
hAxis: {
title: '',
minValue: 0,
gridlines: {
count: 6
}
},
bar: {
groupWidth: "60%"
},
legend: {
position: "top"
},
series: {
0: {
color: '#70b5c5',
visibleInLegend: false
}, // Goal Achieved
1: {
color: '#000000',
type: 'line',
annotations: {
textStyle: {
color: '#000000',
textPosition: 'vertical'
},
stemColor: 'none',
vertical: true
}
} // Target Goal
}
};
var chart = new google.visualization.BarChart(document.getElementById("portal-name-stella-york-horz-month-points"));
chart.draw(view, options);
drawVAxisLine(chart, 13.1);
}
jQuery(window).resize(function() {
drawHorizontalChart_portal_name_stella_york_horz_month_points();
});
function drawVAxisLine(chart, value) {
var layout = chart.getChartLayoutInterface();
var chartArea = layout.getChartAreaBoundingBox();
var svg = chart.getContainer().getElementsByTagName('svg')[0];
var xLoc = layout.getXLocation(value)
svg.appendChild(createLine(xLoc, chartArea.top + chartArea.height, xLoc, chartArea.top, '#000000', 2)); // axis line
}
function createLine(x1, y1, x2, y2, color, w) {
var line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
line.setAttribute('x1', x1);
line.setAttribute('y1', y1);
line.setAttribute('x2', x2);
line.setAttribute('y2', y2);
line.setAttribute('stroke', color);
line.setAttribute('stroke-width', w);
return line;
}
1) 水平基线
水平基线没有出现,因为你在第一列中有一个字符串值
这将创建一个 离散 轴
// string used here --> ["", 1.5, "opacity: .75;", 13.1, "opacity: 0;", "GOAL 13.1 points"]
相反,使用连续的 x 轴(数字、日期等...)
// number --> [1, 1.5, "opacity: .75;", 13.1, "opacity: 0;", "GOAL 13.1 points"]
为了隐藏轴标签,就像使用字符串一样,我们可以提供自定义轴ticks
我们可以使用对象表示法来提供值 (v:
) 和格式化值 (f:
)
这允许我们为格式化值
提供一个空字符串
只需确保刻度值与上面第一列中提供的值相匹配。
vAxis: {
gridlines: {
color: 'transparent'
},
ticks: [{v: 1, f: ''}]
}
注意:连续的轴也会导致其他网格线出现,
我们可以通过使它们透明来删除它们...
2) 分数值
我们可以为轴标签提供格式字符串...
hAxis: {
format: '0' // <-- format as integer
},
3) 注释文字放置
此处唯一可用的选项是 stem.length
我们可以提供一个负值来将注释向左移动...
stem: {
color: 'transparent',
length: -128
},
但是,随着图表大小的调整,实际位置将不会保持不变
当图表较小时,文本将离线较远(越大越近)。
相反,我们可以在图表的 'ready'
事件上手动移动注释文本。
但我们仍然应该使用负的词干长度,以确保注释出现在左侧,并防止被切割。否则,我们将最终移动一个剪切注释。
由于我们将注释移动到轴下方,
我们需要增加 chartArea.bottom
否则它也会在那里被切断。
最后,图表将在任何交互活动中重置注释的位置,
比如悬停。我们必须使用 MutationObserver
将注释保留在新位置。
请参阅以下工作片段...
google.charts.load('current', {
packages: ['corechart']
}).then(drawHorizontalChart_portal_name_stella_york_horz_month_points);
function drawHorizontalChart_portal_name_stella_york_horz_month_points() {
var data = google.visualization.arrayToDataTable([
["", "Goal Achieved", {role: 'style'}, "GOAL 13.1 points", {role: 'style'}, {role: 'annotation'}],
[1, 1.5, "opacity: .75;", 13.1, "opacity: 0;", "GOAL 13.1 points"]
]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation"
}, 3, 4, 5]);
var options = {
title: '',
width: '100%',
height: 132,
chartArea: {
height: '100%',
width: '100%',
top: 36,
left: 18,
right: 18,
bottom: 48
},
hAxis: {
title: '',
minValue: 0,
gridlines: {
count: 6
},
format: '0'
},
bar: {
groupWidth: "60%"
},
legend: {
position: "top"
},
series: {
0: {
color: '#70b5c5',
visibleInLegend: false
}, // Goal Achieved
1: {
color: '#000000',
type: 'line',
annotations: {
textStyle: {
color: '#000000'
},
stem: {
color: 'transparent',
length: -128
},
vertical: true
}
} // Target Goal
},
vAxis: {
gridlines: {
color: 'transparent'
},
ticks: [{v: 1, f: ''}]
}
};
var chart = new google.visualization.BarChart(document.getElementById("portal-name-stella-york-horz-month-points"));
google.visualization.events.addListener(chart, 'ready', function () {
// get x location of goal
var layout = chart.getChartLayoutInterface();
var xLoc = drawVAxisLine(chart, layout, data.getValue(0, 3));
// prevent annotation reset
var observer = new MutationObserver(function () {
var annotationText = data.getValue(0, data.getNumberOfColumns() -1);
Array.prototype.forEach.call(chart.getContainer().getElementsByTagName('text'), function(annotation) {
// find annotation
if ((annotation.textContent === annotationText) &&
(annotation.getAttribute('fill') === options.series[1].annotations.textStyle.color)) {
// move annotation
annotationBounds = annotation.getBBox();
annotation.setAttribute('x',
xLoc - (annotationBounds.width / 2)
);
annotation.setAttribute('y',
layout.getYLocation(0) + (parseInt(annotation.getAttribute('font-size')) * 3)
);
}
});
});
observer.observe(chart.getContainer(), {
childList: true,
subtree: true
});
});
chart.draw(view, options);
}
jQuery(window).resize(function() {
drawHorizontalChart_portal_name_stella_york_horz_month_points();
});
function drawVAxisLine(chart, layout, value) {
var chartArea = layout.getChartAreaBoundingBox();
var svg = chart.getContainer().getElementsByTagName('svg')[0];
var xLoc = layout.getXLocation(value)
svg.appendChild(createLine(xLoc, chartArea.top + chartArea.height, xLoc, chartArea.top, '#000000', 2)); // axis line
return xLoc;
}
function createLine(x1, y1, x2, y2, color, w) {
var line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
line.setAttribute('x1', x1);
line.setAttribute('y1', y1);
line.setAttribute('x2', x2);
line.setAttribute('y2', y2);
line.setAttribute('stroke', color);
line.setAttribute('stroke-width', w);
return line;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="portal-name-stella-york-horz-month-points"></div>
注意:在对图表进行任何更改/添加元素之前,您应该等待 'ready'
事件。
首先,很抱歉将多个问题合并为一个问题。唯一的原因是它们都(希望)与一种特定的图表类型相关。
问题 1:未显示水平基线。
实际
要求
问题 2:分数值。
有没有办法只显示整数?我不需要网格线中的分数值。请看上面的截图。
问题 3:垂直线注释文本放置。
垂直黑色粗线的注释文本位于它的右侧,因此被剪切了。请看下面截图中的第二张图表
这实际上需要这样显示(在行的底部,注释文本需要稍微低于基线标签)。请看下面的截图
这是不可能的吗,有没有办法将注释文本放在该行的左侧,这样它就不会被剪切并且整个注释文本都留在图表中?
下面是我使用的图表脚本:
google.charts.load('current', {packages: ['corechart', 'bar']});
google.charts.setOnLoadCallback(drawHorizontalChart_portal_name_stella_york_horz_month_points);
function drawHorizontalChart_portal_name_stella_york_horz_month_points() {
var data = google.visualization.arrayToDataTable([
["", "Goal Achieved", {role: 'style'}, "GOAL 13.1 points", {role: 'style'}, {role: 'annotation'}],
["", 1.5, "opacity: .75;", 13.1, "opacity: 0;", "GOAL 13.1 points"]
]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation"
}, 3, 4, 5]);
var options = {
title: '',
width: '100%',
height: 120,
chartArea: {
width: '90%',
height: 70
},
hAxis: {
title: '',
minValue: 0,
gridlines: {
count: 6
}
},
bar: {
groupWidth: "60%"
},
legend: {
position: "top"
},
series: {
0: {
color: '#70b5c5',
visibleInLegend: false
}, // Goal Achieved
1: {
color: '#000000',
type: 'line',
annotations: {
textStyle: {
color: '#000000',
textPosition: 'vertical'
},
stemColor: 'none',
vertical: true
}
} // Target Goal
}
};
var chart = new google.visualization.BarChart(document.getElementById("portal-name-stella-york-horz-month-points"));
chart.draw(view, options);
drawVAxisLine(chart, 13.1);
}
jQuery(window).resize(function() {
drawHorizontalChart_portal_name_stella_york_horz_month_points();
});
function drawVAxisLine(chart, value) {
var layout = chart.getChartLayoutInterface();
var chartArea = layout.getChartAreaBoundingBox();
var svg = chart.getContainer().getElementsByTagName('svg')[0];
var xLoc = layout.getXLocation(value)
svg.appendChild(createLine(xLoc, chartArea.top + chartArea.height, xLoc, chartArea.top, '#000000', 2)); // axis line
}
function createLine(x1, y1, x2, y2, color, w) {
var line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
line.setAttribute('x1', x1);
line.setAttribute('y1', y1);
line.setAttribute('x2', x2);
line.setAttribute('y2', y2);
line.setAttribute('stroke', color);
line.setAttribute('stroke-width', w);
return line;
}
1) 水平基线
水平基线没有出现,因为你在第一列中有一个字符串值
这将创建一个 离散 轴
// string used here --> ["", 1.5, "opacity: .75;", 13.1, "opacity: 0;", "GOAL 13.1 points"]
相反,使用连续的 x 轴(数字、日期等...)
// number --> [1, 1.5, "opacity: .75;", 13.1, "opacity: 0;", "GOAL 13.1 points"]
为了隐藏轴标签,就像使用字符串一样,我们可以提供自定义轴ticks
我们可以使用对象表示法来提供值 (v:
) 和格式化值 (f:
)
这允许我们为格式化值
提供一个空字符串
只需确保刻度值与上面第一列中提供的值相匹配。
vAxis: {
gridlines: {
color: 'transparent'
},
ticks: [{v: 1, f: ''}]
}
注意:连续的轴也会导致其他网格线出现,
我们可以通过使它们透明来删除它们...
2) 分数值
我们可以为轴标签提供格式字符串...
hAxis: {
format: '0' // <-- format as integer
},
3) 注释文字放置
此处唯一可用的选项是 stem.length
我们可以提供一个负值来将注释向左移动...
stem: {
color: 'transparent',
length: -128
},
但是,随着图表大小的调整,实际位置将不会保持不变
当图表较小时,文本将离线较远(越大越近)。
相反,我们可以在图表的 'ready'
事件上手动移动注释文本。
但我们仍然应该使用负的词干长度,以确保注释出现在左侧,并防止被切割。否则,我们将最终移动一个剪切注释。
由于我们将注释移动到轴下方,
我们需要增加 chartArea.bottom
否则它也会在那里被切断。
最后,图表将在任何交互活动中重置注释的位置,
比如悬停。我们必须使用 MutationObserver
将注释保留在新位置。
请参阅以下工作片段...
google.charts.load('current', {
packages: ['corechart']
}).then(drawHorizontalChart_portal_name_stella_york_horz_month_points);
function drawHorizontalChart_portal_name_stella_york_horz_month_points() {
var data = google.visualization.arrayToDataTable([
["", "Goal Achieved", {role: 'style'}, "GOAL 13.1 points", {role: 'style'}, {role: 'annotation'}],
[1, 1.5, "opacity: .75;", 13.1, "opacity: 0;", "GOAL 13.1 points"]
]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation"
}, 3, 4, 5]);
var options = {
title: '',
width: '100%',
height: 132,
chartArea: {
height: '100%',
width: '100%',
top: 36,
left: 18,
right: 18,
bottom: 48
},
hAxis: {
title: '',
minValue: 0,
gridlines: {
count: 6
},
format: '0'
},
bar: {
groupWidth: "60%"
},
legend: {
position: "top"
},
series: {
0: {
color: '#70b5c5',
visibleInLegend: false
}, // Goal Achieved
1: {
color: '#000000',
type: 'line',
annotations: {
textStyle: {
color: '#000000'
},
stem: {
color: 'transparent',
length: -128
},
vertical: true
}
} // Target Goal
},
vAxis: {
gridlines: {
color: 'transparent'
},
ticks: [{v: 1, f: ''}]
}
};
var chart = new google.visualization.BarChart(document.getElementById("portal-name-stella-york-horz-month-points"));
google.visualization.events.addListener(chart, 'ready', function () {
// get x location of goal
var layout = chart.getChartLayoutInterface();
var xLoc = drawVAxisLine(chart, layout, data.getValue(0, 3));
// prevent annotation reset
var observer = new MutationObserver(function () {
var annotationText = data.getValue(0, data.getNumberOfColumns() -1);
Array.prototype.forEach.call(chart.getContainer().getElementsByTagName('text'), function(annotation) {
// find annotation
if ((annotation.textContent === annotationText) &&
(annotation.getAttribute('fill') === options.series[1].annotations.textStyle.color)) {
// move annotation
annotationBounds = annotation.getBBox();
annotation.setAttribute('x',
xLoc - (annotationBounds.width / 2)
);
annotation.setAttribute('y',
layout.getYLocation(0) + (parseInt(annotation.getAttribute('font-size')) * 3)
);
}
});
});
observer.observe(chart.getContainer(), {
childList: true,
subtree: true
});
});
chart.draw(view, options);
}
jQuery(window).resize(function() {
drawHorizontalChart_portal_name_stella_york_horz_month_points();
});
function drawVAxisLine(chart, layout, value) {
var chartArea = layout.getChartAreaBoundingBox();
var svg = chart.getContainer().getElementsByTagName('svg')[0];
var xLoc = layout.getXLocation(value)
svg.appendChild(createLine(xLoc, chartArea.top + chartArea.height, xLoc, chartArea.top, '#000000', 2)); // axis line
return xLoc;
}
function createLine(x1, y1, x2, y2, color, w) {
var line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
line.setAttribute('x1', x1);
line.setAttribute('y1', y1);
line.setAttribute('x2', x2);
line.setAttribute('y2', y2);
line.setAttribute('stroke', color);
line.setAttribute('stroke-width', w);
return line;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="portal-name-stella-york-horz-month-points"></div>
注意:在对图表进行任何更改/添加元素之前,您应该等待 'ready'
事件。