Когда разработчики сталкиваются с любой проблемой, которая включает визуализацию данных, большинство примеров диаграммы Google D3 и найдите какой-то код D3, который вроде удовлетворяет их критериям, но им все равно нужно сделать некоторую обратный инжиниринг, чтобы получить его точно вправо. Что кажется простым ребенком рефакторинга, может превратиться в кошмар. Это потому, что D3 может быть немного сложно понять, и есть кривая обучения. Небольшое изменение визуального требования иногда может включать в себя переписывать весь код вашего графика.
Когда я столкнулся с проблемами, которые включают в себя создание простых гистограмм, я всегда обращаюсь к кодированию его с нуля, используя SVG.
Эта статья возьмет вас через шаги в создании базовой диаграммы гистограммы типа инфографики, которая будет визуализировать данные из набора ежемесячных расходов.
Вот видео, которое показывает пошаговое руководство по созданию базовой адаптивной панели
Создайте адаптивную гистограмму в ReactJS.
Что мы строим
Вот как будет выглядеть наша гистограмма, как вы можете, как вы можете, самое высокое значение отображается с именем и значением, а цвет бара является фиолетовым.
Структура приложения
Ниже приведена основная визуальная структура приложения, у нас есть легенда, а SVG, которая содержит график и кнопку. Существует функция, связанная с кнопкой, мы назовем этот обновленный (), это должно генерировать расходы случайных настроек. Как видите, нам также нужна функция, чтобы вернуть самые высокие расходы, мы будем называть это CalculateHiheStexPense ().
Прежде чем нарисовать нашу карту, нам нужно указать некоторые значения измерений:
- Максимальный счет
- Количество
- Значение расхода диаграммы +20 пикселей сверху
- У каждого бара будет иметь 30 пикселей вправо
- Каждое ширина баров составит 50 пикселей
- Ширина диаграммы = (ширина стержня (50) + слияние стержня (30)) * Количество баров (6)
Я выбрал эти цифры, чтобы сделать нашу демонстрацию простой, в реальной жизни, у вас не было бы таких ограничений.
Чтобы нарисовать нашу диаграмму в SVG, нам нужно создать контейнер SVG, используя значения, которые мы указали, как показано выше. Три желтых ящики на диаграмме являются важными атрибутами, которые делают отзывчивый SVG и правильно отображать. В первом желтом ящике у нас есть зона рисования SVG, мы дадим это размер 400 ширину на 220 Hieght. Вторая желтая коробка – порт вид на вид, мы дали эту ширину 100% и 70% высоко. Обратите внимание на несоответствие между значениями ViewPort и ViewBox. Номера процентных процентов просмотра позволяют нам масштабировать его в размере окна. Но это будет только масштабирование пропелезы, если у нас есть атрибут, приведенный в третьей желтой коробке, который является:
preserveAspectRatio="xMidYMax meet"
Весь предмет вокруг SVG и масштабирования – это немного сложной области, вы можете прочитать больше об этом в Эта статья о CSStricks Отказ
На диаграмме выше, у нас также есть тег, который делает бар для каждой из расходов с X, Y, шириной и заполнением цветом в качестве атрибутов.
Диаграмма показывает образец разметки, на котором мы стремимся к нашему демонстрационному приложению, задача состоит в том, чтобы создавать то же самое динамически с нашими данными в реакции. Так вот что мы собираемся сделать.
Наша структура приложения – начните с кода скелета
После создания приложения BoaterPlate с помощью приложения Create-raction и выполните необходимую очистку вверх, мы можем использовать вышеуказанную информацию для построения скелетной структуры нашего приложения. Ниже приведен код для App.js, показан ниже легенды, инициализируя конфигурацию для нашей таблицы и установила пустой SVG Canvas с указанными размерами:
//App.js import React , {useState,useEffect} from 'react'; import './App.css'; //Sample data for expenses for the month const data = [ { name: "Phone", expense: 151 }, { name: "Electricity", expense: 100 }, { name: "Car", expense: 5 }, { name: "House", expense: 43 }, { name: "Food", expense: 56 }, { name: "Leisure", expense: 182 } ]; function App() { // Initialization values that include chart and bar dimensions const [expensesData, setExpensesData] = useState(data); // State value for expenses const maxExpense = 200; const chartHeight = maxExpense + 20; const barWidth = 50; const barMargin = 30; const numberofBars = expensesData.length; let width = numberofBars * (barWidth + barMargin); // Calculate highest expense for the month const calculateHighestExpense = (data) => {} //Button click handler that refresh's expenses data let refreshChart = ()=> { } //Render chart return ( <>Expense Highest expense
{/* To Do: Render children , these will be our bars*/} ); } //Component to render SVG chart const Chart = ({ children, width, height }) => ( ); export default App
Далее Давайте завершим функцию «Рассчитать самые высокие расходы»:
// Calculate highest expense for the month const calculateHighestExpense = (data) => data.reduce((acc, cur) => { const { expense } = cur; return expense > acc ? expense : acc; }, 0);
В этой функции все мы делаем применение функции JavaScript уменьшают на нашем массиве данных. Он пройдет через один на одну сравнение значений и отслеживает наибольшее значение, а затем возвращает наибольшее значение в конце. Мы будем использовать значение, возвращенное для установки состояния для SiteExpense:
const [highestExpense, setHighestExpense] = useState(calculateHighestExpense(data));
Компонент диаграммы
Далее мы собираемся сделать детей для компонента диаграммы. В скелетонном коде выше у нас есть раздел JSX для компонента диаграммы, который в настоящее время выглядит:
{/* To Do: Render children , these will be our bars*/}
Компонент Chart Bar будет отображаться в комментарии, которая в настоящее время говорит «делать». Мы собираемся сделать бар за каждый счет в наших данных, поэтому нам нужно будет применять функцию карты в массив данных. Каждый бар будет представлять элемент с нашими размерами штанга. Так что для вышеуказанного кода будет выглядеть так:
{expensesData.map((data, index) => { const barHeight = data.expense; return ( ); })}
В приведенном выше блоке кода я объявил и назначил Barheight для равных данных.expense. Затем Barheight используется для расчета значения Y. Значение X бар будет рассчитано по формулам (индекс * (Barwidth + Barmargin)). Остальные атрибуты для нашего бареного компонента является самоснабжением.
Барный компонент
Теперь, когда у нас есть компонент диаграммы, и мы знаем, что будут все атрибуты для компонента бара, мы можем записать функцию составляющей панели. Барный компонент вернет элемент с соответствующими атрибутами для правильного отображения его в нашем SVG Canvas. Эта функция компонента будет выглядеть так:
const Bar = ({ x, y, width, height, expenseName,highestExpense }) => ( <>{highestExpense===height ? `${expenseName}: ${height}` : `${height}`} );
Мы возвращаем элемент с расчетными значениями X, Y, ширины и высоты. Кроме того, если текущий бар имеет наибольшее значение расхода, то мы хотим отобразить полосу в фиолетовом режиме, в противном случае отобразите бар с черным цветом. В вышеупомянутом коде мы чередуемся цветами с следующим выражением тройки в атрибуте заполнения:
fill={ highestExpense===height ?`purple`:`black`}
Здесь мы используем строгое равенство «===», чтобы проверить, если SiteExpense равна высоте, высота также является ценностью расхода в этом блоке кода.
В функции панели компонентов мы также возвращаем элемент, который также AHS имеет другое тройное выражение, чтобы чередовать текст:
{highestExpense===height ? `${expenseName}: ${height}` : `${height}`}
Опять же, мы тестируем, если SiteExpense равен высоте, если оно есть, мы сделаем метку с именем и расходами, в противном случае просто сделайте значение. Обратите внимание, что мы используем Backticks для вывода строк, т.е. $ {expensename}: $ {height}
Отказ Мы используем Backticks, поскольку это позволяет объединять переменные в наших строках, это функция ES6, называемых строковыми шаблонами.
…. и, наконец, кнопка обновить
В скелетном коде, который был представлен ранее, у нас была нажатие кнопки, у этого был функция обратного вызова onClick под названием Refreshart, связанная с ним:
Таким образом, конечный кусок кода, который нам нужен, это функция обратного вызова «Refreshart», которая обрабатывает клик. Эта функция будет делать две вещи, один, пересчитал элементы массива, установив элемент расходов на новый счет для каждого элемента массива. Во-вторых, он устанавливает новые государства. Мы можем написать функцию для создания нового набора случайных значений в качестве отдельной функции первой:
const createRandomData = (data) => data.map((exp) => ({ name: exp.name, expense: Math.floor(Math.random() * maxExpense) }))
Затем мы можем использовать это в нашей функции Refreshchart, которая обрабатывает щелчок:
let refreshChart = ()=> { const newData = createRandomData(expensesData); const newHighestexpense = calculateHighestExpense(newData); setExpensesData(newData); setHighestExpense(newHighestexpense); }
Окончательный код и заключение
Вы можете получить доступ к конечному коду на GitHub в https://github.com/ui-code-tv/barchart-demoact.
Здесь намного больше вы можете сделать с SVG, это просто царапает поверхность. Самая сложная часть работы с SVG понимает систему координат и общий рисунок форм и путей. Вы можете узнать больше о координате SVG здесь https://www.sarasoueidan.com/blog/svg-coordinate-systems/ Отказ