d3.js:将样式应用于单个线 [英] d3.js : Applying styles to individual lines

查看:227
本文介绍了d3.js:将样式应用于单个线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试可拖动网络,并希望能为不同链接使用不同的颜色。当我注释掉这些行

Was trying out the draggable network and wanted to be able to use different colours for different links. When I commented out the lines

/*var link = svg.append("g")
    .attr("class", "link") 
    .selectAll("line");*/

并替换为 var link = svg.append(g);

,以便我可以尝试逐个添加链接,if - 条件,我可以应用不同的线条样式到每一行。但是当我试图将一个单一的样式统一应用到所有线条本身时,线条没有出现在屏幕上。 Firebug也没有显示任何错误。

and replaced it with var link = svg.append("g");
so that I could try adding links one by one, with if-else conditions where I could apply a different line style to each line. But when I tried applying just a single style uniformly to all lines itself, the lines didn't show up on the screen. Firebug also didn't show any error.

  link = link.data(graph.links).enter().append("line")
      .attr("x1", function(d) { return d.source.x; })
      .attr("y1", function(d) { return d.source.y; })
      .attr("x2", function(d) { return d.target.x; })
      .attr("y2", function(d) { return d.target.y; })
      .attr("class", "link");



我添加了 .attr(class,link) ; 部分,认为它会将样式应用到线条。但是没有。你能帮助选择性地附加属性的正确方法吗?

I had added the .attr("class", "link"); section, thinking that it'd apply the style to the lines. But it didn't. Could you help with the right way to append attributes selectively?

这是整个代码:

<!DOCTYPE html>
<meta charset="utf-8">

<svg id="mySvg" width="20" height="20">
  <defs id="mdef">
        <pattern id="image" x="0" y="0" height="20" width="20">
          <image x="0" y="0" width="20" height="20" xlink:href="url.png"></image>
        </pattern>
  </defs>
  <defs>
  <pattern id="tile-ww" patternUnits="userSpaceOnUse" width="25" height="25">
  <image xlink:href="url.png" x="15" y="15" width="15" height="15"></image></pattern>
  </defs>
</svg>

<style>

.node {
  stroke: green;
  stroke-width: 1px;
  opacity: 0.8;
  fill: url(#image);  
}

.node .selected {
  stroke: red;
}

.link {
  stroke: orange;
  stroke-width: 3;
  stroke-dasharray: 20,10,5,5,5,10;
  opacity: 0.5;
}

.dotted {border: 1px dotted #ff0000; border-style: none none dotted; color: #fff; background-color: #fff; }

.brush .extent {
  fill-opacity: .1;
  stroke: #fff;
  shape-rendering: crispEdges;
}

</style>
<body>
<script src="d3/d3.v3.js"></script>

<script>

var width = 960, height = 500, shiftKey;

var svg = d3.select("body")
    .attr("tabindex", 1)
    .on("keydown.brush", keydown)
    .on("keyup.brush", keyup)
    .each(function() { this.focus(); })
    .append("svg")
    .attr("width", width)
    .attr("height", height);

/*var link = svg.append("g")
    .attr("class", "link") 
    .selectAll("line");*/
var link = svg.append("g");

var brush = svg.append("g")
    .datum(function() { return {selected: false, previouslySelected: false}; })
    .attr("class", "brush");

var node = svg.append("g")
    .attr("class", "node")
    .selectAll("circle");

//Add the SVG Text Element to the svgContainer
text = svg.append('text').text('This is some information about whatever')
                        .attr('x', 50)
                        .attr('y', 200)
                        .attr('fill', 'black');

//you can delete this circle
svg.append("circle")
         .attr("class", "logo")
         .attr("cx", 225)
         .attr("cy", 225)
         .attr("r", 20)
         .style("fill", "transparent")       
         .style("stroke", "black")     
         .style("stroke-width", 0.25)
         .on("mouseover", function(){ 
               d3.select(this)
                   .style("fill", "url(#image)");
         })
          .on("mouseout", function(){ 
               d3.select(this)
                   .style("fill", "transparent");
         });

//get the json file with either error messages or the entire data as "graph" object
d3.json("graph.json", function(error, graph) {

  //"links" is a property in "graph", and contains some data in it. Iterate through all of them
  graph.links.forEach(function(d) //iterate through each data object in link
  {
    d.source = graph.nodes[d.source];//we got nodes too, with graph so access its data
    d.target = graph.nodes[d.target];
    d.linkStatus = d.status;
    console.log(d.source);
  });


  link = link.data(graph.links).enter().append("line")
      .attr("x1", function(d) { return d.source.x; })
      .attr("y1", function(d) { return d.source.y; })
      .attr("x2", function(d) { return d.target.x; })
      .attr("y2", function(d) { return d.target.y; })
      .attr("class", "link");

  brush.call(d3.svg.brush()
        .x(d3.scale.identity().domain([0, width]))
        .y(d3.scale.identity().domain([0, height]))
        .on("brushstart", function(d) {
          node.each(function(d) { d.previouslySelected = shiftKey && d.selected; });
        })
        .on("brush", function() {
          var extent = d3.event.target.extent();
          node.classed("selected", function(d) {
            return d.selected = d.previouslySelected ^
                (extent[0][0] <= d.x && d.x < extent[1][0]
                && extent[0][1] <= d.y && d.y < extent[1][1]);
          });
        })
        .on("brushend", function() {
          d3.event.target.clear();
          d3.select(this).call(d3.event.target);
        }));

  node = node.data(graph.nodes).enter().append("circle")
      .attr("r", 10)//radius
      .attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; })
      .on("mousedown", function(d) {
        if (!d.selected) { // Don't deselect on shift-drag.
          if (!shiftKey) node.classed("selected", function(p) { return p.selected = d === p; });
          else d3.select(this).classed("selected", d.selected = true);
        }
      })
      .on("mouseup", function(d) {
        if (d.selected && shiftKey) d3.select(this).classed("selected", d.selected = false);
      })
      .call(d3.behavior.drag()
        .on("drag", function(d) { nudge(d3.event.dx, d3.event.dy); }));
});

function nudge(dx, dy) 
{
  node.filter(function(d) { return d.selected; })
      .attr("cx", function(d) { return d.x += dx; })
      .attr("cy", function(d) { return d.y += dy; })

  link.filter(function(d) { return d.source.selected; })
      .attr("x1", function(d) { return d.source.x; })
      .attr("y1", function(d) { return d.source.y; });

  link.filter(function(d) { return d.target.selected; })
      .attr("x2", function(d) { return d.target.x; })
      .attr("y2", function(d) { return d.target.y; });

  d3.event.preventDefault();
}

function keydown() 
{
  if (!d3.event.metaKey) switch (d3.event.keyCode) {
    case 38: nudge( 0, -1); break; // UP
    case 40: nudge( 0, +1); break; // DOWN
    case 37: nudge(-1,  0); break; // LEFT
    case 39: nudge(+1,  0); break; // RIGHT
  }
  shiftKey = d3.event.shiftKey || d3.event.metaKey;
}

function keyup() 
{
  shiftKey = d3.event.shiftKey || d3.event.metaKey;
}

</script>


推荐答案

您不需要任何if-或对现有代码的广泛修改。 D3中设置的线条颜色的方式是通过 .style()命令:

You don't need any if-else conditions, or extensive modifications of the existing code. The way things like line color are set in D3 is through the .style() command:

link.style("stroke", ...);

参数不必是固定值,而可以是函数。然后对选择中的每个元素(在这种情况下为线)评估此函数,从而允许您为它们指定不同的颜色。例如,如果您想根据源的 x 位置给出不同的颜色,您将执行以下操作。

The argument doesn't have to be a fixed value, but can be a function. This function is then evaluated for each element in the selection (the lines in this case), allowing you to give them different colours. If, for example, you wanted to give different colours based on the x position of the source, you would do the following.

var color = d3.scale.category20();
link.style("stroke", function(d) { return color(d.source.x); });

您可以使用绑定到元素的数据的一部分( d )来确定你想要什么颜色,或者其他什么。例如,根据索引为每行设置不同的颜色。

You can use anything that's part of the data bound to the element (d) to determine what color you want, or indeed anything else. To e.g. set a different color for each line based on the index, you would do this.

link.style("stroke", function(d, i) { return color(i); });

这篇关于d3.js:将样式应用于单个线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆