我试图在量表图形的情节带内显示标签,但我无法弄清楚如何正确对齐文字。知道如何在标题带的中间放置标签吗?或者是否有更简单/替代的方式来创建此效果?
PS。我使用"样式模式" Highcharts版本。
longjmp

$(function() {
// Make sure the gauges have correct height on initial load
calculateGaugeHeight();
// And make sure the height is re-calculated on window resize
$(window).on('load resize', function() {
calculateGaugeHeight();
});
var settings = {
gaugeMinValue: 0,
gaugeMaxValue: 8000,
gaugeStartValue: 3000,
gaugeStartAngle: -180,
gaugeEndAngle: 180,
gaugeUpdateInterval: 500 // ms
};
var options = {
tooltip: {
enabled: false
},
chart: {
type: 'gauge'
},
title: false,
pane: {
startAngle: settings.gaugeStartAngle,
endAngle: settings.gaugeEndAngle
},
plotOptions: {
gauge: {
dial: {
radius: 0
},
pivot: {
radius: 0
},
dataLabels: {
borderWidth: 0,
padding: 0,
verticalAlign: 'middle',
style: false,
formatter: function() {
var output = '<div class="gauge-data">';
output += '<span class="gauge-value">' + this.y + '</span>';
output += '</div>';
return output;
},
useHTML: true
}
},
pie: {
dataLabels: false,
animation: false,
startAngle: settings.gaugeStartAngle,
endAngle: settings.gaugeEndAngle,
center: ['50%', '50%'],
states: {
hover: {
enabled: false
}
}
}
},
// the value axis
yAxis: {
offset: 0,
min: settings.gaugeMinValue,
max: settings.gaugeMaxValue,
title: false,
labels: false,
tickAmount: 0,
plotBands: [{
thickness: 25,
outerRadius: "100%",
from: settings.gaugeMinValue,
to: settings.gaugeStartValue,
label: {}
}, {
thickness: 25,
outerRadius: "100%",
from: settings.gaugeStartValue,
to: settings.gaugeMaxValue,
label: {}
}]
},
series: [{
type: 'gauge',
data: [settings.gaugeStartValue],
}, {
type: 'pie',
innerSize: '87%',
className: 'pizza',
data: [{
y: settings.gaugeStartValue,
name: 'Data 1',
className: 'customSeries1'
}, {
y: settings.gaugeMaxValue - settings.gaugeStartValue,
name: 'Data 2',
className: 'customSeries2'
}]
}],
navigation: {
buttonOptions: {
enabled: false
}
},
credits: false
};
$('#gauge1').highcharts(options, buildGraph);
function buildGraph(chart) {
if (!chart.renderer.forExport) {
setInterval(function() {
var gaugePoint = chart.series[0].points[0],
piePoint = chart.series[1],
yAxis = chart.yAxis[0],
newVal,
inc = Math.round((Math.random() - 0.5) * 1500);
newVal = gaugePoint.y + inc;
if (newVal < settings.gaugeMinValue || newVal > settings.gaugeMaxValue) {
newVal = gaugePoint.y - inc;
}
// Update number gauge value
gaugePoint.update(newVal);
// Update pie with current value
piePoint.points[0].update(newVal);
piePoint.points[1].update(settings.gaugeMaxValue - newVal);
yAxis.update({
plotBands: [{
thickness: 25,
outerRadius: "100%",
from: settings.gaugeMinValue,
to: newVal,
label: {
text: 'Text 1',
y: 15,
x: 55,
rotation: 290
}
}, {
thickness: 25,
outerRadius: "100%",
from: newVal,
to: settings.gaugeMaxValue,
label: {
text: 'Text 2',
y: chart.plotSizeY / 2,
x: chart.plotSizeX * 0.87,
rotation: 290
}
}]
});
}, settings.gaugeUpdateInterval);
}
}
function calculateGaugeHeight() {
var div = $('.gauge');
div.height(div.width());
}
});
&#13;
/**
* @license Highcharts
*
* (c) 2009-2016 Torstein Honsi
*
* License: www.highcharts.com/license
*/
.highcharts-container {
position: relative;
overflow: hidden;
width: 100%;
height: 100%;
text-align: left;
line-height: normal;
z-index: 0;
/* #1072 */
-webkit-tap-highlight-color: transparent;
font-family: "Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, sans-serif;
font-size: 12px;
}
.highcharts-root text {
stroke-width: 0;
}
.highcharts-strong {
font-weight: bold;
}
.highcharts-emphasized {
font-style: italic;
}
.highcharts-background {
fill: #ffffff;
}
.highcharts-plot-border,
.highcharts-plot-background {
fill: none;
}
.highcharts-label-box {
fill: none;
}
.highcharts-button-box {
fill: inherit;
}
/* Titles */
.highcharts-title {
fill: #333333;
font-size: 1.5em;
}
.highcharts-subtitle {
fill: #666666;
}
/* Axes */
.highcharts-axis-line {
fill: none;
stroke: #ccd6eb;
}
.highcharts-yaxis .highcharts-axis-line {
stroke-width: 0;
}
.highcharts-axis-title {
fill: #666666;
}
.highcharts-axis-labels {
fill: #666666;
cursor: default;
font-size: 0.9em;
}
.highcharts-grid-line {
fill: none;
stroke: #e6e6e6;
}
.highcharts-xaxis-grid .highcharts-grid-line {
stroke-width: 0;
}
.highcharts-tick {
stroke: #ccd6eb;
}
.highcharts-yaxis .highcharts-tick {
stroke-width: 0;
}
.highcharts-minor-grid-line {
stroke: #f2f2f2;
}
.highcharts-crosshair-thin {
stroke-width: 1px;
stroke: #cccccc;
}
.highcharts-crosshair-category {
stroke: #ccd6eb;
stroke-opacity: 0.25;
}
/* Credits */
.highcharts-credits {
cursor: pointer;
fill: #999999;
font-size: 0.7em;
transition: fill 250ms, font-size 250ms;
}
.highcharts-credits:hover {
fill: black;
font-size: 1em;
}
/* Tooltip */
.highcharts-tooltip {
cursor: default;
pointer-events: none;
white-space: nowrap;
transition: stroke 150ms;
}
.highcharts-tooltip text {
fill: #333333;
}
.highcharts-tooltip .highcharts-header {
font-size: 0.85em;
}
.highcharts-tooltip-box {
stroke-width: 1px;
fill: #f7f7f7;
fill-opacity: 0.85;
}
.highcharts-selection-marker {
fill: #335cad;
fill-opacity: 0.25;
}
.highcharts-graph {
fill: none;
stroke-width: 2px;
stroke-linecap: round;
stroke-linejoin: round;
}
.highcharts-state-hover .highcharts-graph {
stroke-width: 3;
}
.highcharts-state-hover path {
transition: stroke-width 50;
/* quick in */
}
.highcharts-state-normal path {
transition: stroke-width 250ms;
/* slow out */
}
/* Legend hover affects points and series */
g.highcharts-series,
.highcharts-point,
.highcharts-markers,
.highcharts-data-labels {
transition: opacity 250ms;
}
.highcharts-legend-series-active g.highcharts-series:not(.highcharts-series-hover),
.highcharts-legend-point-active .highcharts-point:not(.highcharts-point-hover),
.highcharts-legend-series-active .highcharts-markers:not(.highcharts-series-hover),
.highcharts-legend-series-active .highcharts-data-labels:not(.highcharts-series-hover) {
opacity: 0.2;
}
/* Series options */
/* Default colors */
.highcharts-color-0 {
fill: #7cb5ec;
stroke: #7cb5ec;
}
.highcharts-color-1 {
fill: #434348;
stroke: #434348;
}
.highcharts-color-2 {
fill: #90ed7d;
stroke: #90ed7d;
}
.highcharts-color-3 {
fill: #f7a35c;
stroke: #f7a35c;
}
.highcharts-color-4 {
fill: #8085e9;
stroke: #8085e9;
}
.highcharts-color-5 {
fill: #f15c80;
stroke: #f15c80;
}
.highcharts-color-6 {
fill: #e4d354;
stroke: #e4d354;
}
.highcharts-color-7 {
fill: #2b908f;
stroke: #2b908f;
}
.highcharts-color-8 {
fill: #f45b5b;
stroke: #f45b5b;
}
.highcharts-color-9 {
fill: #91e8e1;
stroke: #91e8e1;
}
.highcharts-area {
fill-opacity: 0.75;
stroke-width: 0;
}
.highcharts-markers {
stroke-width: 1px;
stroke: #ffffff;
}
.highcharts-point {
stroke-width: 1px;
}
.highcharts-dense-data .highcharts-point {
stroke-width: 0;
}
.highcharts-data-label {
font-size: 0.9em;
font-weight: bold;
}
.highcharts-data-label-box {
fill: none;
stroke-width: 0;
}
.highcharts-data-label text {
fill: #333333;
}
.highcharts-data-label-connector {
fill: none;
}
.highcharts-halo {
fill-opacity: 0.25;
stroke-width: 0;
}
.highcharts-point-select {
fill: #cccccc;
stroke: #000000;
}
.highcharts-column-series rect.highcharts-point {
stroke: #ffffff;
}
.highcharts-column-series .highcharts-point {
transition: fill-opacity 250ms;
}
.highcharts-column-series .highcharts-point-hover {
fill-opacity: 0.75;
transition: fill-opacity 50ms;
}
.highcharts-pie-series .highcharts-point {
stroke-linejoin: round;
stroke: #ffffff;
}
.highcharts-pie-series .highcharts-point-hover {
fill-opacity: 0.75;
transition: fill-opacity 50ms;
}
.highcharts-pie-series .highcharts-point-select {
fill: inherit;
stroke: inherit;
}
.highcharts-funnel-series .highcharts-point {
stroke-linejoin: round;
stroke: #ffffff;
}
.highcharts-funnel-series .highcharts-point-hover {
fill-opacity: 0.75;
transition: fill-opacity 50ms;
}
.highcharts-funnel-series .highcharts-point-select {
fill: inherit;
stroke: inherit;
}
.highcharts-pyramid-series .highcharts-point {
stroke-linejoin: round;
stroke: #ffffff;
}
.highcharts-pyramid-series .highcharts-point-hover {
fill-opacity: 0.75;
transition: fill-opacity 50ms;
}
.highcharts-pyramid-series .highcharts-point-select {
fill: inherit;
stroke: inherit;
}
.highcharts-solidgauge-series .highcharts-point {
stroke-width: 0;
}
.highcharts-treemap-series .highcharts-point {
stroke-width: 1px;
stroke: #e6e6e6;
transition: stroke 250ms, fill 250ms, fill-opacity 250ms;
}
.highcharts-treemap-series .highcharts-point-hover {
stroke: #999999;
transition: stroke 25ms, fill 25ms, fill-opacity 25ms;
}
.highcharts-treemap-series .highcharts-above-level {
display: none;
}
.highcharts-treemap-series .highcharts-internal-node {
fill: none;
}
.highcharts-treemap-series .highcharts-internal-node-interactive {
fill-opacity: 0.15;
cursor: pointer;
}
.highcharts-treemap-series .highcharts-internal-node-interactive:hover {
fill-opacity: 0.75;
}
/* Legend */
.highcharts-legend-box {
fill: none;
stroke-width: 0;
}
.highcharts-legend-item text {
fill: #333333;
font-weight: bold;
cursor: pointer;
stroke-width: 0;
}
.highcharts-legend-item:hover text {
fill: #000000;
}
.highcharts-legend-item-hidden * {
fill: #cccccc !important;
stroke: #cccccc !important;
transition: fill 250ms;
}
.highcharts-legend-nav-active {
fill: #003399;
cursor: pointer;
}
.highcharts-legend-nav-inactive {
fill: #cccccc;
}
.highcharts-legend-title-box {
fill: none;
stroke-width: 0;
}
/* Loading */
.highcharts-loading {
position: absolute;
background-color: #ffffff;
opacity: 0.5;
text-align: center;
z-index: 10;
transition: opacity 250ms;
}
.highcharts-loading-hidden {
height: 0 !important;
opacity: 0;
overflow: hidden;
transition: opacity 250ms, height 250ms step-end;
}
.highcharts-loading-inner {
font-weight: bold;
position: relative;
top: 45%;
}
/* Plot bands and polar pane backgrounds */
.highcharts-plot-band,
.highcharts-pane {
fill: #000000;
fill-opacity: 0.05;
}
.highcharts-plot-line {
fill: none;
stroke: #999999;
stroke-width: 1px;
}
/* Highcharts More */
.highcharts-boxplot-box {
fill: #ffffff;
}
.highcharts-boxplot-median {
stroke-width: 2px;
}
.highcharts-bubble-series .highcharts-point {
fill-opacity: 0.5;
}
.highcharts-errorbar-series .highcharts-point {
stroke: #000000;
}
.highcharts-gauge-series .highcharts-data-label-box {
stroke: #cccccc;
stroke-width: 1px;
}
.highcharts-gauge-series .highcharts-dial {
fill: #000000;
stroke-width: 0;
}
.highcharts-polygon-series .highcharts-graph {
fill: inherit;
stroke-width: 0;
}
.highcharts-waterfall-series .highcharts-graph {
stroke: #333333;
stroke-dasharray: 1, 3;
}
/* Highstock */
.highcharts-navigator-mask-outside {
fill-opacity: 0;
}
.highcharts-navigator-mask-inside {
fill: #6685c2;
/* navigator.maskFill option */
fill-opacity: 0.25;
cursor: ew-resize;
}
.highcharts-navigator-outline {
stroke: #cccccc;
fill: none;
}
.highcharts-navigator-handle {
stroke: #cccccc;
fill: #f2f2f2;
cursor: ew-resize;
}
.highcharts-navigator-series {
fill: #335cad;
stroke: #335cad;
}
.highcharts-navigator-series .highcharts-graph {
stroke-width: 1px;
}
.highcharts-navigator-series .highcharts-area {
fill-opacity: 0.05;
}
.highcharts-navigator-xaxis .highcharts-axis-line {
stroke-width: 0;
}
.highcharts-navigator-xaxis .highcharts-grid-line {
stroke-width: 1px;
stroke: #e6e6e6;
}
.highcharts-navigator-xaxis.highcharts-axis-labels {
fill: #999999;
}
.highcharts-navigator-yaxis .highcharts-grid-line {
stroke-width: 0;
}
.highcharts-scrollbar-thumb {
fill: #cccccc;
stroke: #cccccc;
stroke-width: 1px;
}
.highcharts-scrollbar-button {
fill: #e6e6e6;
stroke: #cccccc;
stroke-width: 1px;
}
.highcharts-scrollbar-arrow {
fill: #666666;
}
.highcharts-scrollbar-rifles {
stroke: #666666;
stroke-width: 1px;
}
.highcharts-scrollbar-track {
fill: #f2f2f2;
stroke: #f2f2f2;
stroke-width: 1px;
}
.highcharts-button {
fill: #f7f7f7;
stroke: #cccccc;
cursor: default;
stroke-width: 1px;
transition: fill 250ms;
}
.highcharts-button text {
fill: #333333;
}
.highcharts-button-hover {
transition: fill 0ms;
fill: #e6e6e6;
stroke: #333333;
}
.highcharts-button-pressed {
font-weight: bold;
fill: #e6ebf5;
stroke: #335cad;
}
.highcharts-button-disabled text {
fill: #cccccc;
}
.highcharts-range-selector-buttons .highcharts-button {
stroke-width: 0;
}
.highcharts-range-label rect {
fill: none;
}
.highcharts-range-label text {
fill: #666666;
}
.highcharts-range-input rect {
fill: none;
}
.highcharts-range-input text {
fill: #333333;
}
input.highcharts-range-selector {
position: absolute;
border: 0;
width: 1px;
/* Chrome needs a pixel to see it */
height: 1px;
padding: 0;
text-align: center;
left: -9em;
/* #4798 */
}
.highcharts-crosshair-label text {
fill: #ffffff;
font-size: 1.1em;
}
.highcharts-crosshair-label .highcharts-label-box {
fill: inherit;
}
.highcharts-candlestick-series .highcharts-point {
stroke: #000000;
stroke-width: 1px;
}
.highcharts-candlestick-series .highcharts-point-up {
fill: #ffffff;
}
.highcharts-ohlc-series .highcharts-point-hover {
stroke-width: 3px;
}
.highcharts-flags-series .highcharts-point {
stroke: #999999;
fill: #ffffff;
}
.highcharts-flags-series .highcharts-point-hover {
stroke: #000000;
fill: #ccd6eb;
}
.highcharts-flags-series .highcharts-point text {
fill: #000000;
font-size: 0.9em;
font-weight: bold;
}
/* Highmaps */
.highcharts-map-series .highcharts-point {
transition: fill 500ms, fill-opacity 500ms, stroke-width 250ms;
stroke: #cccccc;
}
.highcharts-map-series .highcharts-point-hover {
transition: fill 0ms, fill-opacity 0ms;
fill-opacity: 0.5;
stroke-width: 2px;
}
.highcharts-mapline-series .highcharts-point {
fill: none;
}
.highcharts-heatmap-series .highcharts-point {
stroke-width: 0;
}
.highcharts-map-navigation {
font-size: 1.3em;
font-weight: bold;
text-align: center;
}
.highcharts-coloraxis {
stroke-width: 0;
}
.highcharts-coloraxis-marker {
fill: #999999;
}
.highcharts-null-point {
fill: #f7f7f7;
}
/* 3d charts */
.highcharts-3d-frame {
fill: transparent;
}
/* Exporting module */
.highcharts-contextbutton {
fill: #ffffff;
/* needed to capture hover */
stroke: none;
stroke-linecap: round;
}
.highcharts-contextbutton:hover {
fill: #e6e6e6;
stroke: #e6e6e6;
}
.highcharts-button-symbol {
stroke: #666666;
stroke-width: 3px;
}
.highcharts-menu {
border: 1px solid #999999;
background: #ffffff;
padding: 5px 0;
box-shadow: 3px 3px 10px #888;
}
.highcharts-menu-item {
padding: 0.5em 1em;
background: none;
color: #333333;
cursor: pointer;
transition: background 250ms, color 250ms;
}
.highcharts-menu-item:hover {
background: #335cad;
color: #ffffff;
}
/* Drilldown module */
.highcharts-drilldown-point {
cursor: pointer;
}
.highcharts-drilldown-data-label text,
.highcharts-drilldown-axis-label {
cursor: pointer;
fill: #003399;
font-weight: bold;
text-decoration: underline;
}
/* No-data module */
.highcharts-no-data text {
font-weight: bold;
font-size: 12px;
fill: #666666;
}
.chart-container {
background: transparent;
}
.highcharts-background {
fill: transparent;
}
.highcharts-plot-background {
background-color: transparent;
}
.highcharts-pie-series .customSeries1 {
border-radius: 20px;
fill: #007272;
}
.highcharts-pie-series .customSeries2 {
fill: #e76a0b;
border-radius: 20px;
}
.highcharts-tooltip-box {
stroke-width: 0;
}
.highcharts-plot-band {
fill: white;
fill-opacity: 1;
stroke-width: 1px;
stroke: lightgray;
}
.highcharts-minor-grid-line,
.highcharts-grid-line {
stroke-width: 0;
}
.highcharts-pane {
fill: white
}
.highcharts-plot-band-label {
font-size: 12px;
text-transform: uppercase;
}
.container {
width: 100%;
max-width: 400px;
}
&#13;
谢谢!
答案 0 :(得分:1)
您可以使用svg textPath元素在绘图带上放置文本。如果将startOffset属性设置为25%(参见下面如何计算正确的startOffset值),文本将根据绘图带居中。
渲染text和textPath的功能可以是这样的:
function renderText(textStr, plotBand, i) {
const id = `plot-band-${i}`
const chart = plotBand.axis.chart
const path = plotBand.svgElem
const textRendered = chart.textRendered
path.attr('id', id)
if (!textRendered[i]) {
const text = chart.renderer.createElement('text')
.attr({
zIndex: 99,
dy: 20,
'text-anchor': 'middle'
})
.css({
color: '#4572A7',
fontSize: '16px'
}).add()
const textPath = chart.renderer.createElement('textPath').attr({
startOffset: '25%'
}).add(text)
textPath.element.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + id)
const textNode = document.createTextNode(textStr)
textPath.element.appendChild(textNode)
textRendered[i] = true
}
}
在加载时创建一个数组。它将阻止呈现多个文本:
chart: {
type: 'gauge',
events: {
load: function() {
this.textRendered = []
}
}
},
在超时内调用该函数:
yAxis.plotLinesAndBands.forEach((plotBand, i) => {
renderText('Custom Text', plotBand, i)
})
https://jsfiddle.net/g0acwkLr/
25%startOffset是一个“足够好”的值 - 你可以看到,如果情节带很厚 - 文本不会完全放在中心。
如果情节带只是一条线,startOffset 50%将完美地运作。
但是情节带有它的宽度 - 如果宽度为0,则25%将恰好是情节带上线的中心
startOffset:50%
startOffset:25%
startOffset:带有薄图带的25%
要计算完全正确的startOffset,您可以测量上部绘图带线和总绘图带线并计算其关系
function calculateStartOffset(wrapper) {
const len = wrapper.element.getTotalLength()
const tempPath = document.createElementNS('http://www.w3.org/2000/svg', 'path')
tempPath.setAttribute('d', wrapper.d.replace(/\sL.*/, '')) // upper line
const len2 = tempPath.getTotalLength()
return Math.round(len2 / 2 / len * 100)
}