d3.js:条形图溢出标签

时间:2014-01-02 21:23:17

标签: javascript svg d3.js label bar-chart

我有一个高度为270像素的d3条形图。图表渲染得很好,但它超出了x轴标签。

当我尝试调整条形的yheight属性时,它们会覆盖svg的边界,在最顶层(调整height)或最底部(调整y)。如何给条形图一个底部“边距”,以容纳标签?

构建图表的功能:

  buildTimeline: ->
    width = @ui.chartWrap.width()
    height = @ui.chartWrap.height()
    console.log height
    dataLength = @data.values.length
    x = d3.time.scale()
      .domain(
        [
          new Date "#{@data.values[0].x}-1-1"
          new Date("#{@data.values[dataLength - 1].x}-1-1")
        ]
      ).rangeRound [0, width - (width/dataLength - 1)]

    y = d3.scale.linear()
      .domain(
        [
          0
          d3.max(@data.values, (d) ->
            d.y
          )
        ]
      ).rangeRound [height, 0]

    xAxis = d3.svg.axis()
      .scale(x)
      .orient('bottom')
      .ticks(d3.time.years, 1)
      .tickFormat(d3.time.format('%Y'))

    yAxis = d3.svg.axis()
      .scale(y)
      .orient('left')
      .tickPadding(8)

    svg = d3.select(@ui.chartWrap[0]).append('svg')
        .attr('width', width)
        .attr('height', height)

    # Bars
    svg.append('g')
      .attr('id', 'timeline-bars')
      .selectAll(".bar")
      .data(@data.values)
      .enter().append("rect")
      .attr("class", "bar")
      .attr("x", (d) ->
        x(new Date "#{d.x}-1-1")
      )
      .attr("width", width/dataLength - 1)
      .attr("y", (d) ->
        y(d.y)
      )
      .attr("height", (d) =>
        height - y(d.y)
      ).attr("data-date", (d) =>
        d.x
      ).attr("data-count", (d) =>
        d.y
      )

    svg.append("g")
      .attr('id', 'timeline-x-labels')
      .call(xAxis)

图表的CSS(SASS):

  #timeline
    height: 270px
    margin: 10px
    cursor: crosshair
    font-size: 1em

    .bar
      fill: blue
      shape-rendering: crispEdges
      &:hover
        cursor: pointer
        fill: darken(blue, 10)

    #timeline-x-labels
      +translate(0, 240px)
      path, line
        fill: none
        stroke: shade(gainsboro, 10%)
        shape-rendering: crispEdges

      .tick > text
        font-size: 0.7em
        +user-select(none)
        +transform(translate(0px, 10px) rotate(-60deg))

2 个答案:

答案 0 :(得分:0)

尝试更改刻度上的范围,而不是调整图表的“x”和“y”属性。如果您使用.range(50, width)(或.rangeround(50, width))而不是(0,width)绘制比例,您将有效地为自己提供50px的保证金。

答案 1 :(得分:0)

我最终根据这里的教程重写了整个代码:http://bost.ocks.org/mike/bar/3/

最终产品如下所示:

  buildTimeline: ->
    margin = 
      top: 10
      bottom: 30
      left: 40
      right: 10
    width = @ui.chartWrap.width() - margin.left - margin.right
    height = @ui.chartWrap.height() - margin.top - margin.bottom
    dataLength = @data.values.length

    y = d3.scale.linear()
      .range([height, 0])

    x = d3.scale.ordinal()
      .rangeRoundBands([0, width], 0.1)

    xAxis = d3.svg.axis()
      .scale(x)
      .orient 'bottom'

    yAxis = d3.svg.axis()
      .scale(y)
      .orient('left')
      .tickFormat (d) ->
        prefix = d3.formatPrefix d
        prefix.scale(d) + prefix.symbol

    @chart = d3.select(@ui.chartWrap[0]).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})")

    x.domain _.pluck(@data.values, 'x')
    y.domain [0, d3.max(_.pluck(@data.values, 'y'))]

    @chart.append('g')
      .attr('id', 'timeline-x-axis')
      .attr('class', 'axis')
      .attr('transform', "translate(0, #{height})")
      .call xAxis

    @chart.append('g')
      .attr('class', 'axis')
      .call yAxis

    @chart.selectAll('.bar')
      .data(@data.values)
      .enter().append('rect')
      .attr('class', 'bar')
      .attr('x', (d) ->
        x(d.x)
      )
      .attr('y', (d) ->
        y(d.y)
      )
      .attr('height', (d) ->
        height - y(d.y)
      )
      .attr('width', x.rangeBand())