Text D3.js如何在路径上旋转文本

Text D3.js如何在路径上旋转文本,text,svg,path,d3.js,rotation,Text,Svg,Path,D3.js,Rotation,这是我的第一个D3项目(我不是程序员,所以一下子就学会了所有东西) 我正试图制作一个圆形日历,我已经手工绘制了好几年,这是一个巨大的痛苦 大多数位现在都在工作,但我不知道如何在这个弧上将文本旋转90度 一旦我把文字转过来,我就需要弄清楚如何使它在圆圈周围的间隔相等 我的目标是让它看起来像这个手绘的例子: 以下是它当前的外观: 我可能已经走到了死胡同,把文本放在一条小路上,所以欢迎任何和所有的建议 编辑:我在这里创建了一个JSFIDLE 以下是我目前掌握的代码: <!DOCTYPE ht

这是我的第一个D3项目(我不是程序员,所以一下子就学会了所有东西)

我正试图制作一个圆形日历,我已经手工绘制了好几年,这是一个巨大的痛苦

大多数位现在都在工作,但我不知道如何在这个弧上将文本旋转90度

一旦我把文字转过来,我就需要弄清楚如何使它在圆圈周围的间隔相等

我的目标是让它看起来像这个手绘的例子:

以下是它当前的外观:

我可能已经走到了死胡同,把文本放在一条小路上,所以欢迎任何和所有的建议

编辑:我在这里创建了一个JSFIDLE

以下是我目前掌握的代码:

<!DOCTYPE html>
<meta charset="utf-8">
<style>
body { font: 12px Arial;}
path {
    stroke: red;
    stroke-width: 1;
    fill: none;
}
.axis path,
.axis line {
    fill: none;
    stroke: grey;
    stroke-width: 1;
    shape-rendering: crispEdges;
}
</style>

<body>
    <script type="text/javascript" src="d3/d3.v3.js"></script>

    <script type="text/javascript">

var margin = {top: 25, right: 25, bottom: 25, left: 25},
width = 950 - margin.left - margin.right,
height = 950 - margin.top - margin.bottom;

// Build Day Numbers
function pad(n) {
    return (n < 10) ? ("0" + n) : n;
}

function getDaysArray(year) {
    var numDaysInMonth, daysInWeek, daysIndex, index, i, l, daysArray;

    numDaysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    daysInWeek = ['S', 'M', 'T', 'W', 'T', 'F', 'S'];
    daysIndex = { 'Sun': 0, 'Mon': 1, 'Tue': 2, 'Wed': 3, 'Thu': 4, 'Fri': 5, 'Sat': 6 };

    daysArray = [];

for (m=0; m < 12; m++) {
        index = daysIndex[(new Date(year, m, 1)).toString().split(' ')[0]];
    for (i = 0, l = numDaysInMonth[m]; i < l; i++) {
        daysArray.push(pad((i + 1)) + ' ' + daysInWeek[index++]);
        if (index == 7) index = 0;
    }
}
    return daysArray;
}


var year = 2014

var days = getDaysArray(year)

var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g"),
    pi = Math.PI;


var arc = d3.svg.arc()
    .innerRadius(850)
    .outerRadius(851)
    .startAngle(0)
    .endAngle(-pi*1.99999)

var path = svg.append("path")
    .attr("d", arc)
    .attr("id", "path1")
    .attr("transform", "translate(900,900)")
    .attr("fill","#f00")


// Draw lines
function daysInYear(year) {
    if(year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)) {
        // Leap year
        return 366;
    } else {
        // Not a leap year
        return 365;
    }
}

var dt = new Date(year+"/01/01");
var day = dt.getDay();
var startrads = (2*pi / daysInYear(year)) * day;
    //---center point(width,height)---
        var cx=width
        var cy=height
        var r=850 //--radius--
        var radialLines=52 //---create 52 lines---
        var angle=2*Math.PI/radialLines //---angle between each line---
        var radialPoints=[]
        for(var k=startrads;k<radialLines;k++)
        {
                var x2=r*Math.cos(angle*k)+cx
                var y2=r*Math.sin(angle*k)+cy
                radialPoints.push([x2,y2])
        }
    //---your d3 SVG parent element---
        svg.selectAll("line")//---an empty selection---
        .data(radialPoints)
        .enter().append("svg:line")
        .attr("x1",cx)
        .attr("y1",cy)
        .attr("x2",function(p){return p[0]})
        .attr("y2",function(p){return p[1]})
        .attr("stroke","red");



// Add day labels.
var text1 = svg.append("text");


text1
    .selectAll("body")
    .data(days)
    .enter()
    .append("textPath")
    .attr("xlink:href","#path1")
    .text(function(d) { return d; });



    </script>

</body>

正文{font:12px Arial;}
路径{
笔画:红色;
笔画宽度:1;
填充:无;
}
.轴线路径,
.轴线{
填充:无;
笔画:灰色;
笔画宽度:1;
形状渲染:边缘清晰;
}
var margin={顶部:25,右侧:25,底部:25,左侧:25},
宽度=950-边距。左侧-边距。右侧,
高度=950-页边距.top-页边距.bottom;
//建立日数
功能板(n){
返回值(n<10)(“0”+n):n;
}
函数getDaysArray(年){
变量numDaysInMonth、daysInWeek、daysIndex、index、i、l、daysArray;
numDaysInMonth=[31,28,31,30,31,30,31,30,31,30,31];
daysInWeek=['S','M','T','W','T','F','S'];
daysIndex={'Sun':0,'Mon':1,'Tue':2,'Wed':3,'Thu':4,'Fri':5,'Sat':6};
daysArray=[];
对于(m=0;m<12;m++){
索引=daysIndex[(新日期(年,m,1)).toString().split(“”)[0]];
对于(i=0,l=numDaysInMonth[m];i对于(var k=startrads;k来说,要正确地获取文本,只需以计算放射线末端的相同方式计算其位置和旋转

svg.selectAll("text").data(days).enter()
.append("text")
.attr("transform", function(d, i) {
    return "translate(" + (850*Math.cos(i*2*Math.PI/365)+width) +
           "," + (850*Math.sin(i*2*Math.PI/365)+height) + ")" +
           "rotate(" + (i*360/365) + ")";
})
.text(function(d) { return d; });
请注意,在JSFIDLE中可见的圆圈一侧,文本将颠倒。您可以通过在
rotate
value.Modified JSFIDLE中添加180来解决此问题