通过数据ID选择和设置对象

时间:2017-01-10 08:21:02

标签: javascript d3.js

我正在尝试鼠标悬停事件,其中圆半径变大,相应的数据标签会增加字体大小。数据标签位于图表本身的圆圈上。所以我的想法是有两个函数,一个用圆形设置漂亮和平滑的过渡,并使用一个单独的补间函数来设置文本的样式。 我想同时调用这两个函数,只让它们的样式对象的数据绑定与其ID匹配。 Id只是我从.tsv解析的索引。这个想法是文本和圈子都有相同的' 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);
    }
}

由于某种原因,当我将鼠标悬停在圆圈上时,没有任何反应。开发工具没有任何错误。如果我不得不猜测,我误解了如何使用d3的选择功能。

谢谢

修改

请注意我需要同时调用圆形和文本样式函数我将接受答案,该答案显示如何设置圆形样式及其相应的data_label文本只需将鼠标悬停在CIRCLE上。似乎this不能同时用作圆圈和文本对象。除this之外的其他解决方案是受欢迎的。

3 个答案:

答案 0 :(得分:2)

看起来您编辑的问题会大大改变一切。这是一种可以工作或被修改以使其工作的方法:

// 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);
}

或者,如果您构建圆形和文本DOM元素以使它们具有兄弟关系,则可以使用d3.select(this.previousElementSibling)来获取对文本选择的引用,其中this是圆形节点被淹没的人(见这里 - How to access "previous sibling" of `this` when iterating over a selection?)。这种方法可以使用上一个回复中的代码。

答案 1 :(得分:0)

您的主要问题是this不是您想要的嵌套函数。它不再绑定到正在悬停的圆圈DOM节点,而是引用全局window

有关javascript中this范围的更多信息,请访问:

Javascript "this" pointer within nested function

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

尝试更改为:

!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);
    }
}

答案 2 :(得分:0)

您应该在函数中传递this

.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);
}

您不需要d.id因为this已经是选定的圈子