You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按日、周、月切换展示CSV数据可视化图表?

按日/周/月切换D3图表的维度实现方案

核心思路

通过D3的时间分组工具,将原始数据按指定维度(日/周/月)聚合,再根据按钮触发重新渲染图表。


步骤1:保存原始解析数据

先把CSV解析后的数据存起来,避免切换时重复加载文件,同时确保value转为数字类型:

let rawData;
const parseDate = d3.timeParse("%Y-%m-%d");

d3.csv("/dates_name_value.csv", function(d){
    return { 
        date: parseDate(d.date), 
        value: +d.value, // 转换为数字,否则聚合会出错
        name: d.name 
    }
}).then(function(data) {
    rawData = data;
    // 默认渲染日维度图表
    renderChart('day');
});

步骤2:实现数据聚合函数

根据传入的维度,用d3.rollup对数据分组并计算聚合值(这里以总和为例,可替换为平均值等):

function aggregateData(dimension) {
    // 选择对应维度的时间分组器
    const timeGroup = {
        day: d3.timeDay,
        week: d3.timeWeek,
        month: d3.timeMonth
    }[dimension] || d3.timeDay;

    // 按时间维度+name分组,计算每组value总和
    const groupedData = d3.rollup(
        rawData,
        group => d3.sum(group, d => d.value), // 聚合逻辑,可替换为d3.mean/d3.max等
        d => timeGroup.floor(d.date), // 将日期归到当前维度的起始点(如周的周一、月的1号)
        d => d.name // 多系列图表需按name分组,单系列可删除此参数
    );

    // 转换为便于渲染的数组格式
    const aggregated = [];
    groupedData.forEach((nameValues, date) => {
        nameValues.forEach((value, name) => {
            aggregated.push({ date, value, name });
        });
    });
    return aggregated;
}

步骤3:实现图表渲染/更新函数

接收聚合后的数据,更新图表的比例尺和可视化元素:

// 假设已定义width、height、svg容器等基础变量
function renderChart(dimension) {
    const chartData = aggregateData(dimension);

    // 更新时间比例尺
    const xScale = d3.scaleTime()
        .domain(d3.extent(chartData, d => d.date))
        .range([0, width]);

    // 更新数值比例尺
    const yScale = d3.scaleLinear()
        .domain([0, d3.max(chartData, d => d.value)])
        .range([height, 0]);

    // 这里添加你的图表更新逻辑:重绘折线、柱状图或其他元素
    // 例如折线图的路径更新:
    const line = d3.line()
        .x(d => xScale(d.date))
        .y(d => yScale(d.value));
    
    svg.selectAll('.line')
        .data(d3.group(chartData, d => d.name))
        .join('path')
        .attr('class', 'line')
        .attr('d', ([name, data]) => line(data));
}

步骤4:添加按钮切换事件

给日/周/月按钮绑定点击事件,触发对应维度的图表渲染:

<button id="day-btn">日</button>
<button id="week-btn">周</button>
<button id="month-btn">月</button>
// 绑定按钮事件
d3.select('#day-btn').on('click', () => renderChart('day'));
d3.select('#week-btn').on('click', () => renderChart('week'));
d3.select('#month-btn').on('click', () => renderChart('month'));

注意事项

  • 如果数据是UTC时间,需将d3.timeDay替换为d3.utcDay,周/月同理,避免时区偏移问题。
  • 聚合逻辑可根据需求调整:比如用d3.mean计算平均值,d3.max取最大值等。
  • 单系列图表可删除rollup中的d => d.name参数,简化分组逻辑。

内容的提问来源于stack exchange,提问作者Kenneth Abillon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 21:12:29