Project

General

Profile

Actions

Web tech » History » Revision 15

« Previous | Revision 15/29 (diff) | Next »
jun chen, 02/13/2025 03:05 PM


Web tech

How to visualize data:

D3 ref: https://observablehq.com/@d3/gallery , https://johan.github.io/d3/ex/
Plotly ref: https://plotly.com/javascript/


交互功能对比

功能 JavaScript/Plotly Python/Plotly JavaScript/d3
缩放/平移 ✔️ ✔️ ✔️
悬停显示数值 ✔️ ✔️ ✔️
数据点高亮 ✔️ ✔️ ✔️
导出为图片(PNG/JPEG) ✔️ ✔️ ✔️
动态更新数据 ✔️(需额外代码) ✔️
旧firefox支持 ❌(globalthis) ? ✔️

js d3 csv


// 设置图表的尺寸和边距
const margin = {top: 20, right: 30, bottom: 30, left: 40},
      width = 960 - margin.left - margin.right,
      height = 500 - margin.top - margin.bottom;

// 设置SVG的尺寸
const svg = d3.select("#chart").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})`);

// 设置比例尺
const x = d3.scaleLinear().range([0, width]);
const y = d3.scaleLinear().range([height, 0]);

// 定义折线生成器
const line = d3.line()
    .x((d, i) => x(i))
    .y(d => y(d.observation));

// 读取CSV文件
d3.csv("data.csv").then(data => {
    // 转换数据类型
    data.forEach((d, i) => {
        d.observation = +d.observation;
        d.index = i;
    });

    // 设置比例尺的域
    x.domain([0, data.length - 1]);
    y.domain([0, d3.max(data, d => d.observation)]);

    // 添加折线
    svg.append("path")
        .datum(data)
        .attr("class", "line")
        .attr("d", line);

    // 添加点
    svg.selectAll(".dot")
        .data(data)
      .enter().append("circle")
        .attr("class", "dot")
        .attr("cx", (d, i) => x(i))
        .attr("cy", d => y(d.observation))
        .attr("r", 5)
        .on("mouseover", function(event, d) {
            tooltip.transition()
                .duration(200)
                .style("opacity", .9);
            tooltip.html(`Observation: ${d.observation}<br>Label: ${d.label}`)
                .style("left", (event.pageX + 5) + "px")
                .style("top", (event.pageY - 28) + "px");
        })
        .on("mouseout", function(d) {
            tooltip.transition()
                .duration(500)
                .style("opacity", 0);
        });

    // 添加X轴
    svg.append("g")
        .attr("transform", `translate(0,${height})`)
        .call(d3.axisBottom(x));

    // 添加Y轴
    svg.append("g")
        .call(d3.axisLeft(y));
});

// 添加提示工具
const tooltip = d3.select("body").append("div")
    .attr("class", "tooltip")
    .style("opacity", 0);
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>D3.js Line Chart</title>
    <script src="https://d3js.org/d3.v7.min.js"></script>
    <style>
        .line {
            fill: none;
            stroke: steelblue;
            stroke-width: 2px;
        }
        .dot {
            fill: steelblue;
            stroke: #fff;
        }
        .tooltip {
            position: absolute;
            text-align: center;
            width: 120px;
            height: auto;
            padding: 5px;
            font: 12px sans-serif;
            background: lightsteelblue;
            border: 0px;
            border-radius: 8px;
            pointer-events: none;
        }
    </style>
</head>
<body>
    <div id="chart"></div>
    <script src="script.js"></script>
</body>
</html>

js d3 内嵌数据显示折线

show code...

JavaScript + Plotly(纯前端实现)

show code...

使用步骤:

  1. 将CSV文件命名为 data.csv,格式如下:
    x,y
    1,5
    2,3
    3,7
    4,2
    5,8
    
  2. 将HTML文件和 data.csv 放在同一目录下,用浏览器打开HTML文件。
  3. 效果:支持缩放、悬停显示数值、拖拽平移等交互。

Python + Plotly(生成独立HTML文件)

特点:适合Python用户,自动化生成图表文件。

show code...

使用步骤:

  1. 安装依赖:
    pip install pandas plotly
    
  2. 运行代码后,生成 interactive_chart.html,用浏览器打开即可看到图表。

进阶方案(可选)

  1. 动态数据加载(JavaScript):

View details...

  • 用户可上传任意CSV文件,实时生成图表。
  1. 添加控件(Python + Dash):
    View details...

    • 运行后访问 http://localhost:8050,支持动态交互和按钮触发操作。

Updated by jun chen 4 months ago · 29 revisions