Y axis labels are cut off on D3 plot

六月ゝ 毕业季﹏ 提交于 2020-01-13 18:10:11

问题


I have this multi-line plot with D3:

But as you can see, the beginning of the y-axis labels are cut off - anybody know how I can properly display the full label?

And if you have any advice on how to rotate the x-axis labels by 90 degrees, that would help too.

Here is the complete code which generates the plot:

<!DOCTYPE html>
<html lang='en'>

<head>

  <link href='http://getbootstrap.com/dist/css/bootstrap.min.css' rel='stylesheet'>
  <link href='http://getbootstrap.com/examples/justified-nav/justified-nav.css' rel='stylesheet'>
  <script src='http://d3js.org/d3.v3.min.js' charset='utf-8'></script>

  <style>

    .axis path {
      fill: none;
      stroke: #777;
      shape-rendering: crispEdges;
    }

    .axis text {
      font-family: Lato;
      font-size: 13px;
    }

  </style>

</head>

<body>

<div class='container'>

  <div class='jumbotron'>

    <svg id='visualisation'></svg>

    <script>

      var heapTotal = JSON.parse('[{"x":1501478175044,"y":18911232},{"x":1501478177048,"y":19959808}]');
      var heapUsed = JSON.parse('[{"x":1501478175044,"y":10492112},{"x":1501478177048,"y":10904080}]');
      var rss = JSON.parse('[{"x":1501478175044,"y":35622912},{"x":1501478177048,"y":36134912}]');

      const values = heapTotal.concat(heapUsed).concat(rss).reduce(function (prev, curr) {

        console.log('curr => ', curr);

        return {
          xMin: Math.min(prev.xMin, curr.x),
          xMax: Math.max(prev.xMax, curr.x),
          yMin: Math.min(prev.yMin, curr.y),
          yMax: Math.max(prev.yMax, curr.y),
        }

      }, {
        xMin: Number.MAX_SAFE_INTEGER,
        xMax: -1,
        yMin: Number.MAX_SAFE_INTEGER,
        yMax: -1
      });

      console.log('values => ', values);

      var vis = d3.select('#visualisation'),
        WIDTH = 1200,
        HEIGHT = 800,
        MARGINS = {
          top: 20,
          right: 20,
          bottom: 20,
          left: 50
        },
        xScale = d3.scale.linear().range([MARGINS.left, WIDTH - MARGINS.right]).domain([values.xMin - 50, values.xMax + 50]),
        yScale = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([values.yMin - 50, values.yMax + 50]),
        xAxis = d3.svg.axis()
        .scale(xScale),
        yAxis = d3.svg.axis()
        .scale(yScale)
        .orient('left');

      vis.attr("width", WIDTH)
      .attr("height", HEIGHT);

      vis.append('svg:g')
      .attr('class', 'x axis')
      .attr('transform', 'translate(0,' + (HEIGHT - MARGINS.bottom) + ')')
      .call(xAxis);

      vis.append('svg:g')
      .attr('class', 'y axis')
      .attr('transform', 'translate(' + (MARGINS.left) + ',0)')
      .call(yAxis);

      var lineGen = d3.svg.line()
      .x(function (d) {
        return xScale(d.x);
      })
      .y(function (d) {
        return yScale(d.y);
      })
      .interpolate('basis');

      vis.append('svg:path')
      .attr('d', lineGen(heapUsed))
      .attr('stroke', 'green')
      .attr('stroke-width', 2)
      .attr('fill', 'none');

      vis.append('svg:path')
      .attr('d', lineGen(heapTotal))
      .attr('stroke', 'blue')
      .attr('stroke-width', 2)
      .attr('fill', 'none');

      vis.append('svg:path')
      .attr('d', lineGen(rss))
      .attr('stroke', 'red')
      .attr('stroke-width', 2)
      .attr('fill', 'none');


    </script>
  </div>

</div>

</body>

</html>

回答1:


One easy css way is to give some padding to the svg element. It will keep the map in better shape.

METHOD 1: just change the left margin value in the script:

MARGINS = {
    top: 20,
    right: 20,
    bottom: 20,
    left: 50 // change this to something larger like 100
  },

Method 2: Using CSS

var heapTotal = JSON.parse(
  '[{"x":1501478175044,"y":18911232},{"x":1501478177048,"y":19959808}]'
);
var heapUsed = JSON.parse(
  '[{"x":1501478175044,"y":10492112},{"x":1501478177048,"y":10904080}]'
);
var rss = JSON.parse(
  '[{"x":1501478175044,"y":35622912},{"x":1501478177048,"y":36134912}]'
);

const values = heapTotal.concat(heapUsed).concat(rss).reduce(function(
  prev,
  curr
) {
  console.log("curr => ", curr);

  return {
    xMin: Math.min(prev.xMin, curr.x),
    xMax: Math.max(prev.xMax, curr.x),
    yMin: Math.min(prev.yMin, curr.y),
    yMax: Math.max(prev.yMax, curr.y)
  };
}, {
  xMin: Number.MAX_SAFE_INTEGER,
  xMax: -1,
  yMin: Number.MAX_SAFE_INTEGER,
  yMax: -1
});

console.log("values => ", values);

var vis = d3.select("#visualisation"),
  WIDTH = 1200,
  HEIGHT = 800,
  MARGINS = {
    top: 20,
    right: 20,
    bottom: 20,
    left: 50
  },
  xScale = d3.scale
    .linear()
    .range([MARGINS.left, WIDTH - MARGINS.right])
    .domain([values.xMin - 50, values.xMax + 50]),
  yScale = d3.scale
    .linear()
    .range([HEIGHT - MARGINS.top, MARGINS.bottom])
    .domain([values.yMin - 50, values.yMax + 50]),
  xAxis = d3.svg.axis().scale(xScale),
  yAxis = d3.svg.axis().scale(yScale).orient("left");

vis.attr("width", WIDTH).attr("height", HEIGHT);

vis
  .append("svg:g")
  .attr("class", "x axis")
  .attr("transform", "translate(0," + (HEIGHT - MARGINS.bottom) + ")")
  .call(xAxis);

vis
  .append("svg:g")
  .attr("class", "y axis")
  .attr("transform", "translate(" + MARGINS.left + ",0)")
  .call(yAxis);

var lineGen = d3.svg
  .line()
  .x(function(d) {
    return xScale(d.x);
  })
  .y(function(d) {
    return yScale(d.y);
  })
  .interpolate("basis");

vis
  .append("svg:path")
  .attr("d", lineGen(heapUsed))
  .attr("stroke", "green")
  .attr("stroke-width", 2)
  .attr("fill", "none");

vis
  .append("svg:path")
  .attr("d", lineGen(heapTotal))
  .attr("stroke", "blue")
  .attr("stroke-width", 2)
  .attr("fill", "none");

vis
  .append("svg:path")
  .attr("d", lineGen(rss))
  .attr("stroke", "red")
  .attr("stroke-width", 2)
  .attr("fill", "none");
#visualisation{
  padding: 0px 20px;
}
.axis path {
      fill: none;
      stroke: #777;
      shape-rendering: crispEdges;
    }

    .axis text {
      font-family: Lato;
      font-size: 13px;
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg id='visualisation'></svg>



回答2:


The file is set up nicely to make this pretty easy. You can just change the left margin. Something like 75 seems to work to keep you axis labels from clipping.:

MARGINS = {
      top: 20,
      right: 20,
      bottom: 20,
      left: 75
},

The class jumbotron is adding a margin to the whole div, which you might need to change move the chart if this pushes everything over to far to the right.



来源:https://stackoverflow.com/questions/45408077/y-axis-labels-are-cut-off-on-d3-plot

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!