Select and Style Objects via Data id

I am trying to have a mouse hover event where the circle radius gets bigger, and the corresponding data label increases font size. The data labels are on the circle, in the graph itself. So my idea was to have two functions, one to style the circles nice and smooth with a transition, and use a separate function with tweening to style the text. I want to call both functions at the same time and have them only style objects with data binding matching its 'id'. Id is just an index that I parsed from the .tsv. The idea is both the text and the circle have the same 'id'.

!boring circle svg code above
.on('mouseenter', function(d) {circle_event(this); text_event(this);})

function circle_event(id) {
    if (d3.select(this).data==id) {
        d3.select(this)
        .transition()
        .attr('r', radius*1.5)
        .duration(500);
    }
}

function text_event(id) {
    if (d3.select(this).data==id) {
        d3.select(this)
        .transition()
        .styleTween('font', function() {return d3.interpolate('12px Calibri', '20px Calibri' )
        .duration(500);
    }
}

For some reason when I hover over the circles, nothing happens. Dev tools didn't have any errors. If I had to guess, I have misunderstood how to use d3's select functions.

Thank you

EDIT

Please note I need to call the circle and text style functions simultaneously I will accept the answer that shows how to style the circle and its corresponding data_label text JUST by mousing over the CIRCLE . It seems this cannot be used as a circle and a text object concurrently. Other solutions aside from this -based are welcome.


It looks like you edited your question which changes things considerably. Here is one approach that could work or be modified to make it work:

// Assumes circle & text objects have the same .x, .y and .id data bound to them and that 
// when created, they each have classes "circle-class" and "text-class" respectively

!boring circle svg code above
.on('mouseenter', function(d) {circle_event(d.x, d.y, d.id); text_event(d.x, d.y, d.id);})

function circle_event(x, y, id) {
    d3.selectAll(".circle-class")
    .filter(function (d) {
      return (d.x === x) && (d.y == y) && (d.id == id);
    })
      .transition()
      .attr('r', radius * 1.5)
      .duration(500);
}

function text_event(x, y, id) {
  d3.selectAll(".text-class")
    .filter(function (d) {
      return (d.x === x) && (d.y == y) && (d.id == id);
    })
      .transition()
      .styleTween('font', function() {return d3.interpolate('12px Calibri', '20px Calibri' )
      .duration(500);
}

Alternatively, if you structure the creation of the circle and text DOM elements such that they have a sibling relationship, you could get a reference to the text selection using d3.select(this.previousElementSibling) where this is the circle node that is being moused over (See here - How to access "previous sibling" of `this` when iterating over a selection?). Such an approach could use the code in my previous reply above.


Your primary issue is that this is not what you want it to be in your nested function. It is no longer bound to your circle DOM node that was being hovered over but instead is referencing the global window .

More info on the scoping of this in javascript can be found here:

Javascript "this" pointer within nested function

http://javascriptissexy.com/understand-javascripts-this-with-clarity-and-master-it/

Try changing to this:

!boring circle svg code above
.on('mouseenter', function(d) {circle_event(this, d.id)})

function circle_event(selection, id) {
    if (d3.select(selection).data==id) {
        d3.select(selection)
        .transition()
        .attr('r', radius*1.5)
        .duration(500);
    }
}

function text_event(selection, id) {
    if (d3.select(selection).data==id) {
        d3.select(selection)
        .transition()
        .styleTween('font', function() {return d3.interpolate('12px Calibri', '20px Calibri' )
        .duration(500);
    }
}

You should pass this in the function :

.on('mouseenter', function(d) {circle_event(this)})

function circle_event(item) {
        d3.select(item)
        .transition()
        .attr('r', radius*1.5)
        .duration(500);
}

function text_event(item) {
        d3.select(item)
        .transition()
        .styleTween('font', function() {return d3.interpolate('12px Calibri', '20px Calibri' )
        .duration(500);
}

You dont need d.id as this is already the selected circle

链接地址: http://www.djcxy.com/p/94912.html

上一篇: 如何引用外部成员

下一篇: 通过数据ID选择和样式对象