D3.js "growing up" 3d 条形图的路径动画
D3.js "growing up" path animation for 3d bar chart
我正在尝试将经典动画添加到伪 3D 条形图。用 rect 做对非常简单。但是路径呢?
我有3个基本的3d效果路径:
如何制作和谐的成长动画?
createColumns(bars, data) {
//...skip code
bars
.data(data)
.append('path')
.attr(
'd',
(d) => `M 0,0 V ${rectHeight(d.value)} H ${rectWidth()} V 0 H 0 Z`,
)
.attr('class', 'forward-bar')
.classed('bar', true);
bars
.data(data)
.append('path')
.attr(
'd',
() =>
`M 0,0 L ${rectWidth()},0 L ${
rectWidth() + depth
}, ${-depth} H ${depth} Z`,
)
.attr('class', 'top-bar')
.classed('bar', true);
bars
.data(data)
.append('path')
.attr(
'd',
(d) =>
`M ${rectWidth()},0 L ${rectWidth() + depth},${-depth}, V ${
rectHeight(d.value) - depth
} L ${rectWidth()} ${rectHeight(d.value)} Z`,
)
.attr('class', 'side-bar')
.classed('bar', true);
}
使用 D3 转换实现(以毫秒为单位设置持续时间):
const add3DBar = (parent, xPos, yPos, width, height, depth, duration) => {
const g = parent.append('g').attr('transform', `translate(${xPos}, ${yPos})`);
g.append('path')
.attr('d', `M 0,0 V [=10=] H ${width} V 0 H 0 Z`)
.style('fill', '#000081')
.transition()
.duration(duration)
.attr('d', `M 0,0 V ${-height} H ${width} V 0 H 0 Z`);
g.append('path')
.attr('d', `M 0,[=10=] L ${depth},${-depth} H ${depth + width} L ${width},0 Z`)
.style('fill', '#0000FF')
.transition()
.duration(duration)
.attr('d', `M 0,${-height} L ${depth},${-height-depth} H ${depth + width} L ${width},${-height} Z`);
g.append('path')
.attr('d', `M ${width},0 L ${width + depth},${-depth}, V ${-depth} L ${width},0 Z`)
.style('fill', '#0000C0')
.transition()
.duration(duration)
.attr('d', `M ${width},0 L ${width + depth},${-depth}, V ${-height-depth} L ${width},${-height} Z`);
}
const svg = d3.select('svg');
add3DBar(svg, 30, 150, 30, 100, 10, 500);
add3DBar(svg, 70, 150, 30, 70, 10, 1000);
add3DBar(svg, 110, 150, 30, 120, 10, 1500);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg>
</svg>
我正在尝试将经典动画添加到伪 3D 条形图。用 rect 做对非常简单。但是路径呢?
我有3个基本的3d效果路径: 如何制作和谐的成长动画?
createColumns(bars, data) {
//...skip code
bars
.data(data)
.append('path')
.attr(
'd',
(d) => `M 0,0 V ${rectHeight(d.value)} H ${rectWidth()} V 0 H 0 Z`,
)
.attr('class', 'forward-bar')
.classed('bar', true);
bars
.data(data)
.append('path')
.attr(
'd',
() =>
`M 0,0 L ${rectWidth()},0 L ${
rectWidth() + depth
}, ${-depth} H ${depth} Z`,
)
.attr('class', 'top-bar')
.classed('bar', true);
bars
.data(data)
.append('path')
.attr(
'd',
(d) =>
`M ${rectWidth()},0 L ${rectWidth() + depth},${-depth}, V ${
rectHeight(d.value) - depth
} L ${rectWidth()} ${rectHeight(d.value)} Z`,
)
.attr('class', 'side-bar')
.classed('bar', true);
}
使用 D3 转换实现(以毫秒为单位设置持续时间):
const add3DBar = (parent, xPos, yPos, width, height, depth, duration) => {
const g = parent.append('g').attr('transform', `translate(${xPos}, ${yPos})`);
g.append('path')
.attr('d', `M 0,0 V [=10=] H ${width} V 0 H 0 Z`)
.style('fill', '#000081')
.transition()
.duration(duration)
.attr('d', `M 0,0 V ${-height} H ${width} V 0 H 0 Z`);
g.append('path')
.attr('d', `M 0,[=10=] L ${depth},${-depth} H ${depth + width} L ${width},0 Z`)
.style('fill', '#0000FF')
.transition()
.duration(duration)
.attr('d', `M 0,${-height} L ${depth},${-height-depth} H ${depth + width} L ${width},${-height} Z`);
g.append('path')
.attr('d', `M ${width},0 L ${width + depth},${-depth}, V ${-depth} L ${width},0 Z`)
.style('fill', '#0000C0')
.transition()
.duration(duration)
.attr('d', `M ${width},0 L ${width + depth},${-depth}, V ${-height-depth} L ${width},${-height} Z`);
}
const svg = d3.select('svg');
add3DBar(svg, 30, 150, 30, 100, 10, 500);
add3DBar(svg, 70, 150, 30, 70, 10, 1000);
add3DBar(svg, 110, 150, 30, 120, 10, 1500);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg>
</svg>