2015-04-18 5 views
0

У меня есть следующий скрипт d3.js для создания гистограммы, которая отлично работает. Я добавил функциональность, чтобы показать подсказку (не уверен, добавила ли я ее в нужное место или нет), которая работает нормально, но она создала проблему с существующим mouseout.d3.js Диаграмма столбика диаграммы с подсказкой

Вопрос: Проблема в том, что следующий код больше не работает. Когда мышь над ним не превращается в серый.

   .on('mouseout', function (d) { 
       d3.select(this) 
       .attr('fill', 'blue'); 

Однако, если я прокомментирую следующие строки, как показано выше, мы работаем идеально.

 .on('mouseover', tip.show)     
     .on('mouseout', tip.hide) 

Complete Script вар jsonData = @ Html.Raw (Json.Encode (модель)); data = jsonData; InitChart(); функция InitChart() {

 var barData = data; 

     var vis = d3.select('#SummaryChart'), 
      WIDTH = 500, 
      HEIGHT = 375, 
      MARGINS = { 
       top: 20, 
       right: 20, 
       bottom: 20, 
       left: 150 
      }, 
      xRange = d3.scale.ordinal().rangeRoundBands([MARGINS.left, WIDTH - MARGINS.right], 0.1).domain(barData.map(function (d) { 
       return d.Date; 
      })), 


      yRange = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([0, 
      d3.max(barData, function (d) { 
       return d.Duration; 
      }) 
      ]), 

      xAxis = d3.svg.axis() 
      .scale(xRange) 
      .tickSize(0) 
      .tickSubdivide(true), 

      yAxis = d3.svg.axis() 
      .scale(yRange) 
      .tickSize(0) 
      .orient("left") 
      .tickSubdivide(true); 

     var tip = d3.tip() 
    .attr('class', 'd3-tip') 
    .offset([-10, 0]) 
    .html(function(d) { 
     return "<strong>Duration:</strong> <span style='color:red'>" + d.Duration + "</span>"; 
    }) 

     vis.call(tip); 

     vis.append('svg:g') 
      .attr('class', 'x axis') 
      .attr('transform', 'translate(0,' + (HEIGHT - MARGINS.bottom) + ')') 
      .call(xAxis); 

     vis.append('svg:g') 
      .attr('class', 'y axis') 
      .attr('transform', 'translate(' + (MARGINS.left) + ',0)') 
      .call(yAxis); 

     vis.append("text") 
     .attr("class", "x label") 
     .attr("text-anchor", "end") 
     .attr("font-size", "20px") 
     .attr("x", WIDTH) 
     .attr("y", HEIGHT + 20) 
     .text("Time"); 

     vis.append("text") 
     .attr("class", "y label") 
     .attr("text-anchor", "end") 
     .attr("font-size", "20px") 
     .attr("y", 100) 
     .attr("x",-100) 
     .attr("dy", ".75em") 
     .attr("transform", "rotate(-90)") 
     .text("Hours:"); 

     vis.selectAll('rect') 
      .data(barData) 
      .enter() 
      .append('rect') 
      .attr('x', function (d) { 
       return xRange(d.Date); 
      }) 
      .attr('y', function (d) { 
       return yRange(d.Duration); 
      }) 
      .attr('width', xRange.rangeBand()) 
      .attr('height', function (d) { 
       return ((HEIGHT - MARGINS.bottom) - yRange(d.Duration)); 
      }) 

      .attr('fill', 'blue') 
      .on('mouseover', function (d) { 
       d3.select(this) 
       .attr('fill', 'grey'); 
      }) 

      .on('mouseout', function (d) { 
       d3.select(this) 
       .attr('fill', 'blue'); 
      }) 
     .on('mouseover', tip.show)     
     .on('mouseout', tip.hide) 
    } 
</script> 

Может кто-то указать на то, что не так и как я кулачок сделать это работает как с подсказкой и мыши превращаются в сером работать как вместе?

+1

Это трудно понять, что ваш на поводу, но попробовать '.На ('MouseOut' , function (d) {d3.select (this) .attr ('fill', 'blue'), tip.hide(); 'например. –

ответ

1

В отличие от jQuery, D3 допускает только один обратный вызов для каждого действия. Поэтому, если вы присоедините два обратных вызова .on('mouseout'), будет выполнен только последний. См:

d3.select('div') 
 
    .on('mouseout', function() {console.log('A')}) 
 
    .on('mouseout', function() {console.log('B')})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
 
<div style='width:250px;height:250px;background:red'></div>

У вас есть два пути вокруг этого. Один из них, как это было предложено в комментариях, было бы назвать как attr и tooltip в обратном вызове, как это:

.on('mouseout', function (d) { 
    d3.select(this).attr('fill', 'blue'); 
    tip.hide(); 
} 

Второй будет использовать точку . обозначение, как описано в API, второй пункт

Если прослушиватель событий уже зарегистрирован для одного и того же типа в выбранном элементе, существующий прослушиватель удаляется до добавления нового слушателя. Чтобы зарегистрировать несколько прослушивателей для одного и того же типа события, за типом может следовать необязательное пространство имен, такое как «click.foo» и «click.bar».

Так что в вашем случае

.on('mouseout.attr', function (d) { 
    d3.select(this) 
    .attr('fill', 'blue'); 
}) 
.on('mouseout.tip', tip.hide) 

Рабочий пример:

d3.select('div') 
 
    .on('mouseout.logA', function() {console.log('A')}) 
 
    .on('mouseout.logB', function() {console.log('B')})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
 
<div style='width:250px;height:250px;background:red'></div>

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