You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Highcharts仅显示JSON中指定的X轴日期?

问题描述

当前行为

图表X轴生成了连续的全周日期序列,例如:2022-5-30、2022-5-31、2022-6-1、2022-6-2、2022-6-3、2022-6-4、2022-6-5、2022-6-6。

复现方式

可通过在线演示复现问题。

代码片段

let globalData = []; let finRez = [];
let chart;

let duration = 500; // 控制新数据点之间的动画时长
let startIterator = 1; // 初始化图表时渲染的数据点数量
let currentIterator = startIterator;
let maxIterator = 1;

let guiButton = document.getElementById('start');
let guiButtonState = 'Start';
let intervalId;

// 获取数据:
fetch('https://raw.githubusercontent.com/veleg/trade/main/trade.json')
  .then(response => response.json())
  .then(data => {
    parseData(data);
    createChart();
    initEvents();
  });

function initEvents() {
  guiButton.addEventListener('click', function() {
    if (guiButtonState === 'Stop') {
      // 用户点击"Stop" -> 停止动画,允许恢复
      intervalId = clearInterval(intervalId);
      guiButton.innerText = guiButtonState = 'Resume';
    } else {
      // 如果动画已结束,重新创建图表
      if (guiButtonState === 'Restart') {
        createChart();
      }
      guiButton.innerText = guiButtonState = 'Stop';
      // 启动动画:
      redrawChart(currentIterator += 1);
      intervalId = setInterval(function() {
        // 如果到达最后一个数据点,停止动画:
        if (currentIterator === maxIterator) {
          intervalId = clearInterval(intervalId);
          currentIterator = startIterator;
          guiButton.innerText = guiButtonState = 'Restart';
        } else {
          redrawChart(currentIterator += 1);
        }
      }, duration);
    }
  });
}

function redrawChart(index) {
  // 每次重绘时更新副标题
  chart.setTitle(null, {
    text:  ' Заработано: ' + globalData[0].data[index][1]
  }, false);
    
    
    const newValues = globalData.map(series => series.data[index][1]);
    const maxIndex = newValues.indexOf(Math.max.apply(null, newValues));

  // 为每个系列添加数据点:
  chart.series.forEach(
    (series, seriesIndex) => {
            const enabled = maxIndex === seriesIndex && ((index < 5) || (index % 5 === 0));
      series.addPoint(
                {
          x: globalData[seriesIndex].data[index][0],
          y: globalData[seriesIndex].data[index][1]
                    <!-- dataLabels: { -->
                        <!-- enabled -->
                    <!-- }, -->
                    <!-- marker: { -->
                        <!-- enabled -->
                    <!-- } -->
        },
        false,
        false,
        false
      );
    }
  );

  // 所有更新完成后,重绘图表:
  chart.redraw({
    duration
  });
}

function parseData(data) {
  Highcharts.objectEach(
    data,
    // 转换为Highcharts要求的数据格式:
    // series: [{
    //   data: [ [x, y], [x, y], ..., [x, y]]
    // }]
    (countryData, country) => {
            if (country !== 'Diamond Princess' && country !== 'Holy See') {
                globalData.push({
                    name: country,
                    data: countryData.map(p => [Date.parse(p.date), p.recovered / getCountryPopulation(country)])
                    <!-- data: countryData.map(p => [p.date, p.recovered / getCountryPopulation(country)]), -->
                    <!-- datas: countryData.date, -->
                    <!-- datass: countryData.map(p => [p.date, p.date]) -->
                });
            }       
            
        }
  );


  // 排序并限制数据集:
  globalData = globalData
    .sort((countryA, countryB) => {
      let countryALen,
        countryBLen;

      if (!countryA || !countryA.data || countryA.data.length === 0) {
        return 1;
      }

      if (!countryB || !countryB.data || countryB.data.length === 0) {
        return -1;
      }

      return countryB.data[countryB.data.length - 1][1] - countryA.data[countryA.data.length - 1][1];
    })
    .splice(0, 8);
        

  maxIterator = Math.max.apply(null, globalData.map(series => series.data.length - 1));
}


function createChart() {
    function format(y) {
    return y.toFixed(2);
  }

  chart = Highcharts.chart('container', {
    chart: {
      type: 'spline',
      marginLeft: 100
    },

    legend: {
      layout: 'proximate',
      align: 'right'
    },


    title: {
      floating: true,
      align: 'left',
      x: 93,
      y: 20,
      text: 'Confirmed cases per country per 1000 inhabitants'
    },
    subtitle: {
      floating: true,
      align: 'left',
      y: 60,
      x: 90,
      text:  ' Заработано: ' + globalData[0].data[0][1],
      style: {
        fontSize: '20px'
      }
    },
    tooltip: {
      split: true,
      pointFormatter: function() {
        <!-- var value = format(this.y); -->
        <!-- return `<span style="color:${this.color}">●</span> ${this.series.name}: <b>${value}</b><br/>`; -->
            }
    },

    yAxis: {
      title: {
        text: ''
      },
      maxPadding: 0.2,
      softMax: 1
    },

    xAxis: {

      gridLineWidth: 2,
      min: globalData[0].data[0][0],
      minRange: 7 * 24 * 3600 * 1000,
      type: 'datetime'
      <!-- categories: [1] -->
    },


    plotOptions: {
      series: {
        animation: {
          duration
        },
        <!-- marker: { -->
          <!-- symbol: 'circle' -->
        <!-- }, -->
        dataLabels: {
          formatter: function() {
            return format(this.y);
          }
        }
      }
    },
    series: globalData.map(series => {
      return {
        name: series.name,
        data: series.data.slice(0, startIterator).map(point => {
                    return { x: point[0], y: point[1] }
                })
      }
    })
  });
}


function getCountryPopulation(country) {
  return {
    "Заработано": 1,
    "Финансовый результат": 1
  }[country];
}

使用版本

Highcharts JS v10.3.2 (2022-11-28)

需求说明

需要让X轴跳过JSON文件中未指定的日期,仅保留指定日期(例如:2022-5-30、2022-5-31、2022-6-1、2022-6-2、2022-6-3、2022-6-6)。无需过滤JSON,JSON已明确所需日期,但脚本会自动补充不存在的日期。需禁用Highcharts自动补全缺失日期的功能,仅展示JSON内的日期(可间隔或为周末)。

解决方案

要解决Highcharts自动补全缺失日期的问题,核心是将X轴类型从datetime改为category,同时调整数据格式适配分类轴,具体步骤如下:

  1. 修改createChart函数中的X轴配置,移除datetime相关参数并替换类型:
xAxis: {
  gridLineWidth: 2,
  type: 'category' // 替换原有的datetime类型
}
  1. 调整parseData函数中的数据处理逻辑,将日期从时间戳改为字符串格式:
data: countryData.map(p => [p.date, p.recovered / getCountryPopulation(country)])
  1. 确保redrawChart函数中添加数据点时,x值保持字符串日期格式,与分类轴匹配。

修改后,X轴会严格按照JSON中提供的日期顺序展示,不会自动补全缺失的日期。


内容的提问来源于stack exchange,提问作者Ринат Ауди

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 15:15:10