代码之家  ›  专栏  ›  技术社区  ›  ttmt

D3-工具提示上的html结构

  •  0
  • ttmt  · 技术社区  · 7 年前

    https://plnkr.co/edit/qDi8bm3xh3hdaV059AXX?p=preview

    它是一个简单的条形图,当鼠标悬停在条形图上时会有一个工具提示。

    在工具提示中,我想显示数据中未用于构建条形图的信息。

    d3.selectAll('.bar').on("mouseover", ()=>{
      d3.select('.chart-tooltip').style("display", null)
    })
    .on("mouseout", ()=>{
      d3.select('.chart-tooltip').style("display", "none")
        .transition()
        .duration(500)
    });
    
    d3.selectAll('.bar').on("mousemove", (d)=>{
    let html = d.day;
    
    d3.select('.chart-tooltip')
    .style("left", d3.event.pageX + 15 + "px")
    .style("top", d3.event.pageY - 25 + "px")
      .html(html)
    });
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   calmar    7 年前

    如果可以将新工具提示数据与条形图匹配<-&燃气轮机;要呈现的工具提示然后可以使用d3选择器的索引来匹配数组中的数据,请参见示例:

    const data_tooltip = [
      {
       text: 'BAR 1',
       html: '<strong>BAR 1</strong>'
     },
     {
       text: 'BAR 2',
       html: '<strong>BAR 2</strong>'
     }
    ];
    
    
    d3.selectAll('.bar').on("mousemove", (d, index)=>{ // index iterator of your bar event
    
        d3.select('.chart-tooltip')
        .style("left", d3.event.pageX + 15 + "px")
        .style("top", d3.event.pageY - 25 + "px")
          .html(data_tooltip[index].html)
      });
    

    const w = 400;
    const h = 300;
    
    const margin = {
      top: 20,
      bottom: 60,
      left: 40,
      right: 20
    }
    
    const width = w - margin.left - margin.right
    const height = h - margin.top - margin.bottom
    
    const data = [
      {
       phase: 'One',
       start: 118,
       finish: 102,
       day: 'Monday',
       time: 'Morning'
     },
     {
       phase: 'Two',
       start: 100,
       finish: 112,
       day: 'Tuesday',
       time: 'Afternoon'
     }
    ];
    
    
    const data_tooltip = [
      {
       text: 'BAR 1',
       html: '<strong>BAR 1</strong>'
     },
     {
       text: 'BAR 2',
       html: '<strong>BAR 2</strong>'
     }
    ];
    
    const x = d3.scaleBand()
      .range([0, width])
      .padding(.33)
    
    const y = d3.scaleLinear()  
      .rangeRound([height, 0]);
    
    const svg = d3.select("body").append("svg")
      .attr("id", "svg")
      .attr("width", w)
      .attr("height", h);
    
    const chart = svg.append('g')
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
      .attr("preserveAspectRatio", "xMinYMin meet");  
    
    const tooltip = d3.select('body').append("div")
    	.classed('tooltip chart-tooltip', true)
    	.style('display', 'none');  
    
    const y_axis = d3.axisLeft()
      .scale(y)
      .tickSize(-width)
    
    const x_axis = d3.axisBottom()
      .scale(x)
      .tickSize(-height )
      .tickPadding(10)  
    
    const update = (data) =>{
    
      x.domain(data.map(function(d) { 
        return d.phase
      }));
    
      y.domain(
        d3.extent(
          d3.extent(data, (d) => {
            return d.start+2;    
          })
          .concat(d3.extent(data, (d) => {
            return d.finish-6;    
          })        
        )
      ));
        
      chart.append("g")
        .classed('y-axis', true)
        .call(y_axis)
      
      chart.append("g")
        .call(x_axis)
        .classed('x-axis', true)
        .attr("transform", "translate(0," + height + ")")
    
      const bar = chart.selectAll(".bar")
        .data(data)
    
        bar.enter()
        .append("rect")
        .attr('class', 'bar')
        .attr('data-arrow', (d, i) => {
              return d.start > d.finish ? 'down' : 'up'
            })
        .attr("x", (d, i) => {
          return x(d.phase)
        })
        .attr("width", (d, i) => {
          return x.bandwidth()
        })
        .attr("y", (d, i) => {
          if(d.start < d.finish){
            return y(d.finish);
          }else{
            return y(d.start);
          }
        })
        .attr("height", (d, i) => {
          if(d.start < d.finish){
            return y(d.start) - y(d.finish);
          }else{
            return y(d.finish) - y(d.start);
          }
        });
        
        d3.selectAll('.bar').on("mouseover", ()=>{
              d3.select('.chart-tooltip').style("display", null)
            })
            .on("mouseout", ()=>{
              d3.select('.chart-tooltip').style("display", "none")
                .transition()
                .duration(500)
            });
    
          d3.selectAll('.bar').on("mousemove", (d, i)=>{
            
            d3.select('.chart-tooltip')
            .style("left", d3.event.pageX + 15 + "px")
            .style("top", d3.event.pageY - 25 + "px")
              .html(data_tooltip[i].html)
          });
    
          d3.selectAll('g.tick')
            .filter((d) => d==100)
            .attr('class', 'grid-100')
    
    }
      
    update(data)
    body{
      background:#f5f6f7;
    }
    
    h1, h2 {
      font-family: Lato;
    }
    
    #svg{
      background-color: white;
    }
    
    .bar{
      shape-rendering: crispEdges;
      fill: mediumvioletred;
    }
    
    .bar-label{
      fill: white;
    }
    
    .bar-label{
      text-anchor: end;
    }
    
    .grid line{
      stroke: #bbb;
    }
    
    .grid .tick:nth-child(7) line{
      stroke-width: 3;
      stroke: #999;
    }
    
    .divide{
      fill: lightgrey;
    }
    
    .bar-1{
      fill: red;
      
    }
    	
    .chart-tooltip{
      background: lightgrey;
      border-radius: 4px;
      display: inline-block;
      font-family: sans-serif;
      font-size: 12px;
      padding: 10px;
      position: absolute;
      width: auto;
    }
    <script src="https://d3js.org/d3.v5.min.js"></script>
    <div id="app"></div>