Заказ меток гистограммы в dc.js (снова) - PullRequest
4 голосов
/ 27 мая 2019

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

Это мои данные:

var theData = [{
  "value": "190.79",
  "age_days": "22",
  "criteria": "FX"
}, {
  "value": "18.43",
  "age_days": "22",
  "criteria": "FX"
}, {...}]

Я помещаю данные в ведра как таковые:

var getAge = (d) => {
  if ((d.age_days) <= 7) {
    return (["1w", "2w", "1m", "3m", "6m", "1y", "All"]);
  } else if ((d.age_days) <= 14) {
    return (["2w", "1m", "3m", "6m", "1y", "All"]);
  } else if ((d.age_days) <= 30) {
    return (["1m", "3m", "6m", "1y", "All"]);
  } else if ((d.age_days) <= 90) {
    return (["3m", "6m", "1y", "All"]);
  } else if ((d.age_days) <= 180) {
    return (["6m", "1y", "All"]);
  } else if ((d.age_days) <= 360) {
    return (["1y", "All"]);
  } else {
    return (["All"]);
  }
};

var ndx = crossfilter(theData);
var dims = {};
var groups = {};

dims.age = ndx.dimension(getAge,true);
groups.age = {};
groups.age.valueSum = dims.age.group().reduceSum((d) => d.value);

Затем я пытаюсь заказать группу, используя подход поддельной группы:

var sort_group = (source_group, order) => { 
    return {
        all: () => {
            let g = source_group.all();
            let map = {};
            g.forEach(function (kv) {
                map[kv.key] = kv.value;
            });
            return order
                .filter((k) => map.hasOwnProperty(k))
                .map((k) => {
                    return {key: k, value: map[k]}
                });
        }
    };
};
var the_order = ["1w", "2w", "1m", "3m", "6m", "1y", "All"];
var the_sorted_age_group = sort_group(groups.age.valueSum, the_order);

затем я создаю barChart, используя

theAgeChart
  .height(200)
  .width(400)
  .dimension(dims.age)
  .group(the_sorted_age_group)
  .valueAccessor((d) => d.value)
  .x(d3.scaleBand())
  .xUnits(dc.units.ordinal);

Но он все равно выходит с использованием сортировки по умолчанию:

enter image description here

Я создал jsFiddle здесь , который содержит все.

Как мне отсортировать бары так, как я хочу, чтобы они были отсортированы?

1 Ответ

1 голос
/ 27 мая 2019

Если значение trueX равно true или домен масштаба x не задан, миксин координатной сетки будет генерировать домен X

        if (_chart.elasticX() || _x.domain().length === 0) {
            _x.domain(_chart._ordinalXDomain());
        }

(источник)

Тополностью имеет смысл, но он всегда сортирует домен, когда генерирует его:

_chart._ordinalXDomain = function () {
    var groups = _chart._computeOrderedGroups(_chart.data());
    return groups.map(_chart.keyAccessor());
};

(источник)

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

В любом случае, одним из обходных путей является установка домена самостоятельно:

.x(d3.scaleBand().domain(the_order))

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

При установленном домене это также работает:

.group(groups.age.valueSum)

correctly sorted bars

Вилка вашей скрипки.

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

Я бы не сказал, что это лучший способ, но есть способ заставить его работать.

...