Chart.JS: Как я могу отображать метки данных только тогда, когда ширина полосы достаточно велика для текста?

Я использую Диаграмма.JS с Плагин меток данных Chart.JS. Можно ли отображать метки данных только тогда, когда ширина полосы достаточно велика для текста?

У меня есть следующий пример:

https://jsfiddle.net/f5p3twcg/2/

var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
    plugins: [ChartDataLabels],
    type: 'bar',
    options: {
        plugins: {
            datalabels: {
                color: '#000000',
                display: true,
                formatter: function(value, ctx) {
                    return value + "kWh";
                }
            }
        }
    },
    data: {
        labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange", "Red1", "Blue1", "Yellow1", "Green1", "Purple1", "Orange1", "Red2", "Blue2", "Yellow2", "Green2", "Purple2", "Orange2", "Red3", "Blue3", "Yellow3", "Green3", "Purple3", "Orange3", "Red4", "Blue4", "Yellow4", "Green4", "Purple4", "Orange4"],
        datasets: [{
            label: '# of Votes',
            data: [12, 19, 3, 5, 2, 3, 12, 19, 3, 5, 2, 3, 12, 19, 3, 5, 2, 3, 12, 19, 3, 5, 2, 3, 12, 19, 3, 5, 2, 3, 12, 19, 3, 5, 2, 3],
            backgroundColor: [
                'rgba(255, 99, 132, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(255, 206, 86, 0.2)',
                'rgba(75, 192, 192, 0.2)',
                'rgba(153, 102, 255, 0.2)',
                'rgba(255, 159, 64, 0.2)',
                'rgba(255, 99, 132, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(255, 206, 86, 0.2)',
                'rgba(75, 192, 192, 0.2)',
                'rgba(153, 102, 255, 0.2)',
                'rgba(255, 159, 64, 0.2)',
                'rgba(255, 99, 132, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(255, 206, 86, 0.2)',
                'rgba(75, 192, 192, 0.2)',
                'rgba(153, 102, 255, 0.2)',
                'rgba(255, 159, 64, 0.2)',
                'rgba(255, 99, 132, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(255, 206, 86, 0.2)',
                'rgba(75, 192, 192, 0.2)',
                'rgba(153, 102, 255, 0.2)',
                'rgba(255, 159, 64, 0.2)',
                'rgba(255, 99, 132, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(255, 206, 86, 0.2)',
                'rgba(75, 192, 192, 0.2)',
                'rgba(153, 102, 255, 0.2)',
                'rgba(255, 159, 64, 0.2)',
                'rgba(255, 99, 132, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(255, 206, 86, 0.2)',
                'rgba(75, 192, 192, 0.2)',
                'rgba(153, 102, 255, 0.2)',
                'rgba(255, 159, 64, 0.2)'
            ]
        }]
    }
});

Я знаю, этот пример не имеет никакого смысла, но вы можете видеть проблему.

Если данных много, метки данных выходят за пределы ширины полосы следующим образом:

enter image description here

Есть ли возможность указать Chart.JS показывать эти метки только тогда, когда текст помещается в полосу? (В противном случае просто покажите всплывающие подсказки).

Я знаю, что такое поведение является стандартным для ZoomCharts (zoomcharts.com) (поскольку я являюсь частью команды, стоящей за этим) ;)

jancha 22.05.2019 14:38

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

FranzHuber23 22.05.2019 14:42
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Сравнение структур данных: Массивы и объекты в Javascript
Сравнение структур данных: Массивы и объекты в Javascript
Итак, вы изучили основы JavaScript и хотите перейти к изучению структур данных. Мотивация для изучения/понимания Структур данных может быть разной,...
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Прошлая статья была первой из цикла статей о создании системы электронной коммерции с использованием Keystone.js, и она была посвящена главным образом...
Приложение для отслеживания бюджета на React js для начинающих
Приложение для отслеживания бюджета на React js для начинающих
Обучение на практике - это проверенная тема для достижения успеха в любой области. Если вы знаете контекст фразы "Практика делает человека...
Стоит ли использовать React в 2022 году?
Стоит ли использовать React в 2022 году?
В 2022 году мы все слышим о трендах фронтенда (React, Vue), но мы не знаем, почему мы должны использовать эти фреймворки, когда их использовать, а...
1
2
1 674
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Если график не меняет размер динамически, вы можете получить ширину полосы после создания экземпляра диаграммы с помощью

var width = myChart.getDatasetMeta(0).data[0]._model.width;

и перепишите средство форматирования, чтобы проверить, не превышает ли ширина текста ширину полосы

formatter: function (value, ctx) {
    function getTextWidth(text, font) {
        // re-use canvas object for better performance
        var canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas"));
        var context = canvas.getContext("2d");
        context.font = font;
        var metrics = context.measureText(text);
        return metrics.width;
    }
    return getTextWidth(value + "kWh") > width ? "" : value + "kWh";
}

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

Возможно, вы могли бы даже написать плагин, который будет записывать в переменную var width перед рендерингом.

plugins: [
    ChartDataLabels,
    {
        beforeRender: (myChart) => { width = myChart.getDatasetMeta(0).data[1]._model.width;}
    }
],

Привет, нет, диаграмма печатается только один раз или полностью обновляется (что означает, что она печатается снова). Я попробую ваше решение.

FranzHuber23 22.05.2019 15:15

Спасибо большое. Он работает, как и ожидалось, после того, как я внес небольшие корректировки (см. Мой ответ здесь).

FranzHuber23 23.05.2019 14:22

Решение от Кшиштоф Кшешевский работает. Однако мне пришлось немного подкорректировать его и добавить несколько проверок на 'undefined' в моем случае:

if (typeof chart !== 'undefined') {
    let datasetData = chart.getDatasetMeta(0);

    if (datasetData !== 'undefined') {
        if (datasetData.data.length > 0) {
            barWidth = chart.getDatasetMeta(0).data[0]._model.width;
        }
    }
}

Другие вопросы по теме