PHP项目怎样实现数据统计图表?

wen PHP项目 8

本文目录导读:

PHP项目怎样实现数据统计图表?

  1. 整体实现流程
  2. 主流图表库选择
  3. 完整示例:销售统计仪表盘
  4. 性能优化建议
  5. 图表库选择建议

我来详细介绍PHP项目实现数据统计图表的几种主流方案。

整体实现流程

数据获取 (PHP/MySQL) 
    → 数据处理 (数组/JSON) 
    → 图表生成 (JS库)
    → 前端展示

主流图表库选择

ECharts (推荐) - 百度开源

// PHP后端 - 准备数据
<?php
// 获取统计数据
$sql = "SELECT DATE(created_at) as date, COUNT(*) as count 
        FROM orders 
        GROUP BY DATE(created_at) 
        ORDER BY date DESC 
        LIMIT 7";
$result = $db->query($sql);
$data = [];
while($row = $result->fetch_assoc()) {
    $data[] = $row;
}
// 返回JSON
header('Content-Type: application/json');
echo json_encode($data);
?>
// 前端 - ECharts图表展示
$.ajax({
    url: 'api/getChartData.php',
    method: 'GET',
    success: function(res) {
        var myChart = echarts.init(document.getElementById('chart'));
        var dates = res.map(item => item.date);
        var counts = res.map(item => parseInt(item.count));
        var option = {
            xAxis: {
                type: 'category',
                data: dates
            },
            yAxis: {
                type: 'value'
            },
            series: [{
                data: counts,
                type: 'line' // 或 'bar'
            }]
        };
        myChart.setOption(option);
    }
});

Chart.js - 轻量级

// PHP输出JSON数据
$chartData = [
    'labels' => ['1月', '2月', '3月', '4月'],
    'datasets' => [
        [
            'label' => '销售额',
            'data' => [12000, 19000, 15000, 22000],
            'backgroundColor' => 'rgba(54, 162, 235, 0.2)'
        ]
    ]
];
echo json_encode($chartData);
// Chart.js 渲染
new Chart(document.getElementById('myChart'), {
    type: 'bar',
    data: <?php echo json_encode($chartData); ?>
});

Highcharts - 商业级

// 生成配置数组
$config = [
    'chart' => ['type' => 'column'], => ['text' => '月度销售统计'],
    'series' => [
        [
            'name' => '销售额',
            'data' => [5000, 8000, 12000, 15000]
        ]
    ]
];

完整示例:销售统计仪表盘

数据库表结构

CREATE TABLE orders (
    id INT PRIMARY KEY,
    amount DECIMAL(10,2),
    created_at DATETIME,
    status VARCHAR(20)
);
CREATE TABLE products (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    category VARCHAR(50),
    price DECIMAL(10,2)
);

PHP后端 - 统计API

<?php
// api/stats.php
class StatisticsController {
    // 1. 日销售额统计
    public function dailySales() {
        $sql = "SELECT DATE(created_at) as date, 
                SUM(amount) as total,
                COUNT(*) as orders 
                FROM orders 
                WHERE status = 'completed'
                GROUP BY DATE(created_at)
                ORDER BY date DESC 
                LIMIT 30";
        // 执行查询...
        return $this->formatChartData($result);
    }
    // 2. 分类销售占比
    public function categoryStats() {
        $sql = "SELECT p.category, 
                SUM(o.amount) as total,
                COUNT(*) as count
                FROM orders o
                JOIN products p ON o.product_id = p.id
                GROUP BY p.category";
        // 执行查询...
        return $this->formatPieData($result);
    }
    // 3. 本月每日趋势
    public function monthlyTrend() {
        $sql = "SELECT DATE_FORMAT(created_at, '%Y-%m-%d') as day,
                SUM(amount) as revenue
                FROM orders
                WHERE MONTH(created_at) = MONTH(CURDATE())
                AND YEAR(created_at) = YEAR(CURDATE())
                GROUP BY day";
        // 返回前端所需格式
        return [
            'dates' => array_column($data, 'day'),
            'revenue' => array_column($data, 'revenue')
        ];
    }
    // 数据格式化辅助函数
    private function formatChartData($result) {
        $categories = [];
        $values = [];
        while($row = $result->fetch_assoc()) {
            $categories[] = $row['date'];
            $values[] = floatval($row['total']);
        }
        return json_encode([
            'categories' => $categories,
            'values' => $values
        ]);
    }
}
?>

前端HTML - 完整仪表盘

<!DOCTYPE html>
<html>
<head>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
    <div class="dashboard">
        <!-- 折线图 - 销售趋势 -->
        <div id="salesTrend" style="height:400px"></div>
        <!-- 饼图 - 分类占比 -->
        <div id="categoryPie" style="height:300px"></div>
        <!-- 柱状图 - 对比 -->
        <div id="comparison" style="height:350px"></div>
    </div>
    <script>
    $(document).ready(function() {
        // 初始化图表
        initSalesTrend();
        initCategoryPie();
        initComparison();
    });
    function initSalesTrend() {
        $.getJSON('api/stats.php?action=daily', function(data) {
            var chart = echarts.init(document.getElementById('salesTrend'));
            chart.setOption({
                title: { text: '30天销售趋势' },
                tooltip: { trigger: 'axis' },
                xAxis: {
                    type: 'category',
                    data: data.categories
                },
                yAxis: {
                    type: 'value',
                    axisLabel: {
                        formatter: '¥{value}'
                    }
                },
                series: [{
                    name: '销售额',
                    type: 'line',
                    data: data.values,
                    smooth: true,
                    areaStyle: {}
                }]
            });
        });
    }
    function initCategoryPie() {
        $.getJSON('api/stats.php?action=category', function(data) {
            var chart = echarts.init(document.getElementById('categoryPie'));
            chart.setOption({
                title: { text: '分类销售占比' },
                series: [{
                    type: 'pie',
                    data: data,
                    radius: ['40%', '70%']
                }]
            });
        });
    }
    </script>
</body>
</html>

性能优化建议

数据缓存策略

// 使用Redis缓存统计结果
$cacheKey = 'stats_daily_' . date('Ymd');
if ($redis->exists($cacheKey)) {
    $data = json_decode($redis->get($cacheKey), true);
} else {
    // 执行复杂查询
    $data = $this->calculateDailyStats();
    $redis->setex($cacheKey, 3600, json_encode($data)); // 缓存1小时
}

大屏实时统计

// WebSocket推送更新
use Ratchet\MessageComponentInterface;
class StatsServer implements MessageComponentInterface {
    public function onOpen(ConnectionInterface $conn) {
        // 每5秒推送更新
        $this->loop->addPeriodicTimer(5, function() use ($conn) {
            $stats = $this->getLatestStats();
            $conn->send(json_encode($stats));
        });
    }
}

MySQL查询优化

-- 创建汇总表(物化视图)
CREATE TABLE daily_stats (
    date DATE PRIMARY KEY,
    total_sales DECIMAL(15,2),
    order_count INT,
    avg_amount DECIMAL(10,2)
);
-- 定时汇总
INSERT INTO daily_stats
SELECT DATE(created_at), 
       SUM(amount), 
       COUNT(*),
       AVG(amount)
FROM orders
WHERE created_at >= CURDATE() - INTERVAL 30 DAY
GROUP BY DATE(created_at)
ON DUPLICATE KEY UPDATE 
    total_sales = VALUES(total_sales),
    order_count = VALUES(order_count);

图表库选择建议

适用场景 特点
ECharts 企业级、大数据量 功能丰富、免费中文文档
Chart.js 简单图表、移动端 轻量级、响应式
Highcharts 商业项目 兼容性好、收费
D3.js 自定义可视化 灵活、学习成本高
AntV 数据驱动 阿里系、多图表类型

推荐方案

  • 小型项目:Chart.js + PHP JSON接口
  • 中型项目:ECharts + Redis缓存 + MySQL汇总表
  • 大型项目:ECharts + WebSocket + 专门统计服务

PHP主要负责数据获取和处理,图表渲染交给前端JS库,这种前后端分离的方式最灵活高效。

抱歉,评论功能暂时关闭!