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

时间:2017-05-01 07:18:41

标签: php mysql json charts morris.js

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

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

这是我现在的代码:

$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};

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

1 个答案:

答案 0 :(得分:1)

以下是我的完整工作代码:

<!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循环的最后一行)。
  • 我在array_values()之前使用json_encode()从数组中删除date - 键。

渲染输出:

enter image description here

源代码输出:

<!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>

我认为labels功能的Morris.Bar部分可能仍然错误,但如果您愿意,我会让您玩这个功能。我在这方面投入了相当多的时间。