Метки круговой диаграммы накладываются друг на друга на экране мобильного устройства.

1
4

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

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

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
<script src="https://cdn.jsdelivr.net/gh/emn178/chartjs-plugin-labels/src/chartjs-plugin-labels.js"></script>
<script>
var pluginLabelsExtension = {
    afterDatasetsUpdate(chart){
        if(chart._labels && chart._labels.length > 0){
            this._installLabelPatch(chart._labels[0].constructor);
        }
    },

    _installLabelPatch(Label){
        if(Label.prototype._patched){
            return;
        }
        Label.prototype._patched = true;
        const _getFontColor = Label.prototype.getFontColor,
            _renderArcLabel = Label.prototype.renderArcLabel;

        // use getFontColor to also get the `reverse` option for this element; save in element._view
        Label.prototype.getFontColor = function(dataset, element, index){
            var fontColor = _getFontColor.call(this, dataset, element, index);
            var reverse = false,
                optionReverse = this.options.reverse;
            if(typeof optionReverse === typeof true){
                reverse = optionReverse;
            }
            else if(typeof optionReverse === 'function'){
                reverse = optionReverse({
                    label: this.chart.config.data.labels[index],
                    value: dataset.data[index],
                    percentage: this.getPercentage(dataset, element, index),
                    backgroundColor: dataset.backgroundColor[index],
                    dataset: dataset,
                    index: index
                });
            }
            else if(Array.isArray(optionReverse)){
                reverse = optionReverse[index];
            }
            element._view.reverse = reverse;
            return fontColor;
        }

        Label.prototype.renderArcLabel = function(label, renderInfo){
            if(renderInfo.view.reverse && typeof label === 'string'){
                var ctx = this.ctx, radius = renderInfo.radius, view = renderInfo.view;
                var deltaToCenterFromEnd = renderInfo.startAngle - view.startAngle - Math.PI / 2;
                ctx.save();
                ctx.translate(view.x, view.y);
                ctx.rotate(renderInfo.endAngle - deltaToCenterFromEnd);
                ctx.textBaseline = 'middle';
                ctx.textAlign = 'left';
                var lines = label.split('\n'), max = 0, widths = [], offset = 0;
                if(this.options.position === 'border'){
                    offset = (lines.length - 1) * this.options.fontSize / 2;
                }
                for(var j = 0; j < lines.length; ++j){
                    var mertrics = ctx.measureText(lines[j]);
                    if(mertrics.width > max){
                        max = mertrics.width;
                    }
                    widths.push(mertrics.width);
                }
                for(var j = 0; j < lines.length; ++j){
                    var line = lines[j];
                    var y = (lines.length - 1 - j) * -this.options.fontSize + offset;
                    ctx.save();
                    var padding = (max - widths[j]) / 2;
                    ctx.rotate(padding / radius);////
                    for(var i = 0; i < line.length; i++){
                        var char = line.charAt(i);
                        mertrics = ctx.measureText(char);
                        ctx.save();
                        ctx.translate(0, -1 * radius);
                        ctx.rotate(Math.PI);
                        ctx.fillText(char, 0, y);
                        ctx.restore();
                        ctx.rotate(-mertrics.width / radius);
                    }
                    ctx.restore();
                }
                ctx.restore();
            }
            else{
                _renderArcLabel.call(this, label, renderInfo)
            }
        }
    }
}

$(document).ready(
    function() {
        var data = {
            datasets: [{
                data: [125, 125, 125, 125, 125, 125, 125, 125],
                backgroundColor: ["#FE4D42","#FFD405","#58E152","#00D59F","#8B7DFF","#E85FED","#F71663","#4F94FF"]
            }],
            labels: [
                "Arts and Creativity",
                "Careers and Employment",
                "Communities and Social",
                "Culture and Heritage",
                "Learning and Skills",
                "Personal Finance",
                "Self-Environment",
                "Wellbeing"
            ]//.map(s => s.split(/[ \-]/)[0])
        };

        var labels_url = {
            "Arts and Creativity" : "arts-and-creativity",
            "Careers and Employment" : "careers-and-employment",
            "Communities and Social" : "communities-and-social",
            "Culture and Heritage" : "culture-and-heritage",
            "Wellbeing" : "health",
            "Learning and Skills" : "learning-and-skills",
            "Personal Finance" : "personal-finance",
            "Self-Environment" : "self-environment"
        };

        var canvas = document.getElementById("myChart");
        var ctx = canvas.getContext("2d");
        var myNewChart = new Chart(ctx,{
            type: 'pie',
            data: data,
            options: {
                legend: {
                    display: false,
                },
                //animation: false,
                plugins: {
                    labels: {
                        render: 'label',
                        arc: true,
                        fontColor:["#FF7805","#0854A3","#14A400","#048A7D","#502788","#F200F2","#FF0068","#000962"],
                        reverse: [false, false, true, true, true, true, false, false],
                        fontSize: 18,
                        position: 'outside'
                    }
                }
            },
            plugins:[
                pluginLabelsExtension
            ]
        });

        canvas.onclick = function(evt) {
            var activePoints = myNewChart.getElementsAtEvent(evt);
            if (activePoints[0]) {
                var chartData = activePoints[0]['_chart'].config.data;
                var idx = activePoints[0]['_index'];

                var label = chartData.labels[idx];
                var value = chartData.datasets[0].data[idx];

                var url = "https://www.maximiseme.co.uk/" + labels_url[label];
                //alert(url);
                console.log(url);
                window.location.href = url;
            }
        };
    }
);
</script>
Анисим
Вопрос задан13 июня 2024 г.

1 Ответ

2

Да, это распространенная проблема при отображении круговой диаграммы на мобильных устройствах. Вот несколько способов решения:

1. Изменение размера текста:

  • Уменьшение размера текста меток:Используйте меньший размер шрифта для меток, чтобы они занимали меньше места.
  • Использование более компактного шрифта: Выберите шрифт, у которого меньшая ширина букв.
  • Сокращение текста: Если у вас длинные метки, попробуйте сократить их. Например, используйте аббревиатуры или сокращения.

2. Изменение положения меток:

  • Перемещение меток наружу:Переместите метки за пределы круговой диаграммы, чтобы они не накладывались на сегменты.
  • Использование радиального расположения: Расположите метки вокруг круговой диаграммы по кругу, сохраняя при этом порядок сегментов.
  • Использование всплывающих подсказок: Показывайте метки только при наведении курсора на сегмент или нажатии на него.

3. Изменение дизайна диаграммы:

  • Уменьшение количества сегментов:Объедините некоторые сегменты, чтобы уменьшить количество меток.
  • Использование цветной кодировки:Используйте цвета для идентификации сегментов вместо меток.
  • Добавление легенды: Поместите легенду с метками в отдельном месте на экране.

4. Использование библиотек:

  • Используйте библиотеки, оптимизированные для мобильных устройств: Существуют библиотеки для визуализации данных, которые оптимизированы для работы на мобильных устройствах. Они могут автоматически адаптировать круговую диаграмму к размеру экрана и решать проблемы с наложением меток.

Пример с использованием библиотеки Chart.js:

var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
  type: 'doughnut',
  data: {
    labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
    datasets: [{
      data: [12, 19, 3, 5, 2, 3],
      backgroundColor: [
        'red',
        'blue',
        'yellow',
        'green',
        'purple',
        'orange'
      ],
      hoverOffset: 4
    }]
  },
  options: {
    plugins: {
      legend: {
        position: 'bottom',
        labels: {
          font: {
            size: 10
          }
        }
      }
    },
    cutout: '60%' // Уменьшаем диаметр круговой диаграммы
  }
});

Дополнительные советы:

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

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

 

Евстигней
Ответ получен7 сентября 2024 г.

Ваш ответ

Загрузить файл.