Подберите совокупную процентную линию для отсортированной гистограммы с помощью d3 для гистограммы диаграммы Парето
Вот что у меня есть: https://gist.github.com/daluu/fc1cbcab68852ed3c5fa и http://bl.ocks.org/daluu/fc1cbcab68852ed3c5fa. Я пытаюсь повторить функциональность Excel.
Линия вписывается в гистограмму по умолчанию так же хорошо, как в base / original http://bl.ocks.org/daluu/f58884c24ff893186416. И я могу отсортировать гистограмму по убыванию частоты, хотя при этом я переключил шкалу х (с линейной на порядковую). В данный момент я не могу правильно отобразить линию на отсортированную гистограмму. Это должно выглядеть как следующие примеры с точки зрения визуального представления:
- скриншот Excel в комментарии в моем гисте, указанном выше
- диаграмма Парето отсортировала гистограмму в этом посте
- диаграмма Парето (похожая, но не совсем отсортированная гистограмма), сделанная с d3 здесь
Какой лучший подход к проектированию, чтобы заставить остальную часть работать? Должен ли я начать с одной шкалы х и не нужно переключаться с линейного на порядковый? Если это так, я не уверен, как правильно применять компоновку гистограммы с использованием порядкового масштаба или как не использовать линейную шкалу х в качестве источника ввода для компоновки гистограммы и при этом получать желаемый результат.
Используя ту же порядковую шкалу с кодом, который у меня был до сих пор, линия выглядит нормально, но это не та кривая, которую я ожидаю увидеть.
Любая помощь приветствуется.
2 ответа
Основная проблема с линией заключается в том, что кумулятивное распределение необходимо пересчитать после сортировки бара, или, если вы стреляете по статической диаграмме Парето, кумулятивное распределение должно рассчитываться в целевом порядке сортировки. Для этой цели я создал небольшую функцию для этого расчета:
function calcCDF(data){
data.forEach(function(d,i){
if(i === 0){
d.cum = d.y/dataset.length
}else{
d.cum = (d.y/dataset.length) + data[i-1].cum
}
})
return data
}
В моем случае я включаю / выключаю сортировку Парето и каждый раз пересчитываю свойство d.cum. Можно теоретически создать два совокупных свойства dist для начала; iedcum для обычного упорядоченного распределения и скажем d.ParetoCum для отсортированного кумулятивного, но я использую d.cum в подсказке и решил против этого.
По оси я использую единственную порядковую шкалу, которая, на мой взгляд, чище, но потребовала некоторой работы для того, чтобы метки были значимыми для диапазонов чисел, поскольку галочки и метки больше не очерчивают ячейки, как это было бы с линейным масштаб. Мое решение здесь состояло в том, чтобы просто использовать диапазон номеров в качестве отметки, например "1 - 1,99", и добавить функцию для альтернативных отметок (это решение было получено некоторое время назад из чередования заполнения отметки в d3.js).
Для сортировки баров я использую этот пример d3 в качестве справочного материала на тот случай, если вам нужно разобраться в контексте более простого / меньшего примера.
Смотрите эту скрипку, которая включает в себя все вышеперечисленное. Если вы хотите использовать его, я бы предложил добавить проверку, чтобы пользователь не мог переключать как строки, так и строки (оставив примечание в коде... должно быть тривиально)
Вместо сортировки у.
data.sort(function(a,b){ return b.y - a.y;});
вы должны сортировать х
data.sort(function(a,b){ return a.x - b.x;});
Рабочий код здесь