gpt4 book ai didi

javascript - 在 Highcharts 仪表图中,如何将 plotband 标签居中放置?

转载 作者:太空宇宙 更新时间:2023-11-04 08:36:32 26 4
gpt4 key购买 nike

我试图在仪表图的绘图带内显示标签,但我不知道如何正确对齐文本。知道如何将标签定位在绘图带的中间吗?或者是否有更简单/替代的方法来创建这种效果?

附言。我使用 Highcharts 的“样式模式”版本。

$(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());
}
});
/**
* @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;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://code.highcharts.com/js/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-more.js"></script>

<div class="container">
<div id="gauge1" class="gauge"></div>
</div>

谢谢!

https://jsfiddle.net/remisture/4e2frewz/9/

最佳答案

您可以使用 svg textPath沿绘图带放置文本的元素。如果将 startOffset 属性设置为 25%(请参阅下文如何计算正确的 startOffset 值),文本将根据绘图带居中。

渲染文本和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/

highcharts textpath plotband

更新:计算 startOffset

25% startOffset 是一个“足够好”的值 - 您可以看到,如果绘图带很粗 - 文本将不会恰好放在中心。

如果 plot band 只是一条线,startOffset 50% 会很完美。

50%

但绘图带有其宽度 - 如果宽度为 0,则 25% 将恰好位于绘图带上线的中心

开始偏移:50%

50% plot band

开始偏移:25%

25% plot band

startOffset:25%,带有细绘图带

25% thin

要计算完全正确的 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)
}

示例:https://jsfiddle.net/g0acwkLr/4/

关于javascript - 在 Highcharts 仪表图中,如何将 plotband 标签居中放置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44436670/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com