d3js如何获得旋转的矩形角坐标?

时间:2017-03-01 16:10:43

标签: d3.js svg rect

我对d3js很陌生,在这里感觉有些不知所措。我试图弄清楚如何查询旋转的矩形的角坐标,这样我就可以在该位置放置一个圆圈(最终我将把它作为一条线的起始坐标来链接到其他节点)。

这是一张显示我想要做的事情的图片: enter image description here

目前我在下面的svg边界的左侧得到了圆圈,我试图将它大致放在x在下面的位置。

以下是我的圆圈代码:

  let rx = node.attr("x");
  let ry = node.attr("y");
  g.append("circle")
    .attr("cx",rx)
    .attr("cy",ry)
    .attr("r",5);

这是我的jsFiddle:jsFiddle和Stack Overflow片段



 	let d3Root = 'd3-cpm';

  let w = document.documentElement.clientWidth;
  let h = document.documentElement.clientHeight;
  //TODO put type any
  let eData = {
    width: 180,
    height: 180,
    padding: 80,
    fill: '#E0E0E0',
    stroke: '#c3c5c5',
    strokeWidth: 3,
    hoverFill: '#1958b5',
    hoverStroke: '#0046ad',
    hoverTextColor: '#fff',
    rx: 18,
    ry: 18,
    rotate: 45,
    label: 'Decision Node',
    textFill: 'black',
    textHoverFill: 'white'
  };
  let cWidth;
  let cHeight = h;

  d3.select(d3Root)
    .append("div")
    .attr("id", "d3-root")
    .html(function () {
    let _txt = "Hello From D3! <br/>Frame Width: ";
    let _div = d3.select(this);
    let _w = _div.style("width");
    cWidth = parseInt(_div.style("width"));
    _txt += cWidth + "<br/> ViewPort Width: " + w;
    return _txt;
  });

  let svg = d3.select(d3Root)
  .append("svg")
  .attr("width", cWidth)
  .attr("height", cHeight)
  .call(d3.zoom()
        //.scaleExtent([1 / 2, 4])
        .on("zoom", zoomed));
  ;
  

  let g = svg.append("g")
  .on("mouseover", function (d) {
    d3.select(this)
      .style("cursor", "pointer");
    d3.select(this).select("rect")
      .style("fill", eData.hoverFill)
      .style("stroke", eData.hoverStroke);
    d3.select(this).select("text")
      .style("fill", eData.textHoverFill);
  })
  .on("mouseout", function (d) {
    d3.select(this)
      .style("cursor", "default");
    d3.select(this).select("rect")
      .style("fill", eData.fill)
      .style("stroke", eData.stroke);
    d3.select(this).select("text")
      .style("fill", eData.textFill);
  });
  

  let node = g.append("rect")
  .attr("width", eData.width)
  .attr("height", eData.height)
  .attr("fill", eData.fill)
  .attr("stroke", eData.stroke)
  .attr("stroke-width", eData.strokeWidth)
  .attr("rx", eData.rx)
  .attr("ry", eData.ry)
  .attr("y", eData.padding)
  .attr('transform', function () {
    let _x = calcXLoc();
    console.log(_x);
    return "translate(" + _x + "," + "0)  rotate(45)";
  })
  .on("click", ()=> {
    console.log("rect clicked");
    d3.event.stopPropagation();
    //this.nodeClicked();
  });

  let nText = g.append('text')
  .text(eData.label)
  .style('fill', eData.textFill)
  .attr('x', calcXLoc() - 50)
  .attr('y', eData.width + 10)
  .attr("text-anchor", "middle")
  .on("click", ()=> {
    console.log("text clicked");
    d3.event.stopPropagation();
    //this.nodeClicked();
  });

	let rx = node.attr("x");
  let ry = node.attr("y");
  g.append("circle")
  	.attr("cx",rx)
    .attr("cy",ry)
    .attr("r",5);

  function calcXLoc() {
    return (cWidth / 2 - eData.width / 2) + eData.width;
  }
  
	function zoomed() {
    g.attr("transform", d3.event.transform);
  }
	
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
<d3-cpm></d3-cpm>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

您正在transform应用rect来定位和旋转它。它没有x属性,因此返回未定义。这让你更接近:

  let rx = parseInt(node.attr("x"), 10) | 0;
  let ry = parseInt(node.attr("y"), 10) | 0;
  let height = parseInt(node.attr("height"), 10) | 0;
  let transform = node.attr("transform");
  g.append("circle")
    .attr("cx",rx + height)
    .attr("cy",ry + height)
    .attr("transform", transform)
    .attr("r",5);

但是请注意,这会变得笨拙且难以处理 - 如果您的数据建模的方式使圆形点也在那里处理并且可能以某种方式处理,那么它会更好衍生/变换一致......

更新了小提琴:https://jsfiddle.net/dcw48tk6/7/

图片:enter image description here