Dinamicamente retornar valor de escala, quando pairar sobre dica de ferramenta hyperlink

votos
0

Eu estou traçando um gráfico de barras agrupadas com d3.js (v4). Neste, eu fiz dica de ferramenta como hyperlink.

Minha exigência: Quando eu pairar sobre a ponta da ferramenta, no código, ele deve retornar o respectivo valor de escala do eixo-x grupo bar usando o que eu vou definir url ponta da ferramenta para arquivos de html únicas.

Eu sou capaz de conseguir Xtick valor usando dados 1 .Week Da mesma forma, no entanto, não está servindo ao propósito como eu preciso este valor a ser mapeada em tempo de execução com dica de ferramenta comportamento pairando.

arquivo CSV

Week,Total,Pass,Fail
w-32,4,4,0
w-33,2,1,1
w-34,2,0,2
w-37,2,1,1
w-38,1,1,0
w-39,1,1,0

Código de trabalho

<!DOCTYPE html>
<html>
<meta http-equiv=content-type content=text/html; charset=UTF8>
<style>

@-webkit-keyframes bounceIn {
    0% {
      opacity: 0;
      -webkit-transform: scale(.3);
    }
    50% {
      opacity: 1;
      -webkit-transform: scale(1.05);
    }
    70% {
      -webkit-transform: scale(.9);
    }
    100% {
      -webkit-transform: scale(1);
    }
  }
  @keyframes bounceIn {
    0% {
      opacity: 0;
      transform: scale(.3);
    }
    50% {
      opacity: 1;
      transform: scale(1.05);
    }
    70% {
      transform: scale(.9);
    }
    100% {
      transform: scale(1);
    }
  }

  .d3-tip.animate {
    animation: bounceIn 0.2s ease-out;
    -webkit-animation: bounceIn 0.2s ease-out;
  }
  .d3-tip span {
    color: #ff00c7;
  }

.d3-tip {
  line-height: 1;
  font-weight: bold;
  padding: 8px;
  background: #FFE4C4;
  color: white;
  border-radius: 2px;
  text-decoration: none;
}

/* 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: #FFE4C4;
  content: \25BC;
  position: absolute;
  text-align: center;
}

/* Style northward tooltips differently */
.d3-tip.n:after {
  margin: -1px 0 0 0;
  top: 100%;
  left: 0;
}

<!-- For setting overall graph dimensions:Start -->
</style>
<body>
<svg width=600 height=400></svg>
<script src=https://d3js.org/d3.v4.min.js></script>
<script src=https://cdnjs.cloudflare.com/ajax/libs/d3-tip/0.7.1/d3-tip.min.js></script>
<script>
labels = [Total, Pass, Fail];
<!-- For setting overall graph dimensions:End -->

<!-- For setting graph margins:Start -->
var svg = d3.select(svg),
    margin = {top: 33, right: 10,bottom: 150, left: 24},
    width = +svg.attr(width) - margin.left - margin.right,
    height = +svg.attr(height) - margin.top - margin.bottom,
    g = svg.append(g).attr(transform, translate( + margin.left + , + margin.top + ));
var colour = [#a9a9a9, #66cc00, #ff3333]

<!-- For gaping between bar groups-->
var x0 = d3.scaleBand()
    .rangeRound([0, width])
    .paddingInner(0.2);

<!-- For gaping between bars in groups-->
var x1 = d3.scaleBand()
    .padding(0.01);

var y = d3.scaleLinear()
    .rangeRound([height, 0]);

var z = d3.scaleOrdinal()
    .range([#a9a9a9, #66cc00, #ff3333]);

var timeout;

<!--Data read from csv and plot grouped bar chart-->
d3.csv(weekwise.csv, function(d, i, columns) {
  for (var i = 1, n = columns.length; i < n; ++i) d[columns[i]] = +d[columns[i]];
  return d;
}, function(error, data) {
   if (error) throw error;
        <!--console.log(data.length);-->
       var tool_tip = d3.tip()
       .attr('class', 'd3-tip')
      .offset([-8, 0])
      .html(function(d) {
           #Help needed here
           #This is where tool tip is getting set dynamically. However, all the bar are poiting to same html file.
           #I'll let each bar point to unique html file dynamically, if get the xtick value
           return '<a href= '+wk+31+-+d.key+-+d.value+.html +' target=_parent>' + d.value + </a>;
        }
    })

  svg.call(tool_tip)
  var keys = data.columns.slice(1);
  x0.domain(data.map(function(d) { return d.Week; }));
  <!--console.log(x0(d.Week));-->
  x1.domain(keys).rangeRound([0, x0.bandwidth()]);
  y.domain([0, d3.max(data, function(d) { return d3.max(keys, function(key) { return d[key]; }); })]).nice();
  g.append(g)
    .selectAll(g)
    .data(data)
    .enter().append(g)
    .attr(transform, function(d) { return translate( + x0(d.Week) + ,0); })
    .selectAll(rect)
    .data(function(d) { return keys.map(function(key) { return {key: key, value: d[key]}; }); })
    .enter().append(rect)
      .attr(x, function(d) { return x1(d.key); })
      .attr(y, function(d) { return y(d.value); })
      .attr(width, x1.bandwidth())
      .attr(height, function(d) { return height - y(d.value); })
      .attr(fill, function(d) { return z(d.key); })
      <!--// Tooltip stuff after this-->
        .on('mouseover', function(d) {
          <!--console.log(d);-->
          var context = this;
          var args = [].slice.call(arguments);
          args.push(this);
          clearTimeout(timeout);
          timeout = setTimeout(function() {
            tool_tip.show.apply(context, args);
            }, 800);
        })
       <!--.on('mouseout', tool_tip.hide)-->
       .on('mouseout', function(d) {
          var context = this;
          var args = [].slice.call(arguments);
          args.push(this);
          clearTimeout(timeout);
          timeout = setTimeout(function() {
            tool_tip.hide.apply(context, args);
          }, 2000);
        })

    g.append(g)
      .attr(class, axis)
      .attr(transform, translate(0, + height + ))
      .call(d3.axisBottom(x0));
    console.log(g);
 <!--Code for adding graph title-->
        g.append(g)
        .attr(class, axis)
        .call(d3.axisLeft(y).ticks(null, s))
    .append(text)
        .attr(x, (width / 2))
        .attr(y, 0 - (margin.top / 1.5))
        .attr(fill, #000)
        .attr(text-anchor, middle)
        .style(font-size, 14px)
        .style(font-weight, bold)
        <!--.style(text-decoration, underline)-->
        .text(Build Statistics-v8.0.18);

<!--Code for defining and appending legend-->

var legend = g.append(g)
            .attr(class, legend)
            .attr(height, 100)
            .attr(width, 100)
        .attr('transform', 'translate(-5,' + (height + 50) + ')')
        .style(font, 12px sans-serif);

    legend.selectAll('rect')
        .data(labels)
      .enter()
      .append(rect)
          .attr(x, function(d, i){
              var xPost = legendXPosition(labels, i, 6);
              return xPost;
          })
      .attr(y, -12)
          .attr(width, 12)
          .attr(height, 12)
          .style(fill, function(d, i) {
              var color = colour[i];
              return color;
          });

    legend.selectAll('text')
      .data(labels)
      .enter()
      .append(text)
          .attr(x, function(d, i){
              var xPost = legendXPositionText(labels, i, 22, 6);
              return xPost;
          })
      .attr(y, -1)
          .text(function(d) {
              return d;
          });


  function legendXPositionText(data, position, textOffset, avgFontWidth){
    return legendXPosition(data, position, avgFontWidth) + textOffset;
  }

  function legendXPosition(data, position, avgFontWidth){
    if(position == 0){
        return 0;
    } else {
        var xPostiion = 0;
        for(i = 0; i < position; i++){
            xPostiion += (data[i].length * avgFontWidth + 40);
        }
        return xPostiion;
    }
  }
});
</script>
</body>
</html>

Por favor, dê uma olhada no gráfico gerado com o código acima.

digite

Publicado 20/09/2018 em 04:25
fonte usuário
Em outras línguas...                            


2 respostas

votos
1

d3-tipnão permite muito de mexer com os dados ou nós, então você está preso com ambos tendo d3-tipretornar os dados a partir do nó que desencadeou (onde você estaria faltando contexto do nó pai) ou o nó pai (onde você seria sem as informações sobre o nó foi pairava sobre). A solução é ou para adicionar mais dados para cada nó (ou seja, incluem a semana nos dados que você ligar a cada nó), ou para puxar dinamicamente nos dados de semana, quando você passa o mouse sobre o nó, assim:

    .on('mouseover', function(d) {
      // if d.parent isn't defined, get the parent node of the current selection
      // and add that data to the current node
      if ( ! d.parent ) {
        d.parent = d3.select( this.parentNode ).datum();
      }
        tool_tip.show(d);
    }

Se você tentar manipular os argumentos para tip.show()de outras formas, ele vai vomitar outros erros como os argumentos são usados internamente pelo d3-tip; eles não são passados diretamente para a tip.html()função que você poderia ter pensado.

Você seria melhor fora incluindo os dados semana em seus dados encadernados de contornar isso, porém:

.data(function(d) {
  return keys.map(function(key) { return {key: key, value: d[key], week: d.Week }; });
})
Respondeu 20/09/2018 em 09:36
fonte usuário

votos
-1

Já considerou adicionando o número da semana aos seus dados encadernados?

.data(d => keys.map(key => ( {key: key, value: d[key], week:d.Week.slice(2)} )) )
Respondeu 20/09/2018 em 09:10
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more