Javascript d3.js:条形图溢出标签
我有一个高度为270像素的d3条形图。图表呈现良好,但超出了x轴标签 当我尝试调整条形图的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
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轴。