Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/473.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript d3.js:条形图溢出标签_Javascript_Svg_D3.js_Label_Bar Chart - Fatal编程技术网

Javascript d3.js:条形图溢出标签

Javascript d3.js:条形图溢出标签,javascript,svg,d3.js,label,bar-chart,Javascript,Svg,D3.js,Label,Bar Chart,我有一个高度为270像素的d3条形图。图表呈现良好,但超出了x轴标签 当我尝试调整条形图的y或height属性时,它们超出了svg的边界,要么在顶部(调整height),要么在最底部(调整y)。我怎样才能给这些条一个底部的“边距”,以适应标签 构建图表的函数: buildTimeline: -> width = @ui.chartWrap.width() height = @ui.chartWrap.height() console.log height

我有一个高度为270像素的d3条形图。图表呈现良好,但超出了x轴标签

当我尝试调整条形图的
y
height
属性时,它们超出了
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)
  #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))
图表的CSS(SASS):

  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)
  #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))

与其调整图形的“x”和“y”属性,不如尝试更改比例上的范围。如果你用
.range(50,width)
(或
.rangeround(50,width)
)而不是
(0,width)
,你会给自己一个50px的边距。

我最后根据这里的教程重写了整个代码:

最终产品如下所示:

  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())

你能为我们创建一个JSFIDLE吗?我真的会帮上忙。我没有完全理解你的代码,但我的感觉是你需要额外的变量,比如说padding,当你计算横杆的垂直尺寸时,你就用(高度-padding)代替padding。然后使用相同的填充来定位x轴。