根据悬停的对象更改D3工具提示背景颜色

时间:2018-05-07 01:44:26

标签: javascript reactjs d3.js

我正在尝试使用d3-tip库创建D3工具提示,该工具提示会根据悬停在其上的元素的背景颜色更改颜色。以下是我到目前为止的情况:

class App extends React.Component {
  constructor(props) { 
    super(props);
    this.state = { 
      chartType: 'shade'
    }
  }
  
  
  drawLegend(hexBorderColor, fontColor) {
    
    var effLegend = d3.select('g.legend')
    var heatScale = d3.scaleQuantize().domain([0, 1]).range(['#1147FF', '#86D8FF', '#FFEF67', '#FF7D11', '#F30000'])

    var hexbin = d3.hexbin()
      .radius(1.5)
      .x(d => d.key[0]) 
      .y(d => d.key[1]); 

    const legendHoverText = ['Bot 20%', '20% - 40%', '40% - 60%', '60% - 80%', 'Top 20%'];
    var tip = d3.tip()
      .attr('class', 'd3-tip')
      .offset([-1, 0])
      .html((d,i) => `<p>${legendHoverText[i]}</p>`)
    effLegend.call(tip)
    
 
    // draw the 5 colorful hexagons (add tip.show and .hide here)
    effLegend.selectAll('path')
      .data(heatScale.range())
      .enter().append('path')
        .attr("transform", (d,i) => `translate(${10+(1+i*2)},10)`)
        .on('mouseover', tip.show)
        .on('mouseout', tip.hide)
        .attr('d', hexbin.hexagon(0))
          .transition().duration(1000)
          .attr('d', hexbin.hexagon(1.1))
          .attr('stroke', hexBorderColor)
          .attr('stroke-width', 0.175)
          .style('fill', d => d)
    // =====
  }
  
  componentDidMount() {
  
    const chart = d3.select('.chart')
      .attr('width', 325)
      .attr('height', 300)
      .attr("viewBox", "0, 0, " + 30 + ", " + 30 + "")

    this.drawLegend('#AAA', '#EEE')    
  }
  
  render() {
    console.log(this.state.chartType);
    return(
      <div className='container'>
        <svg className='chart'>
					<g className="legend"></g>
        </svg>
      </div>
    );
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);
/* D3 ToolTip */
/* ========== */
.d3-tip {
  line-height: .5;
  font-weight: bold;
  padding: 0px 8px;
/*   background: rgba(125, 125, 25, 0.8); */
  color: #444;
  border-radius: 10px;
  border: 2px solid #444;
}

/* Creates a small triangle extender for the tooltip */
.d3-tip:after {
  box-sizing: border-box;
  display: inline;
  font-size: 10px;
  width: 100%;
  line-height: 1;
  color: blue;
  content: "\25BC";
  position: absolute;
  text-align: center;
}

/* Style northward tooltips differently */
.d3-tip.n:after {
  margin: -1px 0 0 0;
  top: 100%;
  left: 0;
}
/* ===== */
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.development.js">
</script>
<script src="https://d3js.org/d3-hexbin.v0.2.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-tip/0.8.0-alpha.1/d3-tip.js"></script>

<div id='root'>
  Work for gods sake!
</div>

输出为5个六边形,其中5种颜色位于heatScale()范围内。我希望工具提示的背景颜色(当前全白色)和后来的字体颜色(当前全黑)改变条件是正在盘旋的六边形的背景颜色。现在,我只是喜欢工具提示背景颜色与正在盘旋的六边形颜色相同。但是,我正在努力做到这一点,任何帮助表示赞赏!

1 个答案:

答案 0 :(得分:2)

最简单的解决方案是选择d3.tip div并将背景颜色设置为绑定基准:

d3.select(".d3-tip").style("background-color", d);

以下是更新后的代码:

&#13;
&#13;
class App extends React.Component {
  constructor(props) { 
    super(props);
    this.state = { 
      chartType: 'shade'
    }
  }
  
  
  drawLegend(hexBorderColor, fontColor) {
    
    var effLegend = d3.select('g.legend')
    var heatScale = d3.scaleQuantize().domain([0, 1]).range(['#1147FF', '#86D8FF', '#FFEF67', '#FF7D11', '#F30000'])

    var hexbin = d3.hexbin()
      .radius(1.5)
      .x(d => d.key[0]) 
      .y(d => d.key[1]); 

    const legendHoverText = ['Bot 20%', '20% - 40%', '40% - 60%', '60% - 80%', 'Top 20%'];
    var tip = d3.tip()
      .attr('class', 'd3-tip')
      .offset([-1, 0])
      .html((d,i) => {
      d3.select(".d3-tip").style("background-color", d);
      return `<p>${legendHoverText[i]}</p>`})
    effLegend.call(tip)
    
 
    // draw the 5 colorful hexagons (add tip.show and .hide here)
    effLegend.selectAll('path')
      .data(heatScale.range())
      .enter().append('path')
        .attr("transform", (d,i) => `translate(${10+(1+i*2)},10)`)
        .on('mouseover', tip.show)
        .on('mouseout', tip.hide)
        .attr('d', hexbin.hexagon(0))
          .transition().duration(1000)
          .attr('d', hexbin.hexagon(1.1))
          .attr('stroke', hexBorderColor)
          .attr('stroke-width', 0.175)
          .style('fill', d => d)
    // =====
  }
  
  componentDidMount() {
  
    const chart = d3.select('.chart')
      .attr('width', 325)
      .attr('height', 300)
      .attr("viewBox", "0, 0, " + 30 + ", " + 30 + "")

    this.drawLegend('#AAA', '#EEE')    
  }
  
  render() {
    console.log(this.state.chartType);
    return(
      <div className='container'>
        <svg className='chart'>
					<g className="legend"></g>
        </svg>
      </div>
    );
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);
&#13;
/* D3 ToolTip */
/* ========== */
.d3-tip {
  line-height: .5;
  font-weight: bold;
  padding: 0px 8px;
/*   background: rgba(125, 125, 25, 0.8); */
  color: #444;
  border-radius: 10px;
  border: 2px solid #444;
}

/* Creates a small triangle extender for the tooltip */
.d3-tip:after {
  box-sizing: border-box;
  display: inline;
  font-size: 10px;
  width: 100%;
  line-height: 1;
  color: blue;
  content: "\25BC";
  position: absolute;
  text-align: center;
}

/* Style northward tooltips differently */
.d3-tip.n:after {
  margin: -1px 0 0 0;
  top: 100%;
  left: 0;
}
/* ===== */
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.development.js">
</script>
<script src="https://d3js.org/d3-hexbin.v0.2.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-tip/0.8.0-alpha.1/d3-tip.js"></script>

<div id='root'>
  Work for gods sake!
</div>
&#13;
&#13;
&#13;

PS:不要使用d3.tip作为工具提示,请自行创建。这样你就可以按照自己的方式自定义它们。