当前位置:首页 > JavaScript

js实现折线图

2026-04-04 07:18:10JavaScript

使用 Canvas API 绘制折线图

通过原生 JavaScript 和 Canvas API 可以实现基础折线图。以下是一个完整示例:

// 获取 Canvas 元素和上下文
const canvas = document.getElementById('lineChart');
const ctx = canvas.getContext('2d');

// 数据准备
const data = [30, 60, 45, 80, 65, 95];
const labels = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'];

// 设置图表样式
const padding = 40;
const chartWidth = canvas.width - padding * 2;
const chartHeight = canvas.height - padding * 2;
const maxValue = Math.max(...data);

// 绘制坐标轴
ctx.beginPath();
ctx.moveTo(padding, padding);
ctx.lineTo(padding, padding + chartHeight);
ctx.lineTo(padding + chartWidth, padding + chartHeight);
ctx.strokeStyle = '#ccc';
ctx.stroke();

// 绘制折线
ctx.beginPath();
data.forEach((value, index) => {
  const x = padding + (index * chartWidth) / (data.length - 1);
  const y = padding + chartHeight - (value / maxValue) * chartHeight;

  if (index === 0) {
    ctx.moveTo(x, y);
  } else {
    ctx.lineTo(x, y);
  }

  // 绘制数据点
  ctx.fillStyle = '#3498db';
  ctx.fillRect(x - 3, y - 3, 6, 6);
});
ctx.strokeStyle = '#3498db';
ctx.lineWidth = 2;
ctx.stroke();

// 添加标签
ctx.fillStyle = '#666';
ctx.textAlign = 'center';
labels.forEach((label, index) => {
  const x = padding + (index * chartWidth) / (data.length - 1);
  ctx.fillText(label, x, canvas.height - padding / 2);
});

使用 Chart.js 库实现

Chart.js 是流行的开源图表库,实现折线图更简单:

<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<canvas id="myChart"></canvas>

<script>
  const ctx = document.getElementById('myChart');
  new Chart(ctx, {
    type: 'line',
    data: {
      labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
      datasets: [{
        label: 'Sales 2023',
        data: [30, 60, 45, 80, 65, 95],
        borderColor: 'rgb(75, 192, 192)',
        tension: 0.1,
        fill: false
      }]
    },
    options: {
      responsive: true,
      scales: {
        y: {
          beginAtZero: true
        }
      }
    }
  });
</script>

使用 D3.js 实现高级折线图

D3.js 适合需要高度定制的场景:

js实现折线图

import * as d3 from 'd3';

// 数据准备
const data = [
  { month: 'Jan', value: 30 },
  { month: 'Feb', value: 60 },
  { month: 'Mar', value: 45 },
  { month: 'Apr', value: 80 },
  { month: 'May', value: 65 },
  { month: 'Jun', value: 95 }
];

// 创建SVG容器
const svg = d3.select('#chart')
  .append('svg')
  .attr('width', 600)
  .attr('height', 400);

// 设置比例尺
const xScale = d3.scaleBand()
  .domain(data.map(d => d.month))
  .range([50, 550])
  .padding(0.2);

const yScale = d3.scaleLinear()
  .domain([0, d3.max(data, d => d.value)])
  .range([350, 50]);

// 创建折线生成器
const line = d3.line()
  .x(d => xScale(d.month) + xScale.bandwidth() / 2)
  .y(d => yScale(d.value));

// 绘制折线
svg.append('path')
  .datum(data)
  .attr('fill', 'none')
  .attr('stroke', 'steelblue')
  .attr('stroke-width', 2)
  .attr('d', line);

// 添加坐标轴
svg.append('g')
  .attr('transform', 'translate(0,350)')
  .call(d3.axisBottom(xScale));

svg.append('g')
  .attr('transform', 'translate(50,0)')
  .call(d3.axisLeft(yScale));

性能优化建议

  1. 大数据量时考虑使用 WebGL 渲染方案(如 ECharts GL)
  2. 避免频繁重绘,使用 requestAnimationFrame 进行动画
  3. 对静态图表使用 canvas.toDataURL() 缓存为图片
  4. 使用防抖技术处理窗口 resize 事件

响应式设计处理

function resizeChart() {
  const container = document.getElementById('chart-container');
  const aspectRatio = 16 / 9;

  if (container.offsetWidth / aspectRatio < container.offsetHeight) {
    canvas.width = container.offsetWidth - 30;
    canvas.height = canvas.width / aspectRatio;
  } else {
    canvas.height = container.offsetHeight - 30;
    canvas.width = canvas.height * aspectRatio;
  }

  // 重新绘制图表
  drawChart();
}

window.addEventListener('resize', () => {
  requestAnimationFrame(resizeChart);
});

以上方案可根据项目需求选择,原生 Canvas 适合轻量需求,Chart.js 适合快速开发,D3.js 适合复杂可视化场景。

标签: 折线图js
分享给朋友:

相关文章

js实现跳转

js实现跳转

使用 window.location 跳转 通过修改 window.location.href 实现页面跳转,这是最常用的方法。 window.location.href = 'https://…

js实现全屏

js实现全屏

实现全屏的基本方法 使用JavaScript实现全屏功能主要依赖Element.requestFullscreen()方法。现代浏览器均支持此API,但不同浏览器可能需要添加前缀。 // 触发全屏…

js 实现链表

js 实现链表

链表的基本概念 链表是一种线性数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针。与数组不同,链表在内存中是非连续存储的,插入和删除操作效率较高。 链表的实现 在 JavaScrip…

js实现正交

js实现正交

正交的概念 正交在数学和计算机科学中通常指两个向量垂直或线性无关。在编程中,正交性常被用于设计模块化、低耦合的系统。 向量正交判断 判断两个向量是否正交可以通过点积是否为0来实现: fun…

js实现轮播代码

js实现轮播代码

基础轮播实现 使用HTML、CSS和JavaScript创建一个简单的轮播效果。HTML部分定义轮播容器和图片元素。 <div class="carousel"> <div c…

js 实现拖拽

js 实现拖拽

实现拖拽的基本步骤 在JavaScript中实现拖拽功能需要监听几个关键事件:mousedown、mousemove和mouseup。以下是实现的基本逻辑。 监听目标元素的mousedown事件,记…