Подтвердить что ты не робот

Есть ли подходящий способ интегрировать графику d3.js в приложение для приложения Facebook?

Да, я знаю, что есть реакция-арт, но он кажется сломанным.

Проблема заключается в том, что d3.js - все о том, как мутировать DOM браузера, и использовать его напрямую, скажем, внутри метода componentDidMount, не будет работать должным образом, потому что все изменения в DOM браузера не будут отображаться в React virtual DOM. Любые идеи?

4b9b3361

Ответ 1

Одной из стратегий может быть создание компонента черного ящика, который вы никогда не разрешите обновлять. Метод жизненного цикла компонента shouldComponentUpdate() предназначен для того, чтобы компонент самостоятельно определял, нужен ли ререйдер. Если вы всегда возвращаете false из этого метода, React никогда не погрузится в дочерние элементы (то есть, если вы не вызываете forceUpdate()), так что это будет действовать как своего рода брандмауэр для системы глубокого обновления React.

Используйте первый вызов render(), чтобы создать контейнер для диаграммы, затем нарисуйте диаграмму с помощью D3 в методе componentDidMount(). Затем это просто сводится к обновлению вашей диаграммы в ответ на обновления компонента React. Хотя вы, возможно, не должны делать что-то подобное в shouldComponentUpdate(), я не вижу реальной причины, по которой вы не можете идти дальше и вызывать обновление D3 оттуда (см. Код для компонента React _performUpdateIfNecessary()).

Итак, ваш компонент будет выглядеть примерно так:

React.createClass({
    render: function() {
        return <svg></svg>;
    },
    componentDidMount: function() {
        d3.select(this.getDOMNode())
            .call(chart(this.props));
    },
    shouldComponentUpdate: function(props) {
        d3.select(this.getDOMNode())
            .call(chart(props));
        return false;
    }
});

Обратите внимание, что вам нужно вызвать диаграмму как в методе componentDidMount() (для первого рендера), так и в shouldComponentUpdate() (для последующих обновлений). Также обратите внимание, что вам нужен способ передать свойства компонента или состояние в диаграмму и что они контекстно-зависимы: в первом рендере они уже были установлены на this.props и this.state, но в последующих обновлениях новые свойства еще не установлены на компоненте, поэтому вам нужно использовать параметры функции.

Смотрите jsfiddle здесь.

Ответ 3

Вы можете использовать D3 как утилиту, то есть НЕ используйте D3 для изменения DOM. Скорее, используйте D3 для масштабирования и материала оси, но интерполируйте выходы этих функций D3 в html/svg.

Вот пример из моего проекта.

 scale = d3.time.scale()
   .range([ 0, 100 ])
   .clamp(true)

... который передается через опоры в компонент...

React.DOM.rect({
          x: "#{props.scale(start)}%"
          width: "#{Math.abs( props.scale(end) - props.scale(start)) }%"
         })

где React связывает данные с элементами, а не с выбором D3.