如何从PostgreSQL数据库获取数据并通过Chart.js绘制图表
将PostgreSQL查询数据传递给Chart.js的实现方案
根据你的需求,有两种常用实现方式,核心是把后端查询到的year和price数据传递到前端,替换Chart.js的随机数据。
方案一:服务器端渲染直接注入数据
适合前后端不分离的场景,后端在渲染页面时直接把数据嵌入HTML中。
步骤:
- 安装Web框架(以Express为例):
npm install express ejs
- 修改后端
index.js,封装查询逻辑并通过模板传递数据:
const express = require('express'); const { Pool } = require('pg'); const app = express(); const port = 3000; // PostgreSQL连接配置,替换为你的实际信息 const pool = new Pool({ user: '你的用户名', host: 'localhost', database: '你的数据库名', password: '你的密码', port: 5432, }); // 查询房价数据的函数 async function fetchHousingData() { const result = await pool.query('SELECT year, price FROM year_price_housing ORDER BY year'); return result.rows; } // 设置模板引擎为EJS app.set('view engine', 'ejs'); // 静态资源目录(可选,放Chart.js本地文件等) app.use(express.static('public')); // 根路由,渲染页面并传递数据 app.get('/', async (req, res) => { try { const housingData = await fetchHousingData(); // 拆分年份和价格为单独数组 const years = housingData.map(item => item.year); const prices = housingData.map(item => item.price); // 渲染模板并传数据 res.render('index', { years, prices }); } catch (err) { console.error('查询数据失败:', err); res.status(500).send('数据加载失败'); } }); app.listen(port, () => { console.log(`服务器运行在 http://localhost:${port}`); });
- 创建
views/index.ejs(替代原index.html),嵌入数据到Chart.js配置:
<!DOCTYPE html> <html> <head> <title>房价趋势图</title> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> </head> <body> <canvas id="priceChart"></canvas> <script> const ctx = document.getElementById('priceChart').getContext('2d'); new Chart(ctx, { type: 'line', data: { labels: <%= JSON.stringify(years) %>, datasets: [{ label: '房价', data: <%= JSON.stringify(prices) %>, borderColor: '#2ecc71', backgroundColor: 'rgba(46, 204, 113, 0.1)', tension: 0.2 }] }, options: { scales: { x: { title: { display: true, text: '年份' } }, y: { title: { display: true, text: '价格' }, beginAtZero: false } } } }); </script> </body> </html>
方案二:前端通过API请求获取数据
适合前后端分离的场景,后端提供接口返回数据,前端异步请求后渲染图表。
步骤:
- 安装Express(如果没装):
npm install express
- 修改后端
index.js,新增API接口返回数据:
const express = require('express'); const { Pool } = require('pg'); const app = express(); const port = 3000; const pool = new Pool({ user: '你的用户名', host: 'localhost', database: '你的数据库名', password: '你的密码', port: 5432, }); async function fetchHousingData() { const result = await pool.query('SELECT year, price FROM year_price_housing ORDER BY year'); return result.rows; } // 静态资源目录,把你的index.html放在这里 app.use(express.static('public')); // API接口:返回房价数据 app.get('/api/housing-data', async (req, res) => { try { const data = await fetchHousingData(); res.json({ years: data.map(item => item.year), prices: data.map(item => item.price) }); } catch (err) { res.status(500).json({ error: '数据查询失败' }); } }); app.listen(port, () => { console.log(`服务器运行在 http://localhost:${port}`); });
- 修改
public/index.html,通过fetch请求数据并渲染图表:
<!DOCTYPE html> <html> <head> <title>房价趋势图</title> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> </head> <body> <canvas id="priceChart"></canvas> <script> async function renderChart() { try { // 请求后端API获取数据 const response = await fetch('/api/housing-data'); const { years, prices } = await response.json(); // 初始化Chart.js const ctx = document.getElementById('priceChart').getContext('2d'); new Chart(ctx, { type: 'line', data: { labels: years, datasets: [{ label: '房价', data: prices, borderColor: '#3498db', backgroundColor: 'rgba(52, 152, 219, 0.1)', tension: 0.2 }] }, options: { scales: { x: { title: { display: true, text: '年份' } }, y: { title: { display: true, text: '价格' }, beginAtZero: false } } } }); } catch (err) { console.error('加载数据失败:', err); alert('图表加载失败,请稍后重试'); } } // 页面加载完成后执行 window.addEventListener('load', renderChart); </script> </body> </html>
注意事项:
- 确保PostgreSQL服务正常运行,连接配置准确无误
- 查询SQL加上
ORDER BY year,保证年份按顺序排列,避免图表错乱 - 处理异常情况,比如数据库查询失败时返回错误信息,前端做容错处理
内容的提问来源于stack exchange,提问作者Merinoide
相关产品推荐
相关产品推荐

