d3.js-旋转文本标签与点不完全对齐

d3.js-旋转文本标签与点不完全对齐,d3.js,D3.js,只要试着用d3.js绘制一个折线图,每个点上旋转的x轴标签和注释文本值看起来与点不完全匹配 如何调整它以匹配该点 test() 功能测试(){ var data=`标记,平均值 启动进度启动,10.8820000000000001 启动\进度\预加载\启动,12.677 开机检查进度检查预加载检查结束,15.962 启动进程系统运行,16.441 开机时间:17.179 开机(进度)(pms)(系统)(扫描)(启动),17.631 开机进程pms扫描结束,20.604 开机检查进度检查准备就绪

只要试着用d3.js绘制一个折线图,每个点上旋转的x轴标签和注释文本值看起来与点不完全匹配

如何调整它以匹配该点

test()
功能测试(){
var data=`标记,平均值
启动进度启动,10.8820000000000001
启动\进度\预加载\启动,12.677
开机检查进度检查预加载检查结束,15.962
启动进程系统运行,16.441
开机时间:17.179
开机(进度)(pms)(系统)(扫描)(启动),17.631
开机进程pms扫描结束,20.604
开机检查进度检查准备就绪,20.907
开机准备就绪,22.7930000000000006
启动\进度\启用\屏幕,25.401
sf_stop_bootanim,25.427
`
var数据集=d3.csvParse(数据);
dataset.forEach(d=>{d.x=d.tag;d.y=+d.mean})
var margin={顶部:50,右侧:50,底部:50,左侧:50}
,宽度=window.innerWidth-margin.left-margin.right
,高度=window.innerHeight-margin.top-margin.bottom;
var xScale=d3.scaleBand()
.范围([0,宽度])
.domain(dataset.map(函数(d){return d.x;}));
var yScale=d3.scaleLinear()
.domain([0,d3.max(数据集,函数(d){return d.y;})])
.范围([高度,0]);
var line=d3.line()
.x(函数(d,i){返回xScale(d.x);})
.y(函数(d){返回yScale(d.y);})
.curve(d3.curveMonotoneX)
var svg=d3.选择(“正文”).追加(“svg”)
.attr(“宽度”,宽度+边距。左侧+边距。右侧)
.attr(“高度”,高度+边距。顶部+边距。底部)
.附加(“g”)
.attr(“转换”、“平移”(+margin.left+)、“+margin.top+”);
svg.append(“g”)
.attr(“类”、“x轴”)
.attr(“变换”、“平移(0)”、“高度+”)
.call(d3.axisBottom(xScale))
.selectAll(“文本”)
.attr(“y”,0)
.attr(“x”,9)
.attr(“dy”、“3em”)
.attr(“变换”、“旋转(-30)”)
.样式(“文本锚定”、“结束”);
svg.append(“g”)
.attr(“类”、“y轴”)
.call(d3.axisLeft(yScale));
追加(“路径”)
.数据集(数据集)
.attr(“类”、“行”)
.attr(“d”,行)
.attr('stroke','black')
.attr('stroke-width',2)
.attr('fill','none')
svg.selectAll(“.dot”)
.数据(数据集)
.enter().append(“圆”)
.attr(“类”、“点”)
.attr(“cx”,函数(d,i){return xScale(d.x)})
.attr(“cy”,函数(d){返回yScale(d.y)})
.attr(“r”,5)
var anno=svg.selectAll(空)
.data(数据集)。输入()
.append(“文本”)
.text(函数(d){返回d.y.toFixed(1);})
.attr(“x”,函数(d){return xScale(d.x);})
.attr(“y”,函数(d){返回yScale(d.y)-15;})
.attr('text-anchor','middle')
.attr(“字体大小”,10)
.attr(“转换”,函数(d){
返回“旋转(45”+xScale(d.x)+”,“+yScale(d.y)+”)
});
var lines=svg.selectAll(空)
.data(数据集)。输入()
.附加(“行”)
.attr(“类”、“干线”)
.attr(“笔划”、“绿色”)
.attr(“笔划宽度”,1)
.attr(“x1”,函数(d){return xScale(d.x);})
.attr(“x2”,函数(d){return xScale(d.x);})
.attr(“y1”,函数(d){返回yScale(0);})
.attr(“y2”,函数(d){返回yScale(d.y);});
}

文本的位置至少由三组参数决定:

  • 它的坐标是
    x
    y
    属性
  • 它的
    文本锚定
    将其定位在坐标的左/中/右
  • 其基线,请参阅Mozilla文档中的和参考
  • 也就是说,您使用
    .attr(“x”,9)
    定位文本,使用
    .attr(“transform”,“rotate(-30)”)
    将文本旋转-30度,并使用
    样式(“文本锚定”,“end”)
    将其锚定到末尾。我不会旋转它,而是将它固定在中间:

    test()
    function test() {
      var data = `tag,mean
    boot_progress_start,10.882000000000001
    boot_progress_preload_start,12.677
    boot_progress_preload_end,15.962
    boot_progress_system_run,16.441
    boot_progress_pms_start,17.179
    boot_progress_pms_system_scan_start,17.631
    boot_progress_pms_scan_end,20.604
    boot_progress_pms_ready,20.907
    boot_progress_ams_ready,22.793000000000006
    boot_progress_enable_screen,25.401
    sf_stop_bootanim,25.427
    `
    
      var dataset = d3.csvParse(data);
      dataset.forEach(d => {d.x = d.tag; d.y = +d.mean})
    
      var margin = {top: 50, right: 50, bottom: 50, left: 50}
      , width = window.innerWidth - margin.left - margin.right
      , height = window.innerHeight - margin.top - margin.bottom;
    
      var xScale = d3.scaleBand()
      .range([0, width])
      .domain(dataset.map(function(d) { return d.x; }));
    
      var yScale = d3.scaleLinear()
      .domain([0, d3.max(dataset, function(d){ return d.y; })])
      .range([height, 0]);
    
      var line = d3.line()
      .x(function(d, i) { return xScale(d.x); })
      .y(function(d) { return yScale(d.y); })
      .curve(d3.curveMonotoneX)
    
      var svg = d3.select("body").append("svg")
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
      .append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
    
      svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(d3.axisBottom(xScale))
        .selectAll("text")
        .attr("y", 0)
        .attr("x", 9)
        .attr("dy", "3em")
        // changing the rotation to 0 or remove it
        .attr("transform", "rotate(0)")
        // anchoring the text at the center
        .style("text-anchor", "middle");
    
      svg.append("g")
        .attr("class", "y axis")
        .call(d3.axisLeft(yScale));
    
      svg.append("path")
        .datum(dataset)
        .attr("class", "line") 
        .attr("d", line) 
        .attr('stroke','black')
        .attr('stroke-width',2)
        .attr('fill','none')
     
      svg.selectAll(".dot")
        .data(dataset)
        .enter().append("circle")
        .attr("class", "dot")
        .attr("cx", function(d, i) { return xScale(d.x) })
        .attr("cy", function(d) { return yScale(d.y) })
        .attr("r", 5)
      
       var anno = svg.selectAll(null)
       .data(dataset).enter()
       .append("text")
      .text(function(d) {return d.y.toFixed(1);})
      .attr("x", function(d) { return xScale(d.x); })
      .attr("y", function(d) { return yScale(d.y) - 15; })
      .attr('text-anchor', 'middle')
      .attr("font-size",10)
      .attr("transform", function(d) {
        return "rotate(45 " + xScale(d.x) + "," + yScale(d.y) + ")"
      });
    
      var lines = svg.selectAll(null)
      .data(dataset).enter()
      .append("line")
      .attr("class", "stem-line")
      .attr("stroke", "green")
      .attr("stroke-width", 1)
      .attr("x1", function(d) { return xScale(d.x); } )
      .attr("x2", function(d) { return xScale(d.x); } )
      .attr("y1", function(d) { return yScale(0); } )
      .attr("y2", function(d) { return yScale(d.y); } );  
    }
    
    关于旋转的补充说明 您可能知道,因为您是为anno执行此操作,所以可以选择一个点来旋转对象。如果希望对象自身旋转,则必须指定对象自身的坐标:

    .attr("transform", function(d) {
        return "rotate(45 " + xScale(d.x) + " " + yScale(d.y) + ")"
      });
    

    回答这个问题的更好方法是把这个片段复制到你的答案中,并演示它是如何在视觉上解决问题的。谢谢你的建议,我对它很陌生!刚刚更新了答案,希望能对大家有所帮助