elasticX
- это действительно простая функция, которая в значительной степени выполняет то, что делает ваш код, хотя она фиксирует мин или макс в ноль в зависимости от положительных или отрицательных данных:
var extent = d3.extent(_rowData, _chart.cappedValueAccessor);
if (extent[0] > 0) {
extent[0] = 0;
}
if (extent[1] < 0) {
extent[1] = 0;
}
( calcAxisScale source )
Этот код вызывается (косвенно) перед каждым рендерингом и перерисовкой.
Вот несколько советов общего назначения, когда elasticX
или elasticY
делает не совсем то, что вы хотите.Я никогда не видел, чтобы это провалилось!(Который говорит что-то в такой причудливой кодовой базе, как dc.js.)
Сначала отключите elasticX
.Затем создайте функцию, которая вычисляет домен X и задает его:
function custom_elastic(chart) {
var max = chart.dimension().top[1][0].value;
var min = chart.dimension().top(10)[9].value;
chart.x().domain([min,max]);
}
Я настроил его на диаграмме для общности.
Теперь мы можем вызвать эту функцию для события preRender и preRedraw .Эти события будут проходить по графику при срабатывании:
chart.on('preRender', custom_elastic)
.on('preRedraw', custom_elastic);
И это должно быть сделано!
Кстати, вы, вероятно, не хотите устанавливать диапазон шкалы - это установленоавтоматически по графику, и это немного сложнее, чем у вас, поскольку он учитывает поля.
Отладка мин и макс
Просмотр вашей скрипки IЯ понял, что я не дал второго взгляда на то, как вы рассчитываете минимальное и максимальное значения.
Я также не заметил, что у вас диапазон начинается с -100.
Хорошо сначалапошаговое ведение журнала;он сообщает
min: 0.81, max: 0.82
, что неверно.Верхние десять находятся в диапазоне от 0,96 до 1.
Проблема заключается в том, что ключом измерения является id
, поэтому строки, возвращаемые .top()
, расположены в обратном алфавитном порядке («самые большие» строки).
Опять вы на правильном пути с
console.log(Group.top(Infinity))
Да!Группа даст вам 10 лучших по значению.
var top10 = thischart.group().top(10);
var max = top10[0].value;
var min = top10[9].value;
Отлично!
скрипка
Но подождите, разве это не похоже на то, что бары растягиваются с левой стороны графика?
Хакинг линейного графика с помощью renderlet для рисования баров начиная с левого края
Хорошо, теперь ясно, что линейный график не поддерживает это.Вот хак, чтобы изменить размеры столбцов к левому краю:
chart.on('renderlet', function(chart) {
var transform = chart.select('g.row rect').attr('transform');
var tx = +transform.split('(')[1].split(',')[0];
chart.selectAll('g.row rect')
.attr('transform', null)
.attr('width', function(d) {
return +d3.select(this).attr('width') + tx;
})
chart.selectAll('g.row text.row')
.attr('transform', null);
})
Все ряды строк будут смещены большим отрицательным числом, которое мы сначала захватим в tx
.Затем мы удаляем transform
как из текстов, так и из текста, и добавляем tx
к ширине рядов.
скрипка
Отлично!Но где последний бар?Итак, мы взяли первые десять значений для минимального и максимального значений, поэтому десятый столбец - это минимальное значение.
Вы должны выяснить, что работает для вас, но я обнаружил, что, глядя на верхние 20значения оставили 10 лучших при хороших размерах:
var N = 20;
var topN = thischart.group().top(N);
var max = topN[0].value;
var min = topN[N-1].value;
конечная скрипка
Этот хак делаетне очень хорошо работают со встроенными переходами, поэтому я отключил их для этого графика:
chart.transitionDuration(0)
Было бы гораздо больше работы, чтобы взломать эту часть, и лучше исправить ее вСам график .