2016-07-12 6 views
0

Этот компонент создается как часть просмотра страницы, на котором пользователи переходят на начальную панель. Все данные, которые SVG должен правильно отображать, правильно регистрируются, но SVG просто не создается при начальной навигации к этому представлению. Функция работает, но SVG не отображается в html. Сначала я подумал, что это связано с тем, что изображение еще не загружено, но SVG присоединяется к div не непосредственно к изображению, поэтому, по крайней мере, я думаю, что оно появляется в html минус ширина и высота. Любая помощь приветствуется.d3 svg не рендеринг на рендеринг исходного компонента. React

import React, { Component, PropTypes } from 'react'; 
import $ from 'jquery'; 
import { connect } from 'react-redux'; 

class BrainComponent extends Component { 
    static propTypes = { 
    showBrainData: PropTypes.bool.isRequired, 
    showThisHitData: PropTypes.object, 
    hit: PropTypes.object 
}; 

constructor(props, context) { 
    super(props, context); 
    this.state = { 
     showBrainData: this.props.showBrainData, 
    }; 
} 

componentWillMount() { 
    console.log(this.props); 
} 

handleBrainVizColor() { 
    console.log(this.props.hit.Hic); 
    let colorString; 
    const hic = this.props.hit.Hic; 
    const redNum = 80 + (Math.round(hic/2)); 
    const greeNum = 180 - (Math.round(hic/2)); 
    colorString = "rgba(" + redNum + "," + greeNum + ", 0, .4)"; 
    return colorString; 
} 

renderBrainViz() { 
    console.log(this.props.hit); 
    this.renderRecangles(); 
} 

componentDidMount() { 
    // this.renderBrainViz.bind(this); 
} 

renderRecangles() { 
    d3.select(".brain-canvas").remove(); 
    const fillColor = this.handleBrainVizColor(); 
    console.log(this.props.showBrainData); 
    if (this.props.showBrainData) { 
    const brainWidth = $(".brain-img").width(); 
    const brainHeight = $(".brain-img").height(); 
    let xLocation; 
    let yLocation; 
    let width = brainWidth/2; 
    let height = brainHeight/2; 
    console.log(this.props.hit.ImpactDirection); 

    switch (this.props.hit.ImpactDirection) { 
     case 'URP': 
      xLocation = brainWidth/2; 
      yLocation = 0; 
     break; 
     case 'LRP': 
      xLocation = 0; 
      yLocation = brainHeight/2; 
      height += 10; 
      break; 
     case 'CR': 
      break; 
     case 'LR': 
      xLocation = 0; 
      yLocation = 0; 
      width = brainWidth; 
      break; 
     case 'UR': 
      xLocation = 0; 
      yLocation = brainWidth/2; 
      width = brainWidth; 
      break; 
     case 'BA': 
      break; 
     case 'LF': 
      xLocation = 0; 
      yLocation = 0; 
      width = brainWidth; 
      break; 
     case 'UF': 
      xLocation = 0; 
      yLocation = 0; 
      width = brainWidth; 
      break; 
     case 'ULP': 
      xLocation = 0; 
      yLocation = 0; 
      break; 
     case 'LLP': 
      xLocation = 0; 
      yLocation = 0; 
      break; 
     } 

    const brainCanvas = d3.select(".brain-one").append("svg") 
       .attr("width", brainWidth) 
       .attr("height", brainHeight) 
       .attr("class", "brain-canvas"); 
    brainCanvas.append("rect") 
      .attr("x", xLocation) 
      .attr("y", yLocation) 
      .attr("width", width) 
      .attr("height", height) 
      .style("fill", fillColor); 
    } 
} 

render() { 
     return (
      <div className="brain-container"> 
       <div className="brain-one"> 
        <img className="brain-img" src="https://s3-us-west-2.amazonaws.com/mvtrak/new-brain.png" /> 
       </div> 
       { this.renderBrainViz() } 
       { !this.props.showBrainData ? <div> 
       <div className="brain-overlay"></div> 
       <div className="select-hit-text">SELECT HIT BELOW</div> 
       </div> : null } 
      </div> 
    ); 
} 
} 

function mapStateToProps(state) { 
    console.log(state); 
    return { 
     hit: state.hitData 
    }; 
} 

export default connect(mapStateToProps)(BrainComponent); 

ответ

2

Это неуместно называть this.renderBrainViz() изнутри render(), так как вы показываете, потому что DOM элементы, созданные внутри render() еще тени DOM элементов в этой точке. Они становятся реальными элементами DOM после завершения render(), и React делает свою вещь для разграничения и актуализации этих элементов DOM тени в реальном DOM. Другими словами, первый раз render() называется, которая, в свою очередь, вызывает this.renderBrainViz(), эту линию:

d3.select(".brain-one").append("svg") 

не имеет .brain-one выбрать еще, потому что он не существует.

Он работает на 2-й вызов render(), потому что в этот момент .brain-one уже существует с первого звонка, но это удачное совпадение. Я все равно считаю это не синхронизированным.

Правильный путь не звонить this.renderRectangles() изнутри render() и вместо того, чтобы назвать его изнутри componentDidUpdate(), а также в componentDidMount(), как ты закомментирована. (Использование .bind() здесь не требуется).

Кроме того, хотя это может быть хорошо, чтобы позвонить d3.select(".brain-one") изнутри renderRectangles(), это было бы проблемой, если существует несколько BrainComponent с, потому что тогда будет кратно .brain-one и d3 выбрал бы первый столкнулся. Лучший способ заключается в использовании РЕАКТ ref функцию, чтобы установить ссылку на .brain-one:

<div className="brain-one" ref="brainOne"> 

Таким образом, вы можете сделать что-то вроде

d3.select(this.refs.brainOne).append("svg") 

Наконец, это, вероятно, не очень хорошая идея, в renderRectangles() , всегда удалять и воссоздавать .brain-canvas. Вместо этого вы никогда не должны удалять его и создавать его только условно, если он не существует. Вы можете проверить, если .brain-canvas существует так:

if(d3.select(this.refs.brainOne).select('.brain-canvas').empty()) { 
    // means it doesn't exist 
} 

Или, вы можете использовать свой род трюк, который будет возвращать .enter() набора размера 1 или 0, в зависимости от того, существует ли она, используя следующее:

d3.select(this.refs.brainOne).selectAll('.brain-canvas') 
    .data([null]) // bind to a data array of 1 element 
.enter() 
    .append('svg') // will only append the svg if it doesn't exist yet 
    .attr('class', 'brain-canvas') 
    .... 
+1

Это удивительно полезно, и все это делает тонны смысла. – hifilorau

Смежные вопросы