Верхние диаграммы с неравномерным интервалом по оси x с метками категорий

#highcharts

#диаграммы с неравномерным расположением оси x

Вопрос:

Я пытаюсь отобразить некоторые разреженные значения по нескольким сотням меток категорий по оси x. Метки представляют точки вдоль географического объекта, поэтому необходимо расположить их в соответствии с фактическим расстоянием между каждой точкой.

Я могу легко создавать категории по оси x и сопоставлять с ними значения, но каждая категория равномерно распределена. Если я перейду на использование комплексного маркера со свойствами {x, y, name}, категории отображаются только в том случае, если они соответствуют интервалу деления. Если категория не соответствует интервалу деления, отображается число.

Я могу создать следующее:

скриншот верхних диаграмм, показывающий метки категорий по оси x

с помощью этой небольшой поддельной выборки данных JSFiddle:

 
    ...
    xAxis: {
        type: 'category'
    },
    series: [{
        name: 'Series 1',
        data: [
          {x:1, y:null, name: 'AB1.1'},
          {x:4, y:1, name: 'AB1.2'},
          {x:5, y:null, name: 'AB1.3'},
          {x:11, y:1, name: 'AB1.4'},
          {x:14, y:null, name: 'AB1.5'},
          {x:14, y:null, name: 'AB1.6'},
          {x:19, y:1, name: 'AB1.7'},
          {x:27, y:1, name: 'AB1.8'},
          {x:28, y:null, name: 'AB1.9'},
          {x:30, y:1, name: 'AB2'},
          {x:37, y:1, name: 'AB2.1'},
          {x:37, y:1, name: 'AB2.2'},
          {x:38, y:1, name: 'AB2.3'},
        ]
    }]
    ...
 

Как вы можете видеть, ось x на этом уровне масштабирования показывает:
0, 3, 6, 9, 12, 15, 18, 21, 24, AB1.8, AB2, 33, 36, 39

Я хочу, чтобы на оси x отображалась любая из фактических меток (при условии, что маркеры расположены относительно их расстояния, точно так же, как значения x на графике); но никаких сгенерированных чисел.

На самом деле у меня есть несколько рядов примерно по 1000 точек в каждом, но все они будут относиться к одному и тому же географическому объекту, поэтому все они имеют одни и те же категории. (JSFiddle с гораздо большим количеством поддельных данных). Я также могу гарантировать, что значения x являются целыми числами.

Я уже пробовал указывать различные параметры оси x вокруг тиков, минимальных тиков и т. Д., Но highcharts по-прежнему хочет экстраполировать равномерно расположенные метки.

Спасибо!

Ответ №1:

Я получил желаемые результаты (JSFiddle) xAxis.tickPositions , динамически устанавливая масштабирование. Для начала я выбираю около 35 позиций по оси x для отображения своих маркеров (произвольное число, но я выбрал то, что подходит для моего размера диаграммы с фиксированной шириной).

Затем при увеличении я обновляю диаграмму, чтобы отобразить около 30 маркеров, которые находятся в пределах нового уровня масштабирования.

Таким образом, у меня всегда отображается большое количество маркеров, и они расположены неравномерно, потому что это то, на что похожи мои фактические данные.

Уменьшенный (L) и увеличенный (R):

Уменьшено Увеличено

это массив всех точек оси x, у которых есть маркер — несколько тысяч

 allTicks = [1, 6, 9, 9, ...]
 

функция для выбора 30 точек из заданного массива

 function selectTickPositions(tickPositions) {
    const maxTicks = 30;
    if (tickPositions.length <= maxTicks) return tickPositions; // return all
    let mod = Math.round(tickPositions.length / maxTicks);
    // always select the first and the last, and then up to 30 more
    return tickPositions.filter((val, idx) => idx == 0 || idx == tickPositions.length - 1 || idx % mod == 0);
}
 

настройка параметров диаграммы:

 let theChart = Highcharts.chart('container', {
    chart: {
        ...
        events: {
          // the selection event is fired when a zoom selection is made
            selection: (event) => {
                let ticks;
                if (event.xAxis) {
                    let min = event.xAxis[0].min;
                    let max = event.xAxis[0].max;
                    ticks = selectTickPositions(allTicks.filter(t => t >= min amp;amp; t <= max));
                } else {
                    ticks = selectTickPositions(allTicks);
                }
                theChart.update({
                    xAxis: {
                        tickPositions: ticks
                    }
                });
                return true;
            }
        }
    },
    ...
    xAxis: {
        type: 'category',
        tickPositions: selectTickPositions(allTicks)
    },
});
 

Ответ №2:

Я не уверен, что хорошо понимаю ваше требование, но вот моя попытка показать, является xAxis.labels ли метка строкой категории.

Демонстрация: https://jsfiddle.net/BlackLabel/4xdjw5L7 /

 xAxis: {
  type: 'category',
  endOnTick: true,
  startOnTick: true,
        labels: {
            formatter() {
                if (typeof this.value !== 'number') {
                    return this.value
                }
            }
        }
},
 

API: https://api.highcharts.com/highcharts/xAxis.labels.formatter

Дайте мне знать, является ли это ожидаемым результатом.

Комментарии:

1. Спасибо за ваш ответ, который помогает избавиться от чисел, но есть ли какой-нибудь способ отобразить еще несколько меток? например, в jsfiddle отображаются только две метки. Я попытался настроить xAxis{ tickInterval: 1, minTickInterval: 1, labels: { step: 1, ...} } , но мне нужно увеличить масштаб несколько раз, прежде чем я увижу больше меток.