用D3.js

时间:2017-04-19 09:44:39

标签: javascript d3.js svg

是否可以在div中包含5个svg,并使用javascript(而不是jquery)在另一个div中每五个新创建的div包装?

这是我的代码

d3.csv("example.svg", function(data) {

data.forEach(function(d){

var svgContainer = d3.select(".parentclass").append("svg")
                                    .attr("width",55)
                                    .attr("height",35);

var rectangle = svgContainer.append("rect")
                     .attr("x",0)
                     .attr("y",0)
                     .attr("width",55)
                     .attr("height",35)
                     .attr("fill", "rgb(" + d.r + "," + d.g + "," + d.b + ")");

 })

 });

我想要的输出是

<div class="column1">
<div class="line">
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg></div>
<div class="line">
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg></div>   
 <div class="line">
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg></div>    
 <div class="line">
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg></div>    
 <div class="line">
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg></div>    
</div>

<div class="column2">
<div class="line">
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg></div>
<div class="line">
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg></div>   
 <div class="line">
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg></div>    
 <div class="line">
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg></div>    
 <div class="line">
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg>
 <svg width="55" height="35">....</svg></div>    
</div>

可能的解决方案1:

我在var svgContainer之前添加了以下代码 但所有的svg都是在第一个孩子身上添加的。

if ((i % 5 == 0) || (i == 0)) {

  var body = d3.select('.parentclass')
    .append('div')
    .attr('class','childclass');
    } 

    i = i + 1;

可能的解决方案2:

var svgContainer = d3.select(".milk").filter(function(i){ return ((i % 5 === 0) || (i === 1)); }).append("div")
                                            .append("svg")
                                            .attr("width",55)
                                            .attr("height",35);


var test = function (i) {
  i = i + 1;
  return i;

}

关于如何开展工作的任何想法?

1 个答案:

答案 0 :(得分:1)

以下是如何执行此操作的示例 - 请记住var data = [1,2,3,4,5,6,7]; var columns = 2; d3.select('.container').selectAll('.column').data(d3.pairs(d3.range(0, data.length, Math.floor(data.length / columns)))) .enter().append('div').attr('class', 'column') .selectAll('.item').data(d => data.slice(d[0], d[1])) .enter() .append('div') .attr('class', 'item') .append('svg') .append('text').text(d => d).attr('y', 20)还可以接收可以返回所需结构的函数。

编辑:更新以显示如何依次收听项目

.container {
  background: lightblue;
  padding: 5px;
}

.item {
  background: lightcyan;
  padding: 5px;
  margin: 5px;
}

.column {
  background: lightgreen;
  padding: 5px;
  margin: 10px;
}

text { 
  fill: black;
  stroke: black;
  font-size: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div class="container"></div>
const { Component } = React
const { createStore, applyMiddleware, combineReducers, compose } = Redux
const { Provider, connect } = ReactRedux
const { Router, Route, browserHistory, IndexRoute, Link } = ReactRouter
const { Field, reduxForm } = ReduxForm
const formReducer = ReduxForm.reducer

class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      focused: false,
      avoidBlur: false
    }
    this.handleClick = this.handleClick.bind(this)
    this.handleBlur = this.handleBlur.bind(this)
    this.handleFocus = this.handleFocus.bind(this)
  }

  handleClick() {
    if (this.state.focused) {
      this.setState({ focused: false, avoidBlur: true })
      console.log('close and submit')
    } else {
      this.setState({ focused: true, avoidBlur: true })
      //this.textInput.focus()
      setTimeout(() => { this.textInput.focus() }, 0) // I don't understand why this works
    }
  }

  handleBlur() {
    if (!this.state.avoidBlur) {
      this.setState({ focused: false })
      console.log('onblur')
    }
  }

  handleFocus() {
    this.setState({ focused: true, avoidBlur: false })
    console.log('onfocus')
  }

  render() {
    console.log('render')
    const inputClass = (this.state.focused) ? 'input__opened' : 'input__closed'
    return (
      <div className='container'>
        <input className={inputClass}
          type='text'
          ref={(input) => { this.textInput = input; }}
          onFocus={this.handleFocus}
          onBlur={this.handleBlur}
          value={inputClass}
        />
        <div className='button' onMouseDown={this.handleClick}>
          Click Me!
        </div>
      </div>
    )
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
)