Как в Apache Superset отсортировать стопки (слои) в стековой диаграмме по возрастанию?

Добрый день! При построении столбчатой диаграммы со стековыми (наслоенными) сегментами в Apache Superset не удаётся упорядочить сегменты внутри каждого столбца по возрастанию. В интерфейсе нет кнопки «сделать стопки по возрастанию». Я пробовала создать вычисляемое поле — результата не получилось, причём поле с рангами уже есть в исходной таблице. Прилагаю диаграмму и пример исходных данных. Как можно добиться, чтобы сегменты в каждом столбце были отсортированы по возрастанию?
  • 20 апреля 2026 г. 13:01
Ответы на вопрос 2
Короткий ответ: штатно — никак. Порядок слоёв (серий) в стеке в Superset фиксированный для всей диаграммы и не меняется отдельно для каждого столбца. Если вам нужен «в каждом столбце слои от меньшего к большему», нужно предварительно перестроить данные — превратить «i‑й по величине сегмент в столбце» в отдельную серию (rank_1, rank_2, …). Тогда серийная последовательность задаёт порядок слоёв и он будет соответствовать возрастанию внутри каждого столбца.

Почему так: движки визуализации (ECharts/D3/Vega и т.д.), которые использует Superset, ожидают фиксированный порядок серий по всей оси X. Они не умеют динамически менять порядок слоёв для каждого x‑значения.

Как реализовать (вариант с SQL-перекодировкой / pivot):

1) Для каждой группы по оси X назначьте ранг сегтам по значению (ROW_NUMBER() или RANK()):
   - PARTITION BY x_column ORDER BY value ASC — если хотите нижний слой = самый маленький.
2) Превратите (pivot) строки в колонки: для каждого rank = 1..N сделайте колонку, которая хранит value, иначе 0.
3) Используйте получённый результат как источник данных в Superset и постройте обычную stacked bar: колонки rank_1..rank_N будут естественно стековаться в нужном порядке.

Пример для PostgreSQL (показываю идею; адаптируйте имена колонок и максимум рангов N):

WITH ranked AS (
  SELECT
    x_col,
    category,
    value,
    ROW_NUMBER() OVER (PARTITION BY x_col ORDER BY value ASC) AS rnk
  FROM your_table
)
SELECT
  x_col,
  SUM(CASE WHEN rnk = 1 THEN value ELSE 0 END) AS rank_1,
  SUM(CASE WHEN rnk = 2 THEN value ELSE 0 END) AS rank_2,
  SUM(CASE WHEN rnk = 3 THEN value ELSE 0 END) AS rank_3
  -- добавьте до нужного числа рангов
FROM ranked
GROUP BY x_col
ORDER BY x_col;

После этого в Superset:
- Создайте dataset на основе этого SQL (или view в БД).
- В Bar Chart: в качестве «group by / series» укажите колонки rank_1..rank_N (или просто выберите их как метрики и включите Stack).
- Порядок колонок в легенде/стеке будет соответствовать их порядку в данных (rank_1 внизу и т.д.).

Замечания и советы:
- Нужно заранее знать максимальное число сегментов (N). Если у разных x‑значений разное число сегментов — недостающие будут нулями.
- Подписи серии можно сделать информативнее (например, "1-й (категория)"), но при pivot вы теряете «какая именно исходная категория на каком ранге» как постоянную метку — она может меняться по x. Если хотите показывать имя оригинальной категории в tooltip — это сложнее и потребует доп. трансформаций (например, хранить в отдельной колонке для каждого ранга и использовать кастомную серийную метку).
- Если вам достаточно глобальной сортировки серий по сумме/метрике (а не по каждому столбцу), в настройках некоторых видов диаграмм есть опция «Sort series by metric» (и направление). Это отсортирует слои глобально по общему значению, но не внутри каждого столбца.

Если хотите, могу:
- Подготовить конкретный SQL под вашу СУБД (Postgres / BigQuery / MySQL) и под ваш пример данных;
- Показать, как сделать это через Dataset -> Custom SQL в Superset пошагово.
В Customize → Sort Series By поставь Name и включи Sort Series Ascending — иногда хватает. Если нет — сделай вычисляемое измерение в датасете (Calculated Columns, тип Dimension): <code>CONCAT(rank, '. ', experience)</code> . Получишь '1. 0-3 мес.', '2. 3-12 мес.' и т.д. Суперсет сортирует по имени алфавитно, пачки встанут по рангу. Именно это поле бери как Breakdown.
Похожие вопросы