Highcharts 专栏系列:居中分类的 x 轴标签

Highcharts Column Series: Centering categorized x-axis labels

我正在使用 React-JSX-Highcharts 制作类似柱状图的直方图。我有 6 个类别,5 个类别有 10 个数据点,第 6 个和最后一个类别有 30 个数据点。我试图实现让刻度线从每个类别开始,但有类别标签,在刻度线之间居中。我能够通过设置 x 轴标签 x: 150 来实现这一点,但是,我了解到它没有响应。

这是我想要实现的目标:

想知道我是否 (A) 采用了错误的方法,(B) 使用了错误的系列类型(我尝试了直方图,但我的箱子是按类别分类的,所以结果是堆叠的列),或者 (C ) 如果我很接近,如果有人能找到解决方案来响应地居中标签。

Highcharts.chart('container', {
    chart: {
    type: 'column'
},
xAxis: {
    categories: [
  "VERY LOW",
  "LOW",
  "MEDIUM",
  "HIGH",
  "VERY HIGH",
  "EXTREMELY HIGH"
],
tickInterval: 10,
startOnTick: true,
tickMarkPlacement: 'between',
type: 'category',
endOnTick: false,
showTempty: true,
},
series: [{
    data: [
  {x: 0, name: 'VERY LOW', y: 0.2},
  {x: 1, name: 'VERY LOW', y: 0.2},
  {x: 2, name: 'VERY LOW', y: 0.8},
  {x: 3, name: 'VERY LOW', y: 1},
  {x: 4, name: 'VERY LOW', y: 1.1},
  {x: 5, name: 'VERY LOW', y: 1.1},
  {x: 6, name: 'VERY LOW', y: 1.3},
  {x: 7, name: 'VERY LOW', y: 1.5},
  {x: 8, name: 'VERY LOW', y: 2},
  {x: 9, name: 'VERY LOW', y: 1.5},
  {y: 2.1, x: 10, name: 'LOW'},
  {y: 2.1, x: 11, name: 'LOW'},
  {y: 2.4, x: 12, name: 'LOW'},
  {y: 2.5, x: 13, name: 'LOW'},
  {y: 2.1, x: 14, name: 'LOW'},
  {y: 2.6, x: 15, name: 'LOW'},
  {y: 2.0, x: 16, name: 'LOW'},
  {y: 2.7, x: 17, name: 'LOW'},
  {y: 2.9, x: 18, name: 'LOW'},
  {y: 2.5, x: 19, name: 'LOW'},
  {y: 2.5, x: 20, name: 'MEDIUM'},
  {y: 3.3, x: 21, name: 'MEDIUM'},
  {y: 3.0, x: 22, name: 'MEDIUM'},
  {y: 2.9, x: 23, name: 'MEDIUM'},
  {y: 2.8, x: 24, name: 'MEDIUM'},
  {y: 2.6, x: 25, name: 'MEDIUM'},
  {y: 2.5, x: 26, name: 'MEDIUM'},
  {y: 2.1, x: 27, name: 'MEDIUM'},
  {y: 2.2, x: 28, name: 'MEDIUM'},
  {y: 2.2, x: 29, name: 'MEDIUM'},
  {y: 2.2, x: 29, name: 'MEDIUM'},
  {y: 2.0, x: 30, name: 'HIGH' },
  {y: 2.0, x: 31, name: 'HIGH' },
  {y: 1.5, x: 32, name: 'HIGH' },
  {y: 1.3, x: 33, name: 'HIGH' },
  {y: 1.2, x: 34, name: 'HIGH' },
  {y: 1.1, x: 35, name: 'HIGH' },
  {y: 1.1, x: 36, name: 'HIGH' },
  {y: 1.0, x: 37, name: 'HIGH' },
  {y: 0.9, x: 38, name: 'HIGH' },
  {y: 0.7, x: 39, name: 'HIGH' },
  {y: 3.1, x: 40, name: 'VERY HIGH'},
  {y: 0.3, x: 41, name: "VERY HIGH"},
  {y: 0.3, x: 42, name: "VERY HIGH"},
  {y: 0.1, x: 43, name: "VERY HIGH"},
  {y: 0.1, x: 44, name: "VERY HIGH"},
  {y: 0.1, x: 45, name: "VERY HIGH"},
  {y: 0, x: 46, name: "VERY HIGH"},
  {y: 0, x: 47, name: "VERY HIGH"},
  {y: 0, x: 48, name: "VERY HIGH"},
  {y: 0, x: 49, name: "VERY HIGH"},
  {y: 0.3, x: 50, name: "EXTREMELY HIGH"},
  {y: 0.3, x: 51, name: "EXTREMELY HIGH"},
  {y: 0.3, x: 52, name: "EXTREMELY HIGH"},
  {y: 0.1, x: 53, name: "EXTREMELY HIGH"},
  {y: 0.1, x: 54, name: "EXTREMELY HIGH"},
  {y: 0.1, x: 55, name: "EXTREMELY HIGH"},
  {y: 0, x: 56, name: "EXTREMELY HIGH"},
  {y: 0, x: 57, name: "EXTREMELY HIGH"},
  {y: 0, x: 58, name: "EXTREMELY HIGH"},
  {y: 0, x: 59, name: "EXTREMELY HIGH"},
  {y: 0, x: 60, name: "EXTREMELY HIGH"},
  {y: 0, x: 61, name: "EXTREMELY HIGH"},
  {y: 0, x: 62, name: "EXTREMELY HIGH"},
  {y: 0, x: 63, name: "EXTREMELY HIGH"},
  {y: 0, x: 64, name: "EXTREMELY HIGH"},
  {y: 0, x: 65, name: "EXTREMELY HIGH"},
  {y: 0, x: 66, name: "EXTREMELY HIGH"},
  {y: 0, x: 67, name: "EXTREMELY HIGH"},
  {y: 0, x: 68, name: "EXTREMELY HIGH"},
  {y: 0, x: 69, name: "EXTREMELY HIGH"},
]
}]

});

JSFiddle

一种以响应方式执行此操作的方法是使用 jQuery resize events 检测图表大小何时发生变化,并在之后动态更新(不要忘记包含 jQuery 如果你使用这个解决方案)。像这样:

$(window).resize(function() {
  setTimeout(function() {
    chart.update({
      xAxis: {
        labels: {
          x: chart.xAxis[0].len / (chart.xAxis[0].tickPositions.length * 2)
        }
      }
    }, true)
  }, 100)
});

我使用与您相同的 xAxis.labels.x 值,但我是动态计算的。

chart.xAxis[0].len - 是 x 轴的长度(以像素为单位)。

(chart.xAxis[0].tickPositions.length * 2) 是 x 轴上的刻度数,乘以 2,因为我们希望位于两个刻度之间的中心,而不是刻度标记处。

使用

setTimeout 是因为如果我们在用户调整大小时正确更新页面,位置将不正确。所以我们等待0.1秒然后更新。

除此之外,在第一次呈现页面时,没有调整大小事件。所以为了调整大小,我使用了 highchart load event 这样的:

chart: {
  type: 'column',
  events: {
    load: function() {
      this.update({
        xAxis: {
          labels: {
            x: this.xAxis[0].len / (this.xAxis[0].tickPositions.length * 2)
          }
        }
      }, true)
    }
  }
},

相同的更新函数,使用 this 而不是 chart 因为图表还没有完全初始化。

var chart = Highcharts.chart('container', {
  chart: {
    type: 'column',
    events: {
      load: function() {
        //Position the labels for the initial rendering
        this.update({
          xAxis: {
            labels: {
              x: this.xAxis[0].len / (this.xAxis[0].tickPositions.length * 2)
            }
          }
        }, true)
      }
    }
  },
  xAxis: {
    categories: [
      "VERY LOW",
      "LOW",
      "MEDIUM",
      "HIGH",
      "VERY HIGH",
      "EXTREMELY HIGH"
    ],
    labels: {
      rotation: 0,

    },
    tickInterval: 10,
    startOnTick: true,
    tickMarkPlacement: 'between',
    type: 'category',
    endOnTick: false,
    showTempty: true,
  },
  series: [{
       data: [
      {x: 0, name: 'VERY LOW', y: 0.2},
      {x: 1, name: 'VERY LOW', y: 0.2},
      {x: 2, name: 'VERY LOW', y: 0.8},
      {x: 3, name: 'VERY LOW', y: 1},
      {x: 4, name: 'VERY LOW', y: 1.1},
      {x: 5, name: 'VERY LOW', y: 1.1},
      {x: 6, name: 'VERY LOW', y: 1.3},
      {x: 7, name: 'VERY LOW', y: 1.5},
      {x: 8, name: 'VERY LOW', y: 2},
      {x: 9, name: 'VERY LOW', y: 1.5},
      {y: 2.1, x: 10, name: 'LOW'},
      {y: 2.1, x: 11, name: 'LOW'},
      {y: 2.4, x: 12, name: 'LOW'},
      {y: 2.5, x: 13, name: 'LOW'},
      {y: 2.1, x: 14, name: 'LOW'},
      {y: 2.6, x: 15, name: 'LOW'},
      {y: 2.0, x: 16, name: 'LOW'},
      {y: 2.7, x: 17, name: 'LOW'},
      {y: 2.9, x: 18, name: 'LOW'},
      {y: 2.5, x: 19, name: 'LOW'},
      {y: 2.5, x: 20, name: 'MEDIUM'},
      {y: 3.3, x: 21, name: 'MEDIUM'},
      {y: 3.0, x: 22, name: 'MEDIUM'},
      {y: 2.9, x: 23, name: 'MEDIUM'},
      {y: 2.8, x: 24, name: 'MEDIUM'},
      {y: 2.6, x: 25, name: 'MEDIUM'},
      {y: 2.5, x: 26, name: 'MEDIUM'},
      {y: 2.1, x: 27, name: 'MEDIUM'},
      {y: 2.2, x: 28, name: 'MEDIUM'},
      {y: 2.2, x: 29, name: 'MEDIUM'},
      {y: 2.2, x: 29, name: 'MEDIUM'},
      {y: 2.0, x: 30, name: 'HIGH' },
      {y: 2.0, x: 31, name: 'HIGH' },
      {y: 1.5, x: 32, name: 'HIGH' },
      {y: 1.3, x: 33, name: 'HIGH' },
      {y: 1.2, x: 34, name: 'HIGH' },
      {y: 1.1, x: 35, name: 'HIGH' },
      {y: 1.1, x: 36, name: 'HIGH' },
      {y: 1.0, x: 37, name: 'HIGH' },
      {y: 0.9, x: 38, name: 'HIGH' },
      {y: 0.7, x: 39, name: 'HIGH' },
      {y: 3.1, x: 40, name: 'VERY HIGH'},
      {y: 0.3, x: 41, name: "VERY HIGH"},
      {y: 0.3, x: 42, name: "VERY HIGH"},
      {y: 0.1, x: 43, name: "VERY HIGH"},
      {y: 0.1, x: 44, name: "VERY HIGH"},
      {y: 0.1, x: 45, name: "VERY HIGH"},
      {y: 0, x: 46, name: "VERY HIGH"},
      {y: 0, x: 47, name: "VERY HIGH"},
      {y: 0, x: 48, name: "VERY HIGH"},
      {y: 0, x: 49, name: "VERY HIGH"},
      {y: 0.3, x: 50, name: "EXTREMELY HIGH"},
      {y: 0.3, x: 51, name: "EXTREMELY HIGH"},
      {y: 0.3, x: 52, name: "EXTREMELY HIGH"},
      {y: 0.1, x: 53, name: "EXTREMELY HIGH"},
      {y: 0.1, x: 54, name: "EXTREMELY HIGH"},
      {y: 0.1, x: 55, name: "EXTREMELY HIGH"},
      {y: 0, x: 56, name: "EXTREMELY HIGH"},
      {y: 0, x: 57, name: "EXTREMELY HIGH"},
      {y: 0, x: 58, name: "EXTREMELY HIGH"},
      {y: 0, x: 59, name: "EXTREMELY HIGH"},
      {y: 0, x: 60, name: "EXTREMELY HIGH"},
      {y: 0, x: 61, name: "EXTREMELY HIGH"},
      {y: 0, x: 62, name: "EXTREMELY HIGH"},
      {y: 0, x: 63, name: "EXTREMELY HIGH"},
      {y: 0, x: 64, name: "EXTREMELY HIGH"},
      {y: 0, x: 65, name: "EXTREMELY HIGH"},
      {y: 0, x: 66, name: "EXTREMELY HIGH"},
      {y: 0, x: 67, name: "EXTREMELY HIGH"},
      {y: 0, x: 68, name: "EXTREMELY HIGH"},
      {y: 0, x: 69, name: "EXTREMELY HIGH"},
    ]
  }]
});
$(window).resize(function() {
  setTimeout(function() {
    chart.update({
      xAxis: {
        labels: {
          x: chart.xAxis[0].len / (chart.xAxis[0].tickPositions.length * 2)
        }
      }
    }, true)
  }, 100)
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<div id="container" style="height: 400px"></div>

工作 JSFiddle 示例: https://jsfiddle.net/ewolden/nLcveqp9/29/