Обзор

Добро пожаловать в наше подробное руководство по визуализации данных в React с использованием VisX! Визуализация данных играет решающую роль в том, чтобы сделать сложную информацию более понятной и действенной. В этой статье мы рассмотрим, как VisX, мощная библиотека визуализации данных, созданная на основе D3, позволяет разработчикам React с легкостью создавать потрясающие и интерактивные визуализации. Независимо от того, являетесь ли вы опытным разработчиком React, стремящимся улучшить свои навыки представления данных, или новичком, стремящимся погрузиться в мир визуализации данных, эта статья поможет вам освоить VisX и раскрыть весь потенциал веб-приложений, управляемых данными. Присоединяйтесь к нам, и мы отправимся в захватывающее путешествие по преобразованию необработанных данных в красивые, информативные и впечатляющие визуальные эффекты с помощью VisX в React. Давайте погрузимся!

Демо

Диаграммы являются одним из основных примеров визуализации данных. В этой статье мы углубимся в создание демонстрационной функциональной линейной диаграммы с использованием VisX.

Настраивать

VisX — это все, что вам понадобится в этом примере:

yarn add @visx/visx

Типы

Во-первых, нам нужно определить некоторые типы, чтобы было безопаснее кодировать наше приложение.

type CityName = 'New York' | 'San Francisco' | 'Austin';

type TooltipData = {
  bar: SeriesPoint<CityTemperature>;
  key: CityName;
  index: number;
  height: number;
  width: number;
  x: number;
  y: number;
  color: string;
};

type BarStackHorizontalProps = {
  width: number;
  height: number;
  margin?: { top: number; right: number; bottom: number; left: number };
  events?: boolean;
};

Этот код определяет три типа TypeScript: CityName, TooltipData и BarStackHorizontalProps. CityName — это объединение трех строковых литералов, представляющих названия городов. TooltipData содержит данные для отображения всплывающих подсказок на диаграмме. BarStackHorizontalProps определяет свойства для настройки горизонтальной гистограммы.

Имитация данных

import cityTemperature, { CityTemperature } from '@visx/mock-data/lib/mocks/cityTemperature';

const data = cityTemperature.slice(0, 20);
const keys = Object.keys(data[0]).filter((d) => d !== 'date') as CityName[];

const temperatureTotals = data.reduce((allTotals, currentDate) => {
  const totalTemperature = keys.reduce((dailyTotal, k) => {
    dailyTotal += Number(currentDate[k]);
    return dailyTotal;
  }, 0);
  allTotals.push(totalTemperature);
  return allTotals;
}, [] as number[]);

Сама библиотека предоставляет нам множество встроенных фиктивных данных. Этот код TypeScript использует библиотеку VisX для работы с фиктивными данными о температуре для городов. Он создает подмножество данных, фильтрует и извлекает соответствующие ключи, а также вычисляет общие значения температуры для каждой записи. Результаты сохраняются в массиве temperatureTotals.

Утилиты

const parseDate = timeParse('%Y-%m-%d');
const format = timeFormat('%b %d');
const formatDate = (date: string) => format(parseDate(date) as Date);

const getDate = (d: CityTemperature) => d.date;

const temperatureScale = scaleLinear<number>({
  domain: [0, Math.max(...temperatureTotals)],
  nice: true,
});
const dateScale = scaleBand<string>({
  domain: data.map(getDate),
  padding: 0.2,
});
const colorScale = scaleOrdinal<CityName, string>({
  domain: keys,
  range: [red1, red2, red3],
});

Код определяет и инициализирует несколько шкал для визуализации данных:

parseDate и formatDate:

  • parseDate — это функция, которая анализирует строки даты в формате %Y-%m-%d и преобразует их в объекты JavaScript Date.
  • formatDate — это функция, которая принимает строку даты в качестве входных данных, анализирует ее с помощью parseDate, а затем форматирует ее в новую строку в формате %b %d. Эта новая отформатированная строка представляет дату в сокращенном формате месяца и дня.

getDate:

  • getDate — это функция, которая принимает объект типа CityTemperature (предположительно содержащий данные о температуре для города) в качестве входных данных и возвращает значение свойства date из этого объекта. Он используется для извлечения значений даты из массива data.

temperatureScale, dateScale и colorScale:

  • temperatureScale — линейная шкала, определяемая с помощью scaleLinear. Он устанавливает домен от 0 до максимального значения temperatureTotals, а nice: true гарантирует, что шкала генерирует приятные, удобочитаемые значения делений.
  • dateScale — это шкала диапазона, определяемая с помощью scaleBand. Он устанавливает домен в массив дат, извлеченный из массива data с помощью функции getDate. Он также определяет заполнение 0,2 между полосами.
  • colorScale – это порядковый номер, который определяется с помощью scaleOrdinal. Он устанавливает домен в массив keys, который предположительно содержит названия городов. range — это массив значений цвета (например, red1, red2, red3), которые будут сопоставлены с каждым уникальным названием города в массиве keys.

Эти шкалы обычно используются при визуализации данных для сопоставления значений данных с визуальными свойствами, такими как позиции, размеры и цвета. Весы играют решающую роль в создании осмысленных и визуально привлекательных визуализаций данных.

Подсказка

Сначала я должен перейти к всплывающей подсказке, иначе за статьей будет довольно сложно следить. Мы должны обернуть наш компонент withTooltip из VisX следующим образом:

withTooltip<BarStackHorizontalProps, TooltipData>(
  ({
    width,
    height,
    events = false,
    margin = defaultMargin,
    tooltipOpen,
    tooltipLeft,
    tooltipTop,
    tooltipData,
    hideTooltip,
    showTooltip,
  }: BarStackHorizontalProps & WithTooltipProvidedProps<TooltipData>)

Затем мы можем показать всплывающую подсказку:

{tooltipOpen && tooltipData && (
          <Tooltip top={tooltipTop} left={tooltipLeft} style={tooltipStyles}>
            <div style={{ color: colorScale(tooltipData.key) }}>
              <strong>{tooltipData.key}</strong>
            </div>
            <div>{tooltipData.bar.data[tooltipData.key]}℉</div>
            <div>
              <small>{formatDate(getDate(tooltipData.bar.data))}</small>
            </div>
          </Tooltip>
        )}

Полный код

Это полная реализация линейного графика:

<svg width={width} height={height}>
          <rect width={width} height={height} fill={background} rx={14} />
          <Group top={margin.top} left={margin.left}>
            <BarStackHorizontal<CityTemperature, CityName>
              data={data}
              keys={keys}
              height={yMax}
              y={getDate}
              xScale={temperatureScale}
              yScale={dateScale}
              color={colorScale}
            >
              {(barStacks) =>
                barStacks.map((barStack) =>
                  barStack.bars.map((bar) => (
                    <rect
                      key={`barstack-horizontal-${barStack.index}-${bar.index}`}
                      x={bar.x}
                      y={bar.y}
                      width={bar.width}
                      height={bar.height}
                      fill={bar.color}
                      onClick={() => {
                        if (events) alert(`clicked: ${JSON.stringify(bar)}`);
                      }}
                      onMouseLeave={() => {
                        tooltipTimeout = window.setTimeout(() => {
                          hideTooltip();
                        }, 300);
                      }}
                      onMouseMove={() => {
                        if (tooltipTimeout) clearTimeout(tooltipTimeout);
                        const top = bar.y + margin.top;
                        const left = bar.x + bar.width + margin.left;
                        showTooltip({
                          tooltipData: bar,
                          tooltipTop: top,
                          tooltipLeft: left,
                        });
                      }}
                    />
                  )),
                )
              }
            </BarStackHorizontal>
            <AxisLeft
              hideAxisLine
              hideTicks
              scale={dateScale}
              tickFormat={formatDate}
              stroke={red3}
              tickStroke={red3}
              tickLabelProps={{
                fill: red3,
                fontSize: 11,
                textAnchor: 'end',
                dy: '0.33em',
              }}
            />
            <AxisBottom
              top={yMax}
              scale={temperatureScale}
              stroke={red3}
              tickStroke={red3}
              tickLabelProps={{
                fill: red3,
                fontSize: 11,
                textAnchor: 'middle',
              }}
            />
          </Group>
        </svg>

Результат

Это будет результат:

Если вы считаете, что статья слишком сложна для понимания:

Заключение

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

Благодаря использованию обширного набора шкал VisX процесс сопоставления данных с визуальными элементами становится очень эффективным и динамичным. Сочетание React и VisX открывает целый мир возможностей для представления сложных данных в понятной и увлекательной форме.

Независимо от того, являетесь ли вы опытным разработчиком или только начинаете, сила VisX заключается в его способности преобразовывать необработанные данные в привлекательные визуальные повествования, что делает его ценным активом для любого проекта, основанного на данных. Воспользуйтесь возможностями VisX и отправляйтесь в путешествие по созданию увлекательных и информативных визуализаций данных, которые окажут длительное влияние на вашу аудиторию.

Спасибо, что дочитали до конца. Пожалуйста, следите за автором и этой публикацией. Посетите Stackademic, чтобы узнать больше о том, как мы демократизируем бесплатное обучение программированию по всему миру.