Создавайте привлекательные визуализации с Cytoscape.js

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

Cytoscape.js предлагает удобное решение для быстрого создания точных графических моделей. Благодаря впечатляющим дисплеям, таким как эта интерактивная карта Токийской железнодорожной системы, Cytoscape стал лучшим визуализатором сети для многих веб-разработчиков.

Когда я недавно работал над React project, мне пришлось просмотреть различные источники, чтобы получить полнофункциональную реализацию Cytoscape.js. Благодаря мощи блогов мои прежние головные боли могут помочь вам в процессе настройки, так что вы сможете быстро реализовать потрясающую визуализацию данных в своем следующем проекте React.

Шаг первый - НПМ

Когда у вас есть Приложение React запущено и работает, запустите эти две команды.

npm install cytoscape
npm install react-cytoscapejs

Cytoscape содержит библиотеку графических инструментов, которые мы будем использовать, а React-cytoscapejs преобразует большую часть ванильного JS Cytoscape в компонент React. С помощью этих двух инструментов мы можем организовать наш код в соответствии с традициями React, сохраняя при этом функциональность Cytoscape.

Шаг второй - создание нашего компонента

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

import React, { Component } from 'react'
import CytoscapeComponent from 'react-cytoscapejs'

export default class Demo extends Component {
  
  state = {
    w: 0,
    h: 0,
    elements: []
  }

  componentDidMount = () => {
    this.setState({
      w: window.innerWidth,
      h:window.innerHeight
    })
  }
  
  render() {
    return(
      <div>
        <CytoscapeComponent
            elements={this.state.elements}
            style={{ width: this.state.w, height: this.state.h }}
        />
      </div>
    )
}

Мы начинаем с импорта Cytoscape и react-cytoscapejs, затем создаем «компонент класса» React.

Cytoscape работает путем рендеринга холста HTML, поэтому мы можем удерживать ширину и высоту экрана клиента в состоянии и фиксировать эту информацию при монтировании компонента React.

Cytoscape также потребует данные об элементах, которые нужно отрисовать. После вызова fetch к внутреннему API мы можем сохранить эти данные в состоянии наших компонентов для достижения традиционного, похожего на React, динамического рендеринга.

Наконец, в нашей функции рендеринга вы можете увидеть, как <CytoscapeComponent/> рендерится с переданными элементами нашего состояния и размером экрана.

Шаг третий - доступ к «cy»

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

Первый шаг - объявление переменной cy в нашем компоненте класса.

Добавьте эту строку в качестве опоры на свой <CytoscapeComponent/>.

cy={(cy) => {this.cy = cy}}

Теперь, после того, как наш компонент React смонтирован, у нас есть доступ ко всем традиционным функциям Cytoscape через переменную this.cy!

Предупреждение:

Поскольку this.cy можно объявить только после монтирования компонента, любое упоминание this.cy перед монтированием компонента приведет к поломке всего приложения. Этот простой факт делает интерактивность программирования несколько неинтуитивной, но как только вы распознаете шаблон, он придет быстро.

Чтобы обойти эту опасность, полезно написать функции, которые будут настраивать интерактивность для вас, а затем вызывать эти функции изнутри componentDidMount.

Вам даже нужно следовать этому шаблону, если вы хотите визуализировать другие компоненты React, которые взаимодействуют с cy. Вот простой пример интерактивного <CytoscapeComponent/>, который регистрирует, какой узел данных был нажат пользователем.

import React, { Component } from 'react'
import CytoscapeComponent from 'react-cytoscapejs'

export default class Demo extends Component {
  
  state = {
    w: 0,
    h: 0,
    elements: []
  }

  componentDidMount = () => {
    this.setState({
      w: window.innerWidth,
      h:window.innerHeight
    })
    this.setUpListeners()
  }
  
  setUpListeners = () => {
    this.cy.on('click', 'node', (event) => {
      console.log(event.target)
    })
  }
  
  render() {
    return(
      <div>
        <CytoscapeComponent
            elements={this.state.elements}
            style={{ width: this.state.w, height: this.state.h }}
            cy={(cy) => {this.cy = cy}}
        />
      </div>
    )
}

Шаг четвертый - рендеринг данных и съемка звезд

Это полностью зависит от вас, как вы хотите получить правильные данные для компонента React. Лично я выполнял все вычисления и форматирование на бэкенде на Python, чтобы все было готово к отображению сразу после вызова fetch.

<CytoscapeComponent/> ожидает массив объектов. Каждый желаемый узел должен иметь как минимум два первичных ключа, data: и position:. «Ребра» графика имеют только один первичный ключ, data:, и должны ссылаться на идентификаторы двух узлов. Вот простой пример правильно отформатированных данных:

elements = [
{ data: { id: 'one', label: 'Node 1' }, position: { x: 0, y: 0 } },
{ data: { id: 'two', label: 'Node 2' }, position: { x: 100, y: 0 }},
{ data: { source: 'one', target: 'two', label: 'Edge from Node1 to Node2'}}
]

С этого момента у вас есть функциональный холст данных для изучения, все они содержатся в стандартном формате React!

Существуют сотни, если не тысячи, дополнительных библиотек для импорта вместе с Cytoscape - уровни настройки кажутся бесконечными. При разработке проекта помните об этих основных моментах, чтобы избежать скрытых ошибок:

  • Всегда импортируйте дополнительные ресурсы в верхнюю часть вашего компонента React.
  • Никогда не ссылайтесь на cy в любом коде, который будет прочитан перед монтированием компонента. Это приведет к мгновенному сбою вашего приложения, и его будет сложно отладить по мере роста вашего приложения и включения дополнительных функций Cytoscape.
  • Изучите документацию к Cytoscape и react-cytoscapejs, так как некоторые функции имеют немного другой синтаксис, когда задействован React.

Ресурсы:

Удачи в вашем путешествии по картированию данных! Приветствую и счастливого кодирования.