php+mysql统计最近30天空值补0,chart.js画折线图

需求:

统计最近7天/30天数据画折线图

最终成果图:

1534410155(1).png
1534410238(1).png

先上html:

<?php
use yii\widgets\LinkPager;

?>
<script type="text/javascript" src="/common/lib/layer.ext.js"></script>
<script src="/common/lib/admin/js/bootstrap.min.js"></script>
<script src="/common/lib/admin/js/chart.min.js"></script>
<script>

    function datacount(){
        window.location.href = '/guest/third/datacount';
    }
    function search(){
        window.location.href="//www.greatytc.com/guest/third/drawthirdcaiwusum?dayselect="+$("#dayselect").val();
    }

</script>

<div id="page-inner" style="padding: 30px;">
    <div class="row">
        <div class="col-md-12">
            <h1 class="page-header">
                财务统计图表
            </h1>
        </div>
        <div class="panel-body">
            <div class="dataTables_wrapper form-inline" style="margin-bottom: 15px;">
                <select class="btn btn-default btn-sm" id="dayselect">
                    <option value = "7" <?= $day == 7?'selected' : ''?>>近7天</option>
                    <option value = "30" <?= $day == 30?'selected' : ''?>>近30天</option>
                </select>
                &nbsp;&nbsp;
                <button class="btn btn-default btn-sm" onclick="search()" title="点击搜索"><i class="fa fa-search"></i>&nbsp;&nbsp;<b>Search</b></button>
                &nbsp;&nbsp;
                <button id="drawdatacount" onclick="datacount()" class="btn btn-sm btn-info">表格显示</button>
            </div>


        </div>

        <div class="container">
            <div class="row">
                <div class="col-xs-1 "><canvas id="myChart"></canvas></div>
                <div class="col-xs-10 "><canvas id="myChart1"></canvas></div>
            </div>
        </div>
    </div>
</div>

<script>

    var ctx = document.getElementById("myChart1");
    var myChart = new Chart(ctx, {
        type: 'line', // line 表示是 曲线图,当然也可以设置其他的图表类型 如柱形图 : bar  或者其他
        data: {
            labels : <?=$a?>, //按时间段 可以按星期,按月,按年
            datasets : <?=$c?>
        }
    });
</script>

方法一:

//交易量折线图
public function actionDrawthirdcaiwusum()
{
    if (Yii::$app->request->get("dayselect")) {
        $day = Yii::$app->request->get("dayselect");
    } else {
        $day = 7;
    }

    $rows=Yii::$app->db->createCommand("select thirdid,FROM_UNIXTIME(yocreatetime,'%Y-%m-%d') as datetime
,SUM(yototal) as money
from ibd_third_oyihuo
LEFT JOIN ibd_shop ON (ibd_third_oyihuo.yosellerid=ibd_shop.suid or ibd_third_oyihuo.yobuyerid=ibd_shop.suid)
where (ystatus = 1 or ystatus = 4) and yotype<20
and yocreatetime>=unix_timestamp(DATE_FORMAT(subdate(now(),$day),'%Y-%m-%d'))
and yocreatetime<unix_timestamp(DATE_FORMAT(now(),'%Y-%m-%d'))
group by thirdid,FROM_UNIXTIME(yocreatetime,'%Y-%m-%d')
ORDER BY yocreatetime desc")->query();

    $th=IbdThirdInfo::find()->all();
    $id=[];
    foreach($th as $val){
        $id[]=$val->id;
    }
    for ($i = $day; 0 < $i; $i--) {
        $result[] = date('Y-m-d', strtotime('-' . $i . ' day'));
        foreach($id as $vvv){
            ${'money'.$vvv}[] =0;
        }
    }
    foreach($rows as $k => $v){
        foreach($result as $value =>$item){
//                print_r($v);
            $temp = reset($v);
            $index = array_search($v['datetime'],$result);
            ${'money'.$temp}[$index]=sprintf("%.2f",$v['money']/100);
        }
    }

    function my_json_decode($str) {
        $str = preg_replace('/"(\w+)"(\s*:\s*)/is', '$1$2', $str);   //去掉key的双引号
        return $str;
    }
    $color = array("#EE0000","#00FFFF","#712704","#43A102","#049FF1","#FFA500","#4C4C4C","#00CCFF","#72CFD7","#FF8C05");
    $res= array();

    foreach($id as $vv){
        $fileinfo['label'] = IbdThirdInfo::findOne(['id'=>$vv])->name;
        $fileinfo['fill'] = true;
        $fileinfo['borderColor'] = $color[$vv%10];
        $fileinfo['pointBackgroundColor'] = "#fff";
        $fileinfo['data'] = ${'money'.$vv};
        array_push($res, $fileinfo);
    }
    $a = json_encode($result);
    $c = my_json_decode(json_encode($res));
//        print_r($c);die;
    return $this->render('drawthirdcaiwusum',['a'=>$a,'c'=>$c,'day'=>$day]);
}

优化后的方法二

    //交易量折线图
    public function actionDrawthirdcaiwusum()
    {
        if (Yii::$app->request->get("dayselect")) {
            $day = Yii::$app->request->get("dayselect");
        } else {
            $day = 7;
        }

        $rows=Yii::$app->db->createCommand("select thirdid,FROM_UNIXTIME(yocreatetime,'%Y-%m-%d') as datetime
,SUM(yototal) as money
from ibd_third_oyihuo
LEFT JOIN ibd_shop ON (ibd_third_oyihuo.yosellerid=suid)
where (ystatus = 1 or ystatus = 4) and yotype<20 
and yocreatetime>=unix_timestamp(DATE_FORMAT(subdate(now(),$day),'%Y-%m-%d'))
and yocreatetime<unix_timestamp(DATE_FORMAT(now(),'%Y-%m-%d')) 
group by thirdid,FROM_UNIXTIME(yocreatetime,'%Y-%m-%d')
ORDER BY yocreatetime desc")->query();

        $th=IbdThirdInfo::find()->all();
        $id=[];
        foreach($th as $val){
            $id[]=$val->id;
        }

        $rows = $rows->readAll();
        for ($i = $day; 0 < $i; $i--) {//time
            $result[] = date('Y-m-d', strtotime('-' . $i . ' day'));
        }

        foreach($id as $v1=>$thirdid){//第三方id
            foreach($result as $value =>$item){ //日期
                $isexit=0;  //0表示不存在  1表示存在
                foreach( $rows as  $f =>$v){    //数据
                    if($item==$v['datetime']&&$thirdid==$v['thirdid']){
                        ${'money'.$v['thirdid']}[]=sprintf("%.2f",$v['money']/100);
                        $isexit=1;
                        break;
                    }
                }
                if(!$isexit){
                    ${'money'.$thirdid}[]=0;
                }
            }
        }

        function my_json_decode($str) {
            $str = preg_replace('/"(\w+)"(\s*:\s*)/is', '$1$2', $str);   //去掉key的双引号
            return $str;
        }
        $color = array("#EE0000","#00FFFF","#712704","#43A102","#049FF1","#FFA500","#4C4C4C","#00CCFF","#72CFD7","#FF8C05");
        $res= array();

        foreach($id as $vv){
            $fileinfo['label'] = IbdThirdInfo::findOne(['id'=>$vv])->name;
            $fileinfo['fill'] = true;
            $fileinfo['borderColor'] = $color[$vv%10];
            $fileinfo['pointBackgroundColor'] = "#fff";
            $fileinfo['data'] = ${'money'.$vv};
            array_push($res, $fileinfo);
        }
        $a = json_encode($result);
        $c = my_json_decode(json_encode($res));
//        print_r($c);die;
        return $this->render('drawthirdcaiwusum',['a'=>$a,'c'=>$c,'day'=>$day]);
    }

再次优化

        $th=IbdThirdInfo::find()->all();
        $id=[];
        foreach($th as $val){
            $id[]=$val->id;
        }

        $rows = $rows->readAll();
        for ($i = $day; 0 < $i; $i--) {//time
            $result[] = date('Y-m-d', strtotime('-' . $i . ' day'));
            $data[] = 0;
        }

//        foreach($id as $v1=>$thirdid){//第三方id
//            foreach($result as $value =>$item){ //日期
//                $isexit=0;  //0表示不存在  1表示存在
//                foreach( $rows as  $f =>$v){    //数据
//                    if($item==$v['datetime']&&$thirdid==$v['thirdid']){
//                        ${'money'.$v['thirdid']}[]=sprintf("%.2f",$v['money']/100);
//                        $isexit=1;
//                        break;
//                    }
//                }
//                if(!$isexit){
//                    ${'money'.$thirdid}[]=0;
//                }
//            }
//        }
        foreach($th as $v1=>$thirdid){//第三方id
            ${'money'.$thirdid->id} = $data;

        }
        foreach( $rows as  $f =>$v){    //数据
                $index  = array_search($v['datetime'],$result);
                ${'money'.$v['thirdid']}[$index]=sprintf("%.2f",$v['money']/100);
        }

时间复杂度优化

    //交易量折线图
    public function actionDrawthirdcaiwusum()
    {
        if (Yii::$app->request->get("dayselect")) {
            $day = Yii::$app->request->get("dayselect");
        } else {
            $day = 7;
        }

        $rows=Yii::$app->db->createCommand("select thirdid,FROM_UNIXTIME(yocreatetime,'%Y-%m-%d') as datetime
,SUM(yototal) as money
from ibd_third_oyihuo
LEFT JOIN ibd_shop ON (ibd_third_oyihuo.yosellerid=suid)
where (ystatus = 1 or ystatus = 4) and yotype<20 
and yocreatetime>=unix_timestamp(DATE_FORMAT(subdate(now(),$day),'%Y-%m-%d'))
and yocreatetime<unix_timestamp(DATE_FORMAT(now(),'%Y-%m-%d')) 
group by thirdid,FROM_UNIXTIME(yocreatetime,'%Y-%m-%d')
ORDER BY yocreatetime desc")->query();

        $th=IbdThirdInfo::find()->all();
        $id=[];
        foreach($th as $val){
            $id[]=$val->id;
        }

        $rows = $rows->readAll();
        for ($i = $day; 0 < $i; $i--) {//time
            $result[] = date('Y-m-d', strtotime('-' . $i . ' day'));
            $data[] = 0;
        }

//        foreach($id as $v1=>$thirdid){//第三方id
//            foreach($result as $value =>$item){ //日期
//                $isexit=0;  //0表示不存在  1表示存在
//                foreach( $rows as  $f =>$v){    //数据
//                    if($item==$v['datetime']&&$thirdid==$v['thirdid']){
//                        ${'money'.$v['thirdid']}[]=sprintf("%.2f",$v['money']/100);
//                        $isexit=1;
//                        break;
//                    }
//                }
//                if(!$isexit){
//                    ${'money'.$thirdid}[]=0;
//                }
//            }
//        }
        foreach($th as $v1=>$thirdid){//第三方id
            ${'money'.$thirdid->id} = $data;
        }
        foreach( $rows as  $f =>$v){    //数据
                $index  = array_search($v['datetime'],$result);
                ${'money'.$v['thirdid']}[$index]=sprintf("%.2f",$v['money']/100);
        }

        function my_json_decode($str) {
            $str = preg_replace('/"(\w+)"(\s*:\s*)/is', '$1$2', $str);   //去掉key的双引号
            return $str;
        }
        $color = array("#EE0000","#00FFFF","#712704","#43A102","#049FF1","#FFA500","#4C4C4C","#00CCFF","#72CFD7","#FF8C05");
        $res= array();

        foreach($id as $vv){
            $fileinfo['label'] = IbdThirdInfo::findOne(['id'=>$vv])->name;
            $fileinfo['fill'] = true;
            $fileinfo['borderColor'] = $color[$vv%10];
            $fileinfo['pointBackgroundColor'] = "#fff";
            $fileinfo['data'] = ${'money'.$vv};
            array_push($res, $fileinfo);
        }
        $a = json_encode($result);
        $c = my_json_decode(json_encode($res));
//        print_r($c);die;
        return $this->render('drawthirdcaiwusum',['a'=>$a,'c'=>$c,'day'=>$day]);
    }

EX1

EX1成果图:

1534411205(1).png
1534411214(1).png

EX1 html

<?php
use yii\widgets\LinkPager;

?>
<script type="text/javascript" src="/common/lib/layer.ext.js"></script>
<script src="/common/lib/admin/js/bootstrap.min.js"></script>
<script src="/common/lib/admin/js/chart.min.js"></script>
<script>

    function datacount(){
        window.location.href = '/guest/account/account-yihuo';
    }
    function search(){
        window.location.href="/guest/account/caiwusum?dayselect="+$("#dayselect").val();
    }

</script>

<div id="page-inner" style="padding: 30px;">
    <div class="row">
        <div class="col-md-12">
            <h1 class="page-header">
                财务统计图表
            </h1>
        </div>
        <div class="panel-body">
            <div class="dataTables_wrapper form-inline" style="margin-bottom: 15px;">
                <select class="btn btn-default btn-sm" id="dayselect">
                    <option value = "7" <?= $day == 7?'selected' : ''?>>近7天</option>
                    <option value = "30" <?= $day == 30?'selected' : ''?>>近30天</option>
                </select>
                &nbsp;&nbsp;
                <button class="btn btn-default btn-sm" onclick="search()" title="点击搜索"><i class="fa fa-search"></i>&nbsp;&nbsp;<b>Search</b></button>
                &nbsp;&nbsp;
                <button id="drawdatacount" onclick="datacount()" class="btn btn-sm btn-info">易货账务表格显示</button>
            </div>


        </div>

        <div class="container">
            <div class="row">
                <div class="col-xs-2 "><canvas id="myChart"></canvas></div>
                <div class="col-xs-8 "><canvas id="myChart1"></canvas></div>
            </div>
        </div>
    </div>
</div>

<script>

    var ctx = document.getElementById("myChart1");
    var myChart = new Chart(ctx, {
        type: 'line', // line 表示是 曲线图,当然也可以设置其他的图表类型 如柱形图 : bar  或者其他
        data: {
            labels : <?=$a?>, //按时间段 可以按星期,按月,按年
            datasets : [
                {
                    label: "交易量(元)",  //当前数据的说明
                    fill: true,  //是否要显示数据部分阴影面积块  false:不显示
                    borderColor: "#36A2EB",//数据曲线颜色
                    pointBackgroundColor: "#fff", //数据点的颜色
                    data: <?=$b?>,  //填充的数据
                },
                {
                    label: "总后台佣金(元)",  //当前数据的说明
                    fill: true,  //是否要显示数据部分阴影面积块  false:不显示
                    borderColor: "#EE0000",//数据曲线颜色
                    pointBackgroundColor: "#fff", //数据点的颜色
                    data: <?=$c?>,  //填充的数据
                }
            ]
        }
    });
</script>

EX1Collecter

    //财务折线图
    public function actionCaiwusum()
    {
        if (Yii::$app->request->get("dayselect")) {
            $day = Yii::$app->request->get("dayselect");
        } else {
            $day = 7;
        }

        $rows=Yii::$app->db->createCommand("select FROM_UNIXTIME(yocreatetime,'%Y-%m-%d') as datetime
,SUM(yototal) as money,SUM(yadminmoney) as commission
from ibd_oyihuo 
where (ystatus = 1 or ystatus = 4) and yotype<20 
and yocreatetime>=unix_timestamp(DATE_FORMAT(subdate(now(),$day),'%Y-%m-%d'))
and yocreatetime<unix_timestamp(DATE_FORMAT(now(),'%Y-%m-%d')) 
group by FROM_UNIXTIME(yocreatetime,'%Y-%m-%d')
ORDER BY yocreatetime desc")->query();

        for ($i = $day; 0 < $i; $i--) {
            $result[] = date('Y-m-d', strtotime('-' . $i . ' day'));
            $money[] = 0;
            $commission[] = 0;
        }

        foreach($rows as $k => $v){
            foreach($result as $value =>$item){
                $index = array_search($v['datetime'],$result);
                $money[$index] = sprintf("%.2f",$v['money']/100);
                $commission[$index] = sprintf("%.2f",$v['commission']/100);
            }
        }
        $a = json_encode($result);
        $b = json_encode($money);
        $c = json_encode($commission);
        return $this->render('drawcaiwusum',['a'=>$a,'b'=>$b,'c'=>$c,'day'=>$day]);
    }

主要要点:

1.php+mysql统计最近30天空值补0

1534411492(1).png

以EX1为例,2018/8/9号后数据为空,使用sql group by需要补0,网上有一种思路是leftjoin一张时间表数据默认为0。
查找最近的几天可以直接构建一个数组

for ($i = $day; 0 < $i; $i--) {//设定日期循环
            $result[] = date('Y-m-d', strtotime('-' . $i . ' day'));//初始化时间,每次减1天
            $money[] = 0;//初始化金额为0
            $commission[] = 0;
        }

然后,for循环取出从数据库拿到的数据,查找时间找出数组的位置,赋值给之前初始化为0的数组

        foreach($rows as $k => $v){
            foreach($result as $value =>$item){
                $index = array_search($v['datetime'],$result);
                $money[$index] = sprintf("%.2f",$v['money']/100);
                $commission[$index] = sprintf("%.2f",$v['commission']/100);
            }
        }

这里写的有问题,首先$result是完整时间包含$rows从数据库找出的时间,应该调换过来,但会报错'DataReader cannot rewind. It is a forward-only reader.'要使用$rows = $rows->readAll();等填坑

       $rows = $rows->readAll();
       foreach($result as $value =>$item){
           foreach($rows as $k => $v){
               $index = array_search($v['datetime'],$result);
               $money[$index] = sprintf("%.2f",$v['money']/100);
               $commission[$index] = sprintf("%.2f",$v['commission']/100);
           }
       }

这样写也是没问题的。
后面传json给view就行了。

2.按第三方数量画折线

首先看chart.js的方法

datasets : [
                {
                    label: "交易量(元)",  //当前数据的说明
                    fill: true,  //是否要显示数据部分阴影面积块  false:不显示
                    borderColor: "#36A2EB",//数据曲线颜色
                    pointBackgroundColor: "#fff", //数据点的颜色
                    data: <?=$b?>,  //填充的数据
                },
                {
                    label: "总后台佣金(元)",  //当前数据的说明
                    fill: true,  //是否要显示数据部分阴影面积块  false:不显示
                    borderColor: "#EE0000",//数据曲线颜色
                    pointBackgroundColor: "#fff", //数据点的颜色
                    data: <?=$c?>,  //填充的数据
                }
            ]

思路:循环构建数组,转为json后,去掉key的双引号
其中变量名的递增可用用:${'money'.$vv}

        function my_json_decode($str) {
            $str = preg_replace('/"(\w+)"(\s*:\s*)/is', '$1$2', $str);   //去掉key的双引号
            return $str;
        }
        $color = array("#EE0000","#00FFFF","#712704","#43A102","#049FF1","#FFA500","#4C4C4C","#00CCFF","#72CFD7","#FF8C05");
        $res= array();

        foreach($id as $vv){
            $fileinfo['label'] = IbdThirdInfo::findOne(['id'=>$vv])->name;
            $fileinfo['fill'] = true;
            $fileinfo['borderColor'] = $color[$vv%10];
            $fileinfo['pointBackgroundColor'] = "#fff";
            $fileinfo['data'] = ${'money'.$vv};
            array_push($res, $fileinfo);
        }
        $a = json_encode($result);
        $c = my_json_decode(json_encode($res));

html里直接输出

datasets : <?=$c?>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容

  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明先生_X自主阅读 15,969评论 3 119
  • 世界杯就这样如约而至,一群人聚到一起深夜狂欢,他们为射进球门而狂喜,为截球成功而懊恼。作为一个从不看世界杯的...
    云柠阅读 557评论 0 0
  • 在我激动的数落完妈妈后,她动了动嘴唇,最终还是沉默了,不再言语,过了一会,她扭过头,时不时说一些无关的话,...
    西西小1007阅读 198评论 0 1
  • 回想以前祖国的壮大发展,从甲骨文到现在我们手中的汉字,经历了很多改变,每当想起了这件事,我就会无比敬佩我们的祖...
    yangkailun阅读 375评论 0 0
  • 图文|知乎者野 “我是一个勤奋的人,只是对现在做的不感兴趣,所以现在搞得一团糟。” 这种论调是不是感到很耳熟呢? ...
    知乎者野阅读 522评论 0 7