如何在不改变坐标的情况下转换(旋转)svg文本元素?

Posted

技术标签:

【中文标题】如何在不改变坐标的情况下转换(旋转)svg文本元素?【英文标题】:How to transform (rotate) svg text element without changing coordinates? 【发布时间】:2018-03-30 17:07:34 【问题描述】:

我是这个 d3.js 的新手。在这里,我尝试使用 d3.v3.js 库绘制条形图。在这里,我面临一些问题。我试图将度量标签包含在 y 轴上。但是一旦我将标签转换为 -90 度,它的位置就会自动改变。

这是我习惯绘制的代码:

    svg.append("g")
    .attr("id","x_axis")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis)
    .selectAll("text")  
    .style("text-anchor", "end")
    .attr("dx", "-.8em")
    .attr("dy", ".15em")
    .attr("transform", "rotate(-65)");
    // .attr("transform", "translate(" + bandSize + ", 0)")

    svg.append("g")
    .attr("class", "x axis")
    .attr("id","dimLabel")
    .append("text")
    .style("text-anchor", "end")
    .attr("x", width/2)
    .attr("y", height+55) 
    .text(dimensionLabels[0]);




    svg.append("g")
    .attr("id","y_axis1")
    .attr("class", "y axis")
    .call(yAxis)
    .append("text")
    .attr("class", "label")
    //.attr("transform", "rotate(-90)")
    .attr("y", function(d)return y(d3.max(data, function(d)  return d.Metric1; )););


    //Measure Labels
    svg.append("g")
    .attr("class", "y axis")
    .attr("id","measureLabels")
    .append("text")
    .style("text-anchor", "end")
    .attr("x", 0)
    .attr("y", height/2) 
    .text(measureLabels[0]+", "+measureLabels[1])
    .attr("transform", "rotate(-90)");

输出图像:

非常感谢任何帮助。

【问题讨论】:

如果你提供更多代码甚至像jsfiddle.net/vintharas/0m9raoj4987654321@这样的小提琴会很有用 您是否尝试过使用 text-anchor: middle 而不是 end(在度量标签部分)? 谢谢大家的回复。抱歉,这是我第一次在 *** 上发布查询。我将包括一个 jsfiddle。 @shareef 我试过 text-anchor:middle 它给了我同样的结果。但是这次位置稍微改变了@rm4。 您希望标签在哪里?也许你也可以试试 start 而不是 end 我希望标签位于 y 轴的左侧。我尝试了所有的strat,end,middle。 .attr("transform", "rotate(-90)") 这行代码从左到右改变位置。你能帮我解决这个问题吗 【参考方案1】:

您现在看到的是预期结果,因为transform 属性的rotate 函数使元素围绕原点 (0,0) 旋转,而不是围绕其中心旋转。

最简单的解决方案是删除您的attr("x")attr("y") 并使用相同的transform 定位文本:

var width = 300,
  height = 300;
var svg = d3.select("body")
  .append("svg")
  .attr("width", width)
  .attr("height", height);
var text = svg.append("text")
  .text("Sum (sales), Sum (quantity)")
  .attr("text-anchor", "middle")
  .attr("transform", "translate(20," + (height / 2) + ") rotate(-90)")
svg 
  border: 1px solid gray;
<script src="https://d3js.org/d3.v3.min.js"></script>

另一种解决方案是将rotate 的中心设置为相同的xy 值:

var width = 300,
  height = 300;
var svg = d3.select("body")
  .append("svg")
  .attr("width", width)
  .attr("height", height);
var text = svg.append("text")
  .text("Sum (sales), Sum (quantity)")
  .attr("text-anchor", "middle")
  .attr("x", 20)
  .attr("y", 150)
  .attr("transform", "rotate(-90, 20, 150)")
svg 
  border: 1px solid gray;
<script src="https://d3js.org/d3.v3.min.js"></script>

【讨论】:

感谢第二个解决方案:设置rotate 的中心是一个非常好的主意。【参考方案2】:

我认为您正在寻找 css 属性 transform-origin https://developer.mozilla.org/en-US/docs/Web/CSS/transform-origin

【讨论】:

以上是关于如何在不改变坐标的情况下转换(旋转)svg文本元素?的主要内容,如果未能解决你的问题,请参考以下文章

在不更改字体的情况下将SVG转换为PNG

如何在不改变高度的情况下让 SVG 具有流畅的宽度?

如何在不破坏布局“流程”的情况下使用 css 旋转元素?

CSS 样式转换与 svg 转换

如何在不使用 Google 地图的情况下将纬度/经度转换为 HTML5 坐标?

如何在不改变世界坐标中的相对位置、大小和比例的情况下将 SCNNode 作为子节点添加到父节点