Как новый разработчик, включение новой библиотеки в проект неизбежно требует обучения и часто открывает дополнительные проблемы и возможности обучения, которые на первый взгляд могут показаться ортогональными для поставленной задачи.
Для нашего финального проекта в Fullstack Academy в Чикаго моей команде, завершившей цикл, нужно было включить набор визуализаций данных в наше сатирическое приложение для геймифицированного фондового рынка, и мы решили найти подходящую библиотеку, чтобы помочь.
После некоторых начальных экспериментов с D3 мы решили попробовать что-то, что будет лучше работать с React, и мы настоятельно рекомендовали пакет Victory Chart от Formidable (он используется Nate Silver’s 538 и другими крупными новостными организациями).
Библиотека Victory невероятно проста в использовании и очень модульна. И документы неплохие, хотя кое-где и немного расплывчаты. Если вы знаете React, это будет вам очень знакомо. Вот как сделать базовую линейную диаграмму:
<VictoryChart data={basicData} height={250}> <VictoryLine interpolation=”linear” data={basicData} x={x} y={y} style={{data: {stroke: ‘#c43a31’, strokeWidth: 1}}} /> </VictoryChart>
Вот основные данные, которые мы ему передаем.
const basicData = [{x: 0, y: 2}, {x: 1, y: 2.5}, {x: 2, y: 4}, {x: 3, y: 5}, {x: 4, y: 3}, {x: 5, y: 1}, {x: 6, y: 3}]
А вот как выглядит линейный график:
Довольно круто! Теперь, если вы хотите, чтобы отдельные узлы были более заметными, просто добавьте <VictoryScatter />
либо до, либо после (или вместо!) <VictoryLine />
. (Примечание: если первым будет упорядочен <VictoryLine />
, то узлы разброса будут отображаться поверх строк; в противном случае верно обратное.) Вот два вместе:
А вот код для узлов разброса, который в данном случае был перед <VictoryLine />
:
<VictoryScatter style={{data: {fill: 'green'}}} size={7} data={basicData} />
Хорошо, но что, если у вас много точек данных и хронологическая ось x с множеством неравномерно упорядоченных дат, и вы не хотите, чтобы метки дат перекрывали друг друга, и вы хотите, чтобы иметь возможность увеличивать масштаб диаграммы до бесконечно детализированного уровня, и вы хотите, чтобы даты автоматически анализировали себя? Что ж, вы можете это сделать, и в документации Victory это даже кажется простым. Но есть пара вещей, о которых они вам не говорят, поэтому ваши диаграммы будут выглядеть примерно так:
Ой. Ну обо всем по порядку. После того, как вы вызвали все свои данные из API, вы захотите переформатировать их так, чтобы они представляли собой массив из {x: date, y: price}
объектов. Victory также позволит вам указать эти данные так:
<VictoryChart data={basicData} height={250}> <VictoryLine interpolation=”linear” data={basicData} x="basicData.date" y="basicData.price" style={{data: {stroke: ‘#c43a31’, strokeWidth: 1}}} /> </VictoryChart>
Затем, если вы имеете дело с датами, вам нужно превратить их в настоящие объекты Javascript Date с помощью конструктора new Date (). Помните, что эта конструкция теряется, когда данные поступают из вашего API, поскольку все, что вы получаете, - это набор объектов JSON. Чтобы JS и Victory могли распознать даты, какими они являются, вам потребуется их повторно создать. (Между прочим, если вы не знакомы с объектом JS Date, вот хорошая, обстоятельная статья об этом).
Вы, вероятно, проделаете всю эту процедуру в несколько громоздком Redux Selector, который находится в самом низу вашего магазина. Это будет выглядеть примерно так:
export const getSingleStockChart = (state, stockId) => { return state.transactions.allIds.reduce((result, transId) => { if (state.transactions.byId[transId].stockId == stockId) result.push({ x: new Date(state.transactions.byId[transId].seedDate), y: state.transactions.byId[transId].price }) return result }, []) }
Если вас пугает синтаксис глубоко вложенных объектов, не беспокойтесь, единственная действительно важная часть - это то, что вы возвращаете массив, в котором объект даты объявлен как новый экземпляр объекта JS Date (т.е. new Date («2018–08 –13T17: 34: 28.779Z ”)).
Как только вы это сделаете, Победа будет творит все виды магии!
Объедините этот подход с <VictoryZoomContainer />
, базовой handleZoom()
функцией и разумной функцией по умолчанию state.zoomDomain
, и вперед в гонки! О, еще одна вещь: убедитесь, что вы передали scale
в качестве реквизита для своего <VictoryChart/>
, например: scale={{x: ‘time’}}
. Это ваш сигнал к Победе, чтобы узнать ваши объекты Date такими, какие они есть на самом деле.
Надеюсь, это поможет вам избежать некоторых ловушек, которые у меня были. Как только наш проект будет запущен, я постараюсь вернуться и опубликовать масштабируемые и правильно датированные диаграммы. А пока ознакомьтесь с соответствующими Документами о победе.
Спасибо замечательным людям из Formidable за создание такой замечательной библиотеки! Не стесняйтесь оставлять комментарии, если это вам помогло!