[D3] Animate Chart Axis Transitions in D3 v4

When the data being rendered by a chart changes, sometimes it necessitates a change to the scales and axes of the chart as well. This lesson demonstrates how to animate and synchronize axis transitions on a column chart.

 

复制代码
var svg = d3.select('.chart')
    .append('svg')
    .attr('width', width + margin.left + margin.right)
    .attr('height', height + margin.top + margin.bottom)
    .call(responsivefy)
    .append('g')
    .attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')');
/**
 * Y axis
 */
const yScale = d3.scaleLinear()
    .domain([
        0, 100
    ])
    .range([height, 0]);
const yAxis = svg
    .append('g')
    .call(d3.axisLeft(yScale));

/**
 * x axis
 */
const xScale = d3.scaleBand()
    .domain(data.map(d => d.name))
    .range([0, width])
    .padding(0.2);
const xAxis = d3.axisBottom(xScale).tickSize(10).tickPadding(5);
svg.append('g')
    .attr('transform', `translate(0, ${height})`)
    .call(xAxis)
    .selectAll('text')
    .attr('text-anchor', 'end')
    .attr('transform', 'rotate(-45)');

// enter: which in the data, but not yet on the page
// upate: which in the data, and also in the page
// exit: which not in the data, but exist on the page
// end


function render(subject = 'math') {

    // Define a resuable transation variable
    var t = d3.transition().duration(1000);

    var update = svg.selectAll('rect')
        .data(data.filter(d => d[subject]), d => d.name); //d => d.name is a uniq idientifier

    // First: we want to remove the existing object which doesn't have any value
    // Get rid of null value object
    // Also animation y and height attr to produce
    // fade out effect 
    update
        .exit()
        .transition(t)
        .attr('y', height)
        .attr('height', 0)
        .remove();

    // Update the y axis with animation
    yScale.domain(
        [0, d3.max(data, d => d[subject])]
    );
    yAxis
        .transition(t)
        .delay(1000)
        .call(d3.axisLeft(yScale));

    // Second, we want to animate the existing elements height    
    update
        .transition(t)
        .delay(1000)
        .attr('y', d => yScale(d[subject]))
        .attr('height', d => height - yScale(d[subject]));

    // Last, for the new data which is not in the page before
    // We want to animate    
    update
        .enter()
        .append('rect')
        .attr('y', height)
        .attr('height', 0)
        .attr('x', d => xScale(d.name))
        .attr('width', d => xScale.bandwidth())
        .transition(t)
        .delay(update.exit().size() ? 2000 : 0) // If page refresh, we don't want to wait 2000ms
        .attr('y', d => yScale(d[subject]))
        .attr('height', d => height - yScale(d[subject]));
}

render();
复制代码

 

 

 

posted @   Zhentiw  阅读(438)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
历史上的今天:
2015-08-28 [Javascript] Linting JavaScript with ESLint
2015-08-28 [CSS] Transition
点击右上角即可分享
微信分享提示