簡體   English   中英

在Highcharts量規圖中,如何將繪圖區標簽定位在中心?

[英]In a Highcharts gauge graph, how can I position plotband labels centered?

我試圖在量規圖的繪圖區中顯示標簽,但無法弄清楚如何正確對齊文本。 知道如何將標簽放置在繪圖區的中間嗎? 還是有一種更簡單/替代的方式來產生這種效果?

PS。 我使用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/

高圖文本路徑繪圖帶

更新:Calculat startOffset

25%startOffset是一個“足夠好”的值-您可以看到,如果繪圖帶很粗-文本將不會精確地放置在中間。

如果繪圖帶只是一條線,則startOffset 50%會完美地工作。

50%

但繪圖帶具有寬度-如果寬度為0,則25%恰好是繪圖帶上線的中心

startOffset:50%

50%情節帶

startOffset:25%

25%情節帶

startOffset:較窄繪圖帶時為25%

薄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)    
}

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM