如何将 MySQL 查询转换为 Morris 图表可读 json

How to convert MySQL query to Morris chart readable json

我有一个 MySQL 查询,在一些 php 干预后导出 json 数据。

激活 morris.js 图表需要 json 数据。

这是我现在的代码:

$lp = array('35', '95', '96');

print '<script>$(document).ready(function() { var day_data = ';
foreach ($lp as $value) {
    $data_array = array();
    foreach ($this->dbh->query("
        SELECT c.datefield AS DATE, IFNULL(COUNT(l.insertDate),0) AS TASK
        FROM calendar c
        LEFT JOIN lead l ON ( DATE( l.insertDate ) = c.datefield )
            AND l.lpid =  '$value'
        GROUP BY DATE
        ORDER BY c.datefield DESC
        LIMIT 30
    ") as $row) {
         //$data_array .=  $row['TASK'];   
         //echo '{"date": "'.$row['DATE'].'", "page 1": '.$row['TASK'].', "page 2": 5},';

         array_push($data_array, $row['DATE'], $row['TASK']);
         //$data_array = array_merge($data_array, array('date' => $row['DATE'],'val' => $row['TASK']));
    }
    echo json_encode($data_array);      
}

我想要的是能够在图表中看到多个id的动态数据。这是我想要达到的json:

{"date": "01-01-2017", "page 35": 3, "page 95": 5, "page 96": 5},
{"date": "02-01-2017", "page 35": 4, "page 95": 3, "page 96": 3},
{"date": "02-01-2017", "page 35": 9, "page 95": 5, "page 96": 4},
{"date": "03-01-2017", "page 35": 0, "page 95": 8, "page 96": 5};

也许更好的建议是将 json 数据按 id 导出,然后在前端按日期合并。

这是我的完整工作代码:

<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.min.js"></script>
<meta charset=utf-8 />
<title>Morris.js Bar Chart For DavSev</title>   
</head>
<body>
<?php
$pdo=new PDO("mysql:host=host;dbname=DB;charset=utf8","username","password");
$params=array(35,95,96);  // lps list
$js_cols="'".implode("','",$params)."'";
$placeholders=array_fill(0,sizeof($params),'?');
$sql="SELECT C.datefield AS `date`,L.lpid AS `lp`,IFNULL(COUNT(L.insertDate),0) AS `task` 
      FROM `calendar` C 
      LEFT JOIN `lead` L ON DATE(L.insertDate)=C.datefield
      WHERE L.lpid IN (".implode(',',$placeholders).")
      GROUP BY `DATE`,L.lpid
      ORDER BY C.datefield,L.lpid;";
$stmt=$pdo->prepare($sql);
$stmt->execute($params);
while($row=$stmt->fetch(PDO::FETCH_ASSOC)){
    if(!isset($data[$row["date"]])){
        $data[$row["date"]]=array_replace(array("D"=>$row["date"]),array_fill_keys($params,0));
    }
    $data[$row["date"]][$row["lp"]]=$row["task"];
}           
?>
<div id="bar-example"></div>
</body>
<script type="text/javascript">
Morris.Bar({
    element: 'bar-example',
    data: <?=json_encode(array_values($data))?>,  // shorthand echo
    xkey: 'D',
    ykeys: [<?=$js_cols?>],  // shorthand echo
    labels: [<?=$js_cols?>]  // shorthand echo
});
</script>
</html>
  • 我更改了您的外部脚本链接。
  • 我使用 pdo 和参数化语句以防 lps 是用户输入。
  • 我更改了您的查询以满足我的需要。请查看并比较,以便您了解查询更改。
  • 我暂时使用 date 作为键来正确构建 $data 数组。
  • 我将所有 lp 的每个日期值默认为零,然后如果 lp 在该日期有值,则覆盖它(while 循环的最后一行)。
  • 我在 json_encode() 之前使用 array_values() 从数组中删除 date 键。

渲染输出:

源代码输出:

<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.min.js"></script>
<meta charset=utf-8 />
<title>Morris.js Bar Chart Example</title>  
</head>
<body>
<div id="bar-example"></div>
</body>
<script type="text/javascript">
Morris.Bar({
    element: 'bar-example',
    data: [{"D":"2017-04-09","35":0,"95":0,"96":"1"},{"D":"2017-04-10","35":0,"95":0,"96":"1"},{"D":"2017-04-11","35":"1","95":"4","96":"1"},{"D":"2017-04-12","35":0,"95":0,"96":"1"},{"D":"2017-04-15","35":"2","95":0,"96":"1"},{"D":"2017-04-16","35":0,"95":0,"96":"1"}],
    xkey: 'D',
    ykeys: ['35','95','96'],
    labels: ['35','95','96']
});
</script>
</html>

我认为 Morris.Bar 函数的 labels 部分可能仍然有误,但如果您愿意,我会让您试一试。我已经为此投入了大量时间。