Как Nivo рассчитывает ширину столбцов на графике?

Я хочу динамически разрешать метки на гистограммах в зависимости от ширины столбцов - если они становятся тонкими, метки выглядят не очень хорошо и часто перекрываются. Однако на самом деле я не хочу возиться с некоторыми низкоуровневыми манипуляциями с элементами SVG, и Nivo нужно что-то использовать для расчета ширины полос; Я мог бы использовать то же самое, чтобы определить, подойдут ли этикетки. Я жду чего-то напрямую от д3, но не знаю.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
244
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Итак, я просмотрел исходный код Nivo и после некоторых поисков нашел то, что искал (вроде как) здесь:

const bandwidth = (indexScale.bandwidth() - innerPadding * (keys.length - 1)) / keys.length

Это версия сгруппированной гистограммы (в отличие от составной, но в этом случае это просто = indexScale.bandwidth()), где innerPadding — это отступы между столбцами в группе, а keys — это клавиши, используемые для одной группы. Однако indexScale — это внутренний объект, созданный с помощью (я упрощаю) createBandScale, который вы можете увидеть здесь:

export const createBandScale = <Input extends StringValue>(
    { round = true }: ScaleBandSpec,
    data: ComputedSerieAxis<Input>,
    size: number,
    axis: ScaleAxis
) => {
    const scale = scaleBand<Input>()
        .range(axis === 'x' ? [0, size] : [size, 0])
        .domain(data.all)
        .round(round)

    return castBandScale<Input>(scale)
}

Эта функция доступна через @nivo/scales, поэтому я могу использовать ее в своих целях. Однако после некоторого тестирования я обнаружил, что мои результаты были неверными: кажется, что в вычислениях игнорируются отступы между группами, поэтому рассчитываемая мной ширина была больше фактической ширины полосы; Я не знаю, почему это так, возможно, это рассматривается где-то дальше, но для моих целей мне просто нужно было создать BandScale вот так:

const bandScale = createBandScale(
    { round: false },
    { all: xAxis },
    totalWidth,
    "x"
).paddingInner(padding) // << this is the important part

Единственной оставшейся проблемой было определение общей ширины элемента SVG, и, к счастью, в кодовой базе Nivo есть такой крючок, но он не является частью пакета, поэтому я добавил его в свой собственный код - вот крюк.

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