我使用D3创建一个条形图,看起来像这样:
目前,这些条从左上角***(由于D3坐标系)以Angular 浮动。我希望条形图***直接向下浮动,但***仅当用户滚动到页面的该部分时***(注意:该页面相当长,并且用户滚动到该元素将花费几分钟)。
下面是我的代码:
let data = [
{"color": "Blue", "plotValue": 11},
{"color": "Red", "plotValue": 20},
{"color": "Orange", "plotValue": 21},
{"color": "Purple", "plotValue": 30},
{"color": "Green", "plotValue": 35},
{"color": "Violet", "plotValue": 40},
]
vis.margin = {top: 70, right: 90, bottom: 90, left: 80};
vis.width = 800 - vis.margin.left - vis.margin.right;
// initialize the drawing area
vis.svg = d3.select('#' + vis.parentElement).append('svg')
.attr('width', vis.width + vis.margin.left + vis.margin.right)
.attr('height', vis.height + vis.margin.top + vis.margin.bottom)
.append('g')
.attr('transform', `translate (${vis.margin.left}, ${vis.margin.top})`);
// scales and axes
vis.xScale = d3.scaleBand()
.range( [ 0, vis.width ] )
.padding(0.4);
vis.yScale = d3.scaleLinear()
.range( [ vis.height, 0 ] );
vis.xAxis = d3.axisBottom()
.scale(vis.xScale);
vis.yAxis = d3.axisLeft()
.scale(vis.yScale);
// add chart title
vis.svg.append('g')
.attr('class', 'title bar-chart-title')
.append('text')
.text(vis.chartTitle)
.attr('transform', `translate(${vis.width / 2 + 45}, -50)`)
.attr('text-anchor', 'middle');
// tooltip
vis.tooltip = d3.select('body').append('div')
.attr('class', 'tooltip')
.attr('id', 'barChartTooltip');
// create the axis groups
vis.xAxisGroup = vis.svg.append('g')
.attr('class', 'x-axis axis')
.attr('transform', 'translate(0, ' + vis.height + ')');
vis.yAxisGroup = vis.svg.append('g')
.attr('class', 'y-axis axis');
let vis = this;
// update the domains
vis.xScale.domain(vis.data.map(function (d) { return d.color; }));
vis.yScale.domain( [ 0, 100 ] );
// draw the bars
vis.bars = vis.svg.selectAll('.bar')
.data(vis.data)
vis.bars.exit().remove();
vis.bars
.enter()
.append('rect')
.attr('class', 'bar')
.on('mouseover', function(event, d) {
d3.select(this)
.attr('stroke-width', '2px')
.attr('stroke', 'grey')
.attr('fill', 'blue')
vis.tooltip
.style('opacity', 1)
.style('left', event.pageX + 20 + 'px')
.style('top', event.pageY + 'px')
.html(`
<div style='border: thin solid grey; border-radius: 5px; background: lightgrey; padding: 20px'>
<h3>${d.color}</h3>
<h4> ${100- d.plotValue.toLocaleString()}% decline </h4>
</div>
`)
})
.on('mouseout', function(event, d) {
d3.select(this)
.attr('stroke-width', 1)
.attr('stroke', '#456983')
.attr('fill', function(d) {
return 'red'
})
vis.tooltip
.style('opacity', 0)
.style('left', 0)
.style('top', 0)
.html(``);
})
.merge(vis.bars)
.transition()
.duration(1200)
.attr('x', d => vis.xScale(d.color) )
.attr('y', d => vis.yScale(d.plotValue) )
.attr('width', vis.xScale.bandwidth() )
.attr('height', function(d) { return vis.height - vis.yScale(d.plotValue); })
.attr('fill', 'red')
// .attr('stroke', 'grey');
// add the axes
vis.xAxisGroup
.transition()
.duration(500)
.style('font-size', '15px')
.style('color', 'blue')
.call(d3.axisBottom((vis.xScale)))
.selectAll('text')
.attr('y', 30)
.attr('x', -35)
.attr('dy', '.35em')
.attr('transform', 'rotate(-30)')
;
vis.yAxisGroup
.transition()
.duration(500)
.style('font-size', '15px')
.style('color', 'blue')
.call(d3.axisLeft(vis.yScale));
vis.text = vis.svg.selectAll('.text')
.data(vis.data)
vis.text
.enter()
.append('text')
.attr('class', 'text')
.attr('text-anchor', 'middle')
.attr('x', d => vis.xScale(d.color) + 27)
.attr('y', d => vis.yScale(d.plotValue) - 10)
.text( function (d) {
return '-' + (100 - d.plotValue) + '%';
})
我该如何修改代码,使条形图直接向下浮动,并且仅在用户滚动到页面的该部分时触发?
提前感谢您给予的任何建议!
1条答案
按热度按时间pcww981p1#
没有像 *D3坐标系 * 这样的东西,那只是SVG坐标系:
0,0
是左上角。为了解决这个问题,您只需要在条形输入时设置
x
,y
和width
属性,然后更改过渡上的y
和height
属性。我相信显示向上的条形对用户来说更好,但是从顶部显示它们是微不足道的(只需更改原始的y
位置):关于只在用户到达SVG时才做动画,这是一个完全不同的问题,请在SO每个问题只保留一个问题。因此,您可以针对该单独问题发布另一个问题(您不需要在该新问题中使用d3.js标签)。