簡體   English   中英

D3 x 刻度定位

[英]D3 x scale positioning

在此處輸入圖片說明

大家好,我是 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's Margin Convention Block截取的屏幕截圖

在此處輸入圖片說明

因此,您確定所需的邊距大小(在本例中為底部 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約定,因此最好進行此實踐。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM