Как отсортировать гистограмму с накоплением D3 по 2 свойствам объекта

Я новичок в использовании D3 и создал горизонтальную гистограмму с накоплением на основе https://observablehq.com/@d3/stacked-horizontal-bar-chart.

Это мой график:

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

Диаграмма должна выглядеть примерно так:

Где диаграмма сортируется сначала в алфавитном порядке по названию шкалы на оси Y, а затем по убыванию или возрастанию по значению на оси X.

Это код, который я использую для создания диаграммы и сортировки ее по возрастанию/убыванию:

chartGenerate = stackedBarChart(pandas, 
  {
    x: d => d.value,
    y: d => d.scale,
    z: d => d.key,
    yDomain: d3.groupSort(pandas, 
      D => d3.sum(D, d => (order === "ascending" ? -d.value : d.value)), 
      d => d.scale),
    zDomain: key,
  }
)

Где значение — это значение одной из полос внутри большой полосы по оси X, шкала — это метка по оси Y, а ключ — это массив:

var key = ["punnets_underweight", "punnets_overweight", "punnets_on_weight"]

Порядок — это состояние, которое изменяется между значениями «по возрастанию» и «по убыванию» при нажатии кнопки.

Можно ли как-то изменить функцию groupSort, чтобы она могла сортировать по 2 свойствам объекта? Возможно, я упустил много информации, потому что не знал, как сформулировать все в целом, но это суть моей проблемы.

Поведение ключевого слова "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) для оценки ваших знаний,...
1
0
61
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Вы написали:

Что мне нужно сделать сейчас, так это сначала отсортировать график в алфавитном порядке по метке оси Y, а затем по возрастанию по значению на оси X.

Однако, если я правильно понимаю ваш пример, вы не хотите сортировать по полной метке y (поскольку это будет полностью сортировать yDomain), а только по первой части - возможно, только до Line ${n} или что-то в этом роде. Затем вы хотите отсортировать внутри этих групп по размеру?

Я уверен, что это можно сделать с помощью d3.groupSort, используя более общий компаратор в качестве второго аргумента. Однако иногда мне трудно найти это особое заклинание для более специализированных функций более высокого уровня. Это определенно можно сделать с помощью d3.group, а затем d3.sort.

Поскольку у меня нет доступа к вашим данным, я разветвил блокнот Observable, на который вы ссылались, и создал там пример. В примере я довольно произвольно разбил состояния на первую половину алфавита, а затем на вторую. Затем я отсортировал по населению в этих двух группах. Код там выглядит так:

// An Array of objects with {state, population} keys:
state_populations = Array.from(
  d3.group(stateages, (o) => o.state).values()
).map((a) => ({
  state: a[0].state,
  population: d3.sum(a, (o) => o.population)
}));

/// The yDomain
yDomain = d3
  .sort(
    state_populations,
    (s) => (s.state < "M" ? 1 : 0),
    (s) => s.population
  )
  .map((s) => s.state)

Подробнее вы можете посмотреть в блокноте. Вот верхняя часть получившегося изображения:

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