D3 4.0带有定向边和标签的图形

时间:2016-09-11 19:02:27

标签: javascript d3.js graph

我正在尝试使用d3(v4.0)创建一个图形,该图形具有针对节点的方向边和标签,如下所示:http://jsfiddle.net/chrisJamesC/HgHqy/但是具有较新版本的D3。

这是我到目前为止所做的:https://jsfiddle.net/4nu57pgn/1/但我似乎无法弄清楚如何告诉D3使边缘看起来是直观的(带箭头)或显示节点ID。

smbinning.genCUSTOM = function(df, ivout, chrname = "NewChar") {
    df = cbind(df, tmpname = NA)
    ncol = ncol(df)
    col_id = paste0(ivout, '[[6]]', collapse = NULL) # Original: ivout$col_id
    # Updated 20160130
    b = paste0(ivout, '[[4]]', collapse = NULL) # Original: ivout$bands
    df[, ncol][is.na(df[, col_id])] = 0 # Missing
    df[, ncol][df[, col_id] <= b[2]] = 1 # First valid
    # Loop goes from 2 to length(b)-2 if more than 1 cutpoint
    if (length(b) > 3) {
        for (i in 2:(length(b) - 2)) {
            df[, ncol][df[, col_id] > b[i] & df[, col_id] <= b[i + 1]] = i
        }
    }
    df[, ncol][df[, col_id] > b[length(b) - 1]] = length(b) - 1 # Last
    df[, ncol] = as.factor(df[, ncol]) # Convert to factor for modeling
    blab = c(paste("01 <=", b[2]))
    if (length(b) > 3) {
        for (i in 3:(length(b) - 1)) {
            blab = c(blab, paste(sprintf("%02d", i - 1), "<=", b[i]))
        }
    } else { i = 2 }
    blab = c(blab, paste(sprintf("%02d", i), ">", b[length(b) - 1]))

    # Are there ANY missing values
    # any(is.na(df[,col_id]))

    if (any(is.na(df[, col_id]))) {
        blab = c("00 Miss", blab)
    }
    df[, ncol] = factor(df[, ncol], labels = blab)

    names(df)[names(df) == "tmpname"] = chrname
    return(df)
}

我是D3的新手,非常感谢帮助我指明正确的方向。

1 个答案:

答案 0 :(得分:9)

箭头

要在行尾添加箭头,您需要使用SVG定义标记。只需稍加修改即可使用v4更新d3 v3代码。您提供的示例设置了三个箭头定义(每种类型的关系一个),但要创建一个,您可以使用它:

svg.append("defs").append("marker")
    .attr("id", "arrow")
    .attr("viewBox", "0 -5 10 10")
    .attr("refX", 20)
    .attr("refY", 0)
    .attr("markerWidth", 8)
    .attr("markerHeight", 8)
    .attr("orient", "auto")
  .append("svg:path")
    .attr("d", "M0,-5L10,0L0,5");

markerWidthmarkerHeightrefXrefY的值很重要并且决定了标记的位置 - 遗憾的是我不知道它们如何与viewBox或圆半径,因此通过反复试验选择了这些。

无需将标记捕获为变量,因为它将使用URL说明符引用,如下所示:

  var link = svg.append("g")
      .attr("class", "links")
    .selectAll("line")
      .data(graph.links)
    .enter().append("line")
      .attr("stroke", function(d) { return color(d.type); })
      .attr("marker-end", "url(#arrow)");

标签

同样,对v3代码的轻微修改也会起作用。文本标签需要单独附加到SVG,而不是作为节点的子项,并在ticked函数中独立翻译。

设置标签:

var text = svg.append("g").attr("class", "labels").selectAll("g")
    .data(graph.nodes)
  .enter().append("g");

text.append("text")
    .attr("x", 14)
    .attr("y", ".31em")
    .style("font-family", "sans-serif")
    .style("font-size", "0.7em")
    .text(function(d) { return d.id; });

然后在力模拟滴答时将它们转换到正确的位置:

  function ticked() {
    // ...
    text
        .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
  }

设置标签时,水平偏移量由x的值定义(在这种情况下为14)。

一起

有关完整示例,请参阅this fiddle