D3 x刻度定位

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了D3 x刻度定位相关的知识,希望对你有一定的参考价值。

enter image description here

大家好,我是d3.js的新手,我希望得到x轴刻度定位的帮助。

我需要将x轴刻度定位在y轴刻度附近。简单来说,我想向上移动x刻度以触及其底部尖端的y刻度。请查看附图以获得清晰的图片。

但是,我可以通过改变y刻度范围的值来向下移动y刻度,但我不希望这样,因为我试图避免x轴标签被截断,如图所示,因此我需要将它们向上移动。

这是我的整个代码:

 d3.json("month.json", function(error, jdata) {

 var margin = {top: 20, right: 160, bottom: 35, left: 30};
 var width = 960 - margin.left - margin.right,
 height = 500 - margin.top - margin.bottom;

 var svg = d3.select("#chart").append("svg")
             .attr("width", 1200)
             .attr("height",  height + margin.top + margin.bottom)
             .append("g")
             .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

 var data = jdata.MonthsData;
 var dataset = d3.layout.stack()(["Value", "Value3", "Value1", "Value2"].map(function (c) {
    return data.map(function (d) {
             if(d.Total == 0){
                return { x: d.Location + " - Volume: "+ d.Max +")", y: +d[c]};   
            }else{
                return { x: d.Location + " - Volume: "+ d.Max +" - Total: "+d.Total, y: +d[c]};
            }  
        });
 }));

 var x = d3.scale.ordinal()
          .domain(dataset[0].map(function (d){return d.x;})) 
          .rangeRoundBands([0, width-10], .25, .100);

var y = d3.scale.linear()
          .domain([0, 380]).nice()  
          .range([height - 30, 0]);

var colors = ["#002672", "#B8CFFF","#70A0FF","#2970FF"];

var xAxis = d3.svg.axis().scale(x).orient("bottom");        
var yAxis = d3.svg.axis().scale(y).orient("left").ticks(10).tickSize(-width, 0, 0).tickFormat( function(d) { return d } ); 

           svg.append("g")
               .attr("class", "y axis")
               .call(yAxis);

           svg.append("g")
               .attr("class", "x axis")
               .attr("transform", "translate(0," + height + ")")
               .call(xAxis)
               .selectAll(".tick text")
               .call(wrap, x.rangeBand());  

var groups = svg.selectAll("g.cost")
               .data(dataset)
               .enter()
               .append("g")
               .attr("class", "cost")
               .style("fill", function (d, i) {return colors[i];});

var rect  = groups.selectAll("rect")
               .data(function (d) {return d;})
               .enter().append("rect")
               .attr("x", function (d) {return x(d.x);})
               .attr("y", function (d) {return y(d.y + d.y0);})
               .attr("height", function (d) {return y(d.y0) - y(d.y + d.y0);})
               .attr("width", x.rangeBand())
               .on("mouseover", function() { tooltip.style("display", null); })
               .on("mouseout", function() { tooltip.style("display", "none"); })
               .on("mousemove", function(d) {
                 var xPosition = d3.mouse(this)[0] - 15;
                 var yPosition = d3.mouse(this)[1] - 25;
                 tooltip.attr("transform", "translate(" + xPosition + "," + yPosition + ")");
                 tooltip.select("text").text(d.y);
               })
               .append("text")
               .attr("class", "label")
               .attr("x", function (d,i) {
                  return i * ( width / dataset.length);
               })
               .attr("y", function (d) {
                  var e = d.y;
                  return (height - e);
               })
               .attr("font-size", "16px")
               .attr("fill", "red") 
               .text(function (d){
                  return d.y;
               });

// Draw legend
var legend = svg.selectAll(".legend")
              .data(colors)
              .enter().append("g")
              .attr("class", "legend")
              .attr("transform", function(d, i) { return "translate(30," + i * 19 + ")"; });

        legend.append("rect")
              .attr("x", width - 18)
              .attr("width", 18)
              .attr("height", 18)
              .style("fill", function(d, i) {return colors.slice().reverse()[i];});

        legend.append("text")
              .data(dataset)
              .attr("x", width + 5)
              .attr("y", 9)
              .attr("dy", ".35em")
              .style("text-anchor", "start")
              .text(function(d, i) { 
                switch (i) {
                  case i: return d[i].x;
                }
              });   

            // Prep the tooltip bits, initial display is hidden
            var tooltip = svg.append("g")
                          .attr("class", "tooltip")
                          .style("display", "none");

                    tooltip.append("rect")
                          .attr("width", 30)
                          .attr("height", 20)
                          .attr("fill", "white")
                          .style("opacity", 0.5);

                    tooltip.append("text")
                          .attr("x", 15)
                          .attr("dy", "1.2em")
                          .style("text-anchor", "middle")
                          .attr("font-size", "12px")
                          .attr("font-weight", "bold");     

            //Text Wrap funtion on x-axis labels
            function wrap(text, width) {
              text.each(function() {
                var text = d3.select(this),
                    words = text.text().split(/s+/).reverse(),
                    word,
                    line = [],
                    lineNumber = 0,
                    lineHeight = 1.1, // ems
                    y = text.attr("y"),
                    dy = parseFloat(text.attr("dy")),
                    tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
                while (word = words.pop()) {
                  line.push(word);
                  tspan.text(line.join(" "));
                  if (tspan.node().getComputedTextLength() > width) {
                    line.pop();
                    tspan.text(line.join(" "));
                    line = [word];
                    tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
                  }
                }
              });
            }

            function type(d) {
              d.value = +d.value;
              return d;
            }                 

});  
答案

通常,您定位轴的方式是获取高度,然后减去任何填充。这是Mike的Margin Convention Block截图

enter image description here

因此,您可以确定边距所需的尺寸(在本例中为底部x轴),然后在添加x轴时,您只需执行以下操作:

 var margin = { top: 20, right: 10, bottom: 20, left: 10 };

 svg.append("g")
           .attr("class", "x axis")
           .attr("transform", "translate(0," + height - margin.bottom + ")")
           .call(xAxis)
           .selectAll(".tick text")
           .call(wrap, x.rangeBand());

然后,应该将您的轴定位到您设置的任何余量。请注意,这是一个D3惯例,所以最好进入这种做法。

以上是关于D3 x刻度定位的主要内容,如果未能解决你的问题,请参考以下文章

如何解决d3.js中x轴上的重叠刻度文本

对条形图中的 x 轴使用序数刻度 ('d3.scale.ordinal')

在 D3.js 中创建带有序数刻度的文本标记 x 轴

添加 d3 时间轴开头的额外刻度

d3中的多行svg文本轴刻度

D3.js:为啥我的图例刻度线的文字消失了?