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

基于AJAX、PHP与MySQL的Flot双折线图表(销售/采购)实现咨询

Flot双折线图表(销售+采购)完整实现方案

一、前端完整代码

首先得确保引入jQuery和Flot的脚本(Flot依赖jQuery才能运行),然后编写图表容器和核心JS逻辑:

<!DOCTYPE html>
<html>
<head>
    <title>Sales & Purchase Trend</title>
    <!-- 引入jQuery -->
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <!-- 引入Flot核心库 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.min.js"></script>
    <!-- 可选:如果需要时间轴支持,引入时间插件 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.time.min.js"></script>
    <style>
        .demo-placeholder {
            width: 100%;
            height: 400px;
            margin: 20px 0;
        }
    </style>
</head>
<body>
    <div id="graph" class="demo-placeholder"></div>

    <script>
        $(document).ready(function() {
            // 同时请求销售和采购数据,减少AJAX请求次数
            $.when(
                $.getJSON('sales.php'),
                $.getJSON('purchase.php')
            ).done(function(salesData, purchaseData) {
                // 处理数据:把数据库返回的日期字符串转成Flot能识别的毫秒时间戳
                const processedSales = salesData[0].data.map(item => [
                    new Date(item[0]).getTime(),
                    parseFloat(item[1])
                ]);
                const processedPurchase = purchaseData[0].data.map(item => [
                    new Date(item[0]).getTime(),
                    parseFloat(item[1])
                ]);

                // 初始化Flot图表
                $.plot("#graph", [
                    {
                        label: salesData[0].label,
                        data: processedSales,
                        color: "#2ecc71" // 自定义销售线颜色
                    },
                    {
                        label: purchaseData[0].label,
                        data: processedPurchase,
                        color: "#e74c3c" // 自定义采购线颜色
                    }
                ], {
                    series: {
                        lines: { show: true, lineWidth: 2 }, // 显示线条并设置粗细
                        points: { show: true } // 可选:显示数据点
                    },
                    xaxis: {
                        mode: "time", // 启用时间轴模式
                        timeformat: "%Y-%m-%d", // 自定义X轴日期显示格式
                        tickSize: [1, "day"] // 按天显示刻度
                    },
                    yaxis: {
                        label: "Amount" // Y轴标签
                    },
                    grid: {
                        hoverable: true, // 开启鼠标悬停提示
                        clickable: true
                    },
                    legend: {
                        position: "nw" // 图例位置:左上角
                    }
                });

                // 可选:添加鼠标悬停提示框
                $("#graph").bind("plothover", function(event, pos, item) {
                    if (item) {
                        const date = new Date(item.datapoint[0]);
                        const formattedDate = date.toLocaleDateString();
                        $("#tooltip").remove();
                        $("<div id='tooltip'>")
                            .css({
                                position: "absolute",
                                display: "none",
                                border: "1px solid #fdd",
                                padding: "4px",
                                "background-color": "#fff",
                                opacity: 0.9,
                                "border-radius": "3px"
                            })
                            .text(`${item.series.label}: $${item.datapoint[1]} (${formattedDate})`)
                            .appendTo("body")
                            .css({top: pos.pageY + 10, left: pos.pageX + 10})
                            .show();
                    } else {
                        $("#tooltip").remove();
                    }
                });
            }).fail(function() {
                alert("Failed to load sales/purchase data!");
            });
        });
    </script>
</body>
</html>

二、后端PHP接口完善

1. 销售数据接口(sales.php)

注意:mysql_*函数已经被PHP官方废弃,强烈建议改用mysqli或PDO,下面给出两种版本:

版本1:兼容原有mysql_*(不推荐,仅用于旧项目过渡)
<?php
// 数据库连接配置
$host = 'localhost';
$user = 'your_db_username';
$pass = 'your_db_password';
$dbname = 'your_db_name';

// 建立连接
$conn = mysql_connect($host, $user, $pass);
mysql_select_db($dbname, $conn);

// 查询2013年的销售数据
$sql = "SELECT date, amount from sales where YEAR(date)='2013'";
$res = mysql_query($sql);
$return = [];
while($row = mysql_fetch_array($res)){
    // 直接返回日期字符串,留到前端转时间戳
    $return[] = [$row['date'], $row['amount']];
}

// 设置响应头为JSON格式
header('Content-Type: application/json');
echo json_encode(array("label"=>"Sales","data"=>$return));

// 关闭连接
mysql_close($conn);
?>
版本2:推荐使用mysqli(面向对象写法)
<?php
// 数据库连接配置
$host = 'localhost';
$user = 'your_db_username';
$pass = 'your_db_password';
$dbname = 'your_db_name';

// 建立连接
$conn = new mysqli($host, $user, $pass, $dbname);
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

// 查询2013年的销售数据
$sql = "SELECT date, amount from sales where YEAR(date)='2013'";
$result = $conn->query($sql);
$return = [];
while($row = $result->fetch_assoc()){
    // 可选:后端直接转成毫秒时间戳,前端无需再处理
    // $return[] = [strtotime($row['date']) * 1000, $row['amount']];
    $return[] = [$row['date'], $row['amount']];
}

// 返回JSON数据
header('Content-Type: application/json');
echo json_encode(array("label"=>"Sales","data"=>$return));

// 关闭连接
$conn->close();
?>

2. 采购数据接口(purchase.php)

逻辑和销售接口完全一致,只需要修改表名和返回的label:

<?php
$host = 'localhost';
$user = 'your_db_username';
$pass = 'your_db_password';
$dbname = 'your_db_name';

$conn = new mysqli($host, $user, $pass, $dbname);
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

// 查询2013年的采购数据
$sql = "SELECT date, amount from purchase where YEAR(date)='2013'";
$result = $conn->query($sql);
$return = [];
while($row = $result->fetch_assoc()){
    $return[] = [$row['date'], $row['amount']];
}

header('Content-Type: application/json');
echo json_encode(array("label"=>"Purchase","data"=>$return));

$conn->close();
?>

三、常见问题解决方法

  1. 图表空白/数据加载失败

    • 打开浏览器开发者工具(F12),查看Network标签,检查AJAX请求的状态码(200才是正常)和返回的JSON格式是否正确。
    • 确保PHP文件路径正确,若前端和后端不在同一域名,需在PHP文件头部添加CORS头:header("Access-Control-Allow-Origin: *");。
    • 检查数据库连接信息、SQL语句是否正确,可直接在数据库客户端执行SQL验证是否能返回数据。
  2. 日期显示异常

    • 确保数据库中的date字段是标准日期格式(如YYYY-MM-DD),否则前端无法解析成时间戳。
    • 若后端返回的是秒级时间戳,前端需要乘以1000转成Flot需要的毫秒时间戳。
  3. 折线样式不符合预期

    • 可通过修改Flot配置项调整:比如在series.lines中添加lineWidth: 3加粗线条,fill: true开启填充效果。
    • 图例位置可通过legend.position调整,可选值有nw(左上)、ne(右上)、sw(左下)、se(右下)。
  4. *PHP报错:mysql_函数未定义

    • 这是因为PHP 7+已彻底移除mysql_*扩展,直接改用上面推荐的mysqli或PDO版本即可解决。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:19:46