如何在D3中使用资源对象(通过promises)?

时间:2023-01-24 10:56:23

UPDATE: I realized that trying to perform the database lookups this late in the game was poor form -- I updated my code so that my raw data coming into D3 already included the information I would need to create my graph and everything works as expected.

更新:我意识到在游戏后期尝试执行数据库查找是不好的形式 - 我更新了我的代码,以便我的原始数据进入D3已经包含了创建我的图形所需的信息,一切都按预期工作。

I'm trying to build a force-directed graph that performs a database lookup on node elements to get additional information regarding the node for further customization in the graph.

我正在尝试构建一个强制导向图,它对节点元素执行数据库查找,以获取有关节点的其他信息,以便在图中进一步自定义。

In the below example, I am trying to use FontAwesome glyphs to create 'icons' for my nodes. Right now, in my getIcon() function, I correctly draw the node icon/glyph IF and ONLY IF I return the unicode value right away. Once I put a promise in and wait to return the value, things break. D3 is constructing and rendering the graph before the promise has a chance to return. How can I make .text(getIcon) wait to append text (a glyph icon) to a node until after we've resolved my promise?

在下面的示例中,我尝试使用FontAwesome字形为我的节点创建“图标”。现在,在我的getIcon()函数中,我正确地绘制节点图标/字形IF,并且只有我立即返回unicode值。一旦我提出承诺并等待返回价值,事情就会破裂。 D3在承诺有机会返回之前构建并呈现图形。我怎样才能使.text(getIcon)等待将文本(字形图标)附加到节点,直到我们解决了我的承诺?

node.append('text')
  .attr('text-anchor', 'middle')
  .attr('dominant-baseline', 'central')
  .style('font-family','FontAwesome')
  .style('font-size','24px')
  .text(getIcon)
  .style('fill', function (d) {
    return color(d.group);
  });

getIcon() is defined as follows:

getIcon()定义如下:

function getIcon(d) {
  myPromise.then(function(data) {
    if(data.value) {
      return '\uf108';
    } else { return '\uf233'; }
  });
}

2 个解决方案

#1


1  

I'm not sure I understand your promise because your not using d and you haven't shared the declaration of your promise, but maybe this is the type of structure you need...

我不确定我理解你的承诺,因为你没有使用d并且你没有分享你的承诺声明,但也许这是你需要的结构类型......

node.append('text')
    .attr('text-anchor', 'middle')
    .attr('dominant-baseline', 'central')
    .style('font-family','FontAwesome')
    .style('font-size','24px')
    .each(getIcon)
    .style('fill', function (d) {
        return color(d.group);
    });
function getIcon(d) {
    var node = this;
    var myPromise = new Promise(function(resolve, reject){
        d3.json("data.json", function(error, glyphs){
            if(error || glyphs[d.char] === "undefined") reject('\uf233'); else resolve(glyphs[d.glyph]);
        })
    });
    myPromise.then(function(glyph) {
        d3.select(node).text(glyph)
    }).catch(function(defaultGlyph){
        d3.select(node).text(defaultGlyph)
    })
}

#2


0  

While i have never worked on D3, but i think you need to call getIcon first and then do the node.append logic in the promise callback. Something like

虽然我从未参与D3,但我认为你需要先调用getIcon,然后在promise回调中执行node.append逻辑。就像是

getIcon().then(function(data) {
   node.append('text')
  .attr('text-anchor', 'middle')
  .attr('dominant-baseline', 'central')
  .style('font-family','FontAwesome')
  .style('font-size','24px')
  .text(data)
  .style('fill', function (d) {
    return color(d.group);
  });
});

But i realize that the d parameter then will be unavailable.

但我意识到d参数将无法使用。

#1


1  

I'm not sure I understand your promise because your not using d and you haven't shared the declaration of your promise, but maybe this is the type of structure you need...

我不确定我理解你的承诺,因为你没有使用d并且你没有分享你的承诺声明,但也许这是你需要的结构类型......

node.append('text')
    .attr('text-anchor', 'middle')
    .attr('dominant-baseline', 'central')
    .style('font-family','FontAwesome')
    .style('font-size','24px')
    .each(getIcon)
    .style('fill', function (d) {
        return color(d.group);
    });
function getIcon(d) {
    var node = this;
    var myPromise = new Promise(function(resolve, reject){
        d3.json("data.json", function(error, glyphs){
            if(error || glyphs[d.char] === "undefined") reject('\uf233'); else resolve(glyphs[d.glyph]);
        })
    });
    myPromise.then(function(glyph) {
        d3.select(node).text(glyph)
    }).catch(function(defaultGlyph){
        d3.select(node).text(defaultGlyph)
    })
}

#2


0  

While i have never worked on D3, but i think you need to call getIcon first and then do the node.append logic in the promise callback. Something like

虽然我从未参与D3,但我认为你需要先调用getIcon,然后在promise回调中执行node.append逻辑。就像是

getIcon().then(function(data) {
   node.append('text')
  .attr('text-anchor', 'middle')
  .attr('dominant-baseline', 'central')
  .style('font-family','FontAwesome')
  .style('font-size','24px')
  .text(data)
  .style('fill', function (d) {
    return color(d.group);
  });
});

But i realize that the d parameter then will be unavailable.

但我意识到d参数将无法使用。