Правильно разместите метки на осях в D3.js

У меня есть тепловая карта, на которой показаны некоторые данные. Если пользователь нажимает на метку (ось x или y), данные сортируются правильно. Моя проблема - правильное расположение меток до и после сортировки данных.

Это PLUNKER.

Как видите, изначально график выглядит так:

Правильно разместите метки на осях в D3.js

Метки на оси y правильные, а метки на оси x - нет, потому что все они должны быть на одной высоте. Вместо этого они спускаются.

Когда я нажимаю на ddd, он становится:

Правильно разместите метки на осях в D3.js

Та же проблема.

когда я нажимаю на 2001, он становится:

Правильно разместите метки на осях в D3.js

Теперь все в беспорядке.

Код, управляющий расположением меток, следующий:

var rowLabels = svg.append('g')
    .attr('class', 'rowLabels')
    .selectAll('.rowLabels')
    .data(regionsName)
    .enter().append('text')
    .text(function(d) {
        return d;
    })
    .attr('x', 0)
    .attr('y', function(d, i) {
        return i * cellSize;
    })
    .attr('transform', function(d, i) {
        return 'translate(-25, 11)';
    })
    .attr('class', 'rowLabel mono')
    .attr('id', function(d) {
        return 'rowLabel_' + regionsName.indexOf(d);            
    })
    .attr('font-weight', 'normal')
    .on('mouseover', function(d) {
        d3.select(this).attr('font-weight', 'bold').style('fill', 'red');
    })
    .on('mouseout', function(d) {
        d3.select(this).attr('font-weight', 'normal').style('fill', 'black');
    })
    .on('click', function(d, i) {
        rowSortOrder = !rowSortOrder;
        sortByValues('r', i, rowSortOrder);
    });

var colLabels = svg.append('g')
    .attr('class', 'colLabels')
    .selectAll('.colLabels')
    .data(yearsName)
    .enter().append('text')
    .text(function(d) {
        return d;
    })
    .attr('x', 0)
    .attr('y', function(d, i) {
        return i * cellSize;
    })
    .attr('transform', function(d, i) {
        return 'translate(0, -3) rotate(-65)';
    })
    .attr('class', 'colLabel mono')
    .attr('id', function(d) {
        return 'colLabel_' + yearsName.indexOf(d);          
    })
    .attr('font-weight', 'normal')
    .style('text-anchor', 'left')
    .attr('dx', '.8em')
    .attr('dy', '.5em')
    .on('mouseover', function(d) {
        d3.select(this).attr('font-weight', 'bold').style('fill', 'red');
    })
    .on('mouseout', function(d) {
        d3.select(this).attr('font-weight', 'normal').style('fill', 'black');
    })
    .on('click', function(d, i) {
        colSortOrder = !colSortOrder;
        sortByValues('c', i, colSortOrder);
    });

а также:

t.selectAll('.colLabel')
    .attr('y', function(d, i) {
        return sorted.indexOf(i) * cellSize;
    })
    .attr('transform', function(d, i) {
        return 'translate(-10, 2) rotate(-65) rotate(0, 0, ' + (sorted.indexOf(i) * cellSize) + ')';
    });

а также:

t.selectAll('.rowLabel')
    .attr('y', function(d, i) {
        return sorted.indexOf(i) * cellSize;
    })
    .attr('transform', function(d, i) {
        return 'translate(-5, 0)';
    });

Тысячу раз менял, думал, но ничего. Кто-нибудь знает, как мне помочь?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
0
220
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Вы слишком усложняете установку меток осей. При повороте меток метки поворачиваются от начала системы координат, а не от привязки текста. Мы можем увидеть это лучше, если сравним метки как есть, и если мы удалим преобразование и просто будем использовать указанные вами атрибуты x, y:

.attr('x', 0)
.attr('y', function(d, i) {
    return i * cellSize;
})
//.attr('transform', function(d, i) {
//    return 'translate(-25, 11)';
//})

Мы видим, как все метки вращаются вместе вокруг общей точки. Намек на то, что что-то может быть не так с размещением меток, также исходит из кода, который динамически устанавливает значение y и фиксированное значение x для размещения значений, которые отличаются только значениями x.

Мы можем упростить это, вместо того, чтобы устанавливать x, y и преобразование, давайте просто установим преобразование. Сначала мы изменим систему координат так, чтобы начало каждой системы координат меток находилось там, где она закреплена. Затем мы будем вращать:

.attr('transform', function(d, i) {
    return 'translate('+(i*cellSize)+',2) rotate(-65)';
})

Мы также хотим обновить функцию обновления:

t.selectAll('.colLabel')
  .attr('transform', function(d, i) {
    return 'translate('+(sorted.indexOf(i)*cellSize)+',2) rotate(-65)';
  })

Даёт нам:

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

t.selectAll('.rowLabel')
  .attr('y', function(d, i) {
     return sorted.indexOf(i) * cellSize;
   })

Вот обновленный plunkr.

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