• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

php+ajax 实现无限树列表

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

首先介绍我实现的是xhprof插件的日志转为无限树状图,先看效果图:

废话不多说,直接看代码:(辛辛苦苦敲了好久才搞定,逻辑比较多,新手多揣摩)

控制器:

<?php

namespace Admin\Controller;

class XhprofController extends AdminbaseController
{
    function _initialize()
    {
        parent::_initialize();
    }

    //获取当前文件目录
    public function index()
    {
        $file = scandir("./public/xhprof");
        $str = ".xhprof";
        foreach ($file as $value) {
            if (preg_replace("/($str)/", "", $value) != $value) {
                $dir[] = $value;
            }
        }
        $this->assign("dir", $dir);
        $this->display();
    }

    //获取适当的结构
    public function tree($file_name)
    {
        $file_path = "./public/xhprof/$file_name";
        $file_name = str_replace('.', '', $file_name);
        if (F($file_name)) {
            $mainTree = F($file_name);
        } else {
            if (file_exists($file_path)) {
                $fp = fopen($file_path, "r");
                $str = fread($fp, filesize($file_path));//指定读取大小,这里把整个文件内容读取出来
                $array = json_decode($str, true);
                $array_keys = array_keys($array);
                //按照调用者整理数据
                $calls = [];
                foreach ($array_keys as $array_key) {
                    $caller = explode("==>", $array_key)[0];
                    $beCall = explode("==>", $array_key)[1];
                    if (!$calls[$caller]) {
                        $calls[$caller] = [
                            "caller" => $caller,
                            "beCalls" => []
                        ];
                    }
                    $status = 0;//是否有子目录
                    foreach ($array_keys as $keyv) {
                        if (strpos($keyv, $beCall . '==>') !== false && strpos($keyv, "@") === false && $beCall !== null && $beCall !== "count") {
                            $status = 1;
                        }
                    }
                    if ($beCall !== null) {
                        $calls[$caller]['beCalls'][] = array('name' => $beCall, "status" => $status, 'data' => $array[$array_key]);
                    }
                }
                foreach ($calls as &$v) {
                    $tmpAll = 0;
                    foreach ($v['beCalls'] as $vv) {
                        $tmpAll += $vv['data']['wt'];
                    }
                    foreach ($v['beCalls'] as &$vv1) {
                        $vv1['data']['wtp'] = round($vv1['data']['wt'] * 100 / $tmpAll, 2);
                        $vv1['wtp'] = $vv1['data']['wt'];
                    }
                }
                $mainTree = $calls;
                //缓存$mainTree
                F($file_name, $mainTree);
            } else {
                $mainTree = "";
            }
        }
        array_multisort(array_column($mainTree["main()"]["beCalls"], "wtp"), SORT_DESC, array_column($mainTree["main()"]["beCalls"], "name"), SORT_DESC, $mainTree["main()"]["beCalls"]);
        $this->assign("main", $array["main()"]);
        $this->assign("mainTree", $mainTree["main()"]);
        $this->assign("level", 1);
        $this->assign("file_name", $file_name);
        $this->assign("file_path", $file_path);
        $this->display();
    }

    public function ajax()
    {
        $note = htmlspecialchars_decode(I("post.note"));
        $file_name = htmlspecialchars_decode(I("post.file_name"));
        $file_path = htmlspecialchars_decode(I("post.file_path"));
        //处理$mainTree
        if (F($file_name)) {
            $mainTree = F($file_name);
        } else {
            if (file_exists($file_path)) {
                $fp = fopen($file_path, "r");
                $str = fread($fp, filesize($file_path));//指定读取大小,这里把整个文件内容读取出来
                $array = json_decode($str, true);
                $array_keys = array_keys($array);
                //按照调用者整理数据
                $calls = [];
                foreach ($array_keys as $array_key) {
                    $caller = explode("==>", $array_key)[0];
                    $beCall = explode("==>", $array_key)[1];
                    if (!$calls[$caller]) {
                        $calls[$caller] = [
                            "caller" => $caller,
                            "beCalls" => []
                        ];
                    }
                    $status = 0;//是否有子目录
                    foreach ($array_keys as $keyv) {
                        if (strpos($keyv, $beCall . '==>') !== false && strpos($keyv, "@") === false && $beCall !== null && $beCall !== "count") {
                            $status = 1;
                        }
                    }
                    if ($beCall !== null) {
                        $calls[$caller]['beCalls'][] = array('name' => $beCall, "status" => $status, 'data' => $array[$array_key]);
                    }
                }
                foreach ($calls as &$v) {
                    $tmpAll = 0;
                    foreach ($v['beCalls'] as $vv) {
                        $tmpAll += $vv['data']['wt'];
                    }
                    foreach ($v['beCalls'] as &$vv1) {
                        $vv1['data']['wtp'] = round($vv1['data']['wt'] * 100 / $tmpAll, 2);
                        $vv1['wtp'] = $vv1['data']['wt'];
                    }
                }
                $mainTree = $calls;
                //缓存$mainTree
                F($file_name, $mainTree);
            } else {
                $mainTree = "";
            }
        }
        array_multisort(array_column($mainTree[$note]["beCalls"], "wtp"), SORT_DESC, array_column($mainTree[$note]["beCalls"], "name"), SORT_DESC, $mainTree[$note]["beCalls"]);
        $this->ajaxReturn($mainTree[$note]);
    }


}





veiw界面:

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>Xhprof数据分析</title>
    <link rel="stylesheet" type="text/css" href="__TMPL__Public/assets/css/bootstrap.min.css"/>
    <link rel="stylesheet" type="text/css" href="__TMPL__Public/assets/css/xhprof.css"/>
    <script type="text/javascript" src="__PUBLIC__/js/jquery.js"></script>
</head>
<body>
<div class="tree well">
    <ul>
        <li>
            <span class="main">
                <i class='icon-minus'> </i>  <b class="name">main()</b>
                            第<b>&nbsp;1&nbsp;</b>级&emsp;&emsp;&emsp;
                            ct:<b class="bw">{$main.ct}</b>
                            wt:<b class="red" >{$main.wt} (100%)</b>
                            cpu:<b class="bw">{$main.cpu}</b>
                            mu:<b class="bw">{$main.mu}</b>
                            pmu:<b class="bw">{$main.pmu}</b>
            </span>
            <foreach name="mainTree['beCalls']" item="vo">
                <ul>
                    <li class='parent_li'>
                        <span title='Collapse this branch' note="{$vo.name}" level="2" file_name={$file_name} file_path={$file_path}>
                             <if condition="$vo['status']==1">
                                 <i class="icon-plus"></i>
                                 <else/>
                                 <b style='width:14px;display: inline-block;'></b>
                             </if>
                            <div style="display: inline-block;">
                             <b class="name" title={$vo.name}>{$vo.name}</b>
                             第<b>&nbsp;2&nbsp;</b>级&emsp;&emsp;&emsp;
                             ct:<b class="ct">{$vo.data.ct}</b>
                             <if condition="$vo['data']['wtp'] gt 10">
                                 wt:<b class="red">{$vo.data.wt} ({$vo.data.wtp|round=2}%)</b>
                                 <else/>
                                 wt:<b class="wt" style="display: inline-block;min-width: 150px;">{$vo.data.wt} ({$vo.data.wtp|round=2}%)</b>
                             </if>
                            cpu:<b class="bw">{$vo.data.cpu}</b>
                            mu:<b class="bw">{$vo.data.mu}</b>
                            pmu:<b class="bw">{$vo.data.pmu}</b>
                            </div>
                        </span>
                    </li>
                </ul>
            </foreach>
        </li>
    </ul>
</div>
</body>
<script>
    $(function () {
        $('.tree li:has(ul)').addClass('parent_li').find(' > span').attr('title', 'Collapse this branch');
        $('body').on('click', "span", function (e) {
            e.stopPropagation();
            if ($(this).attr('is_click') === 1) {
                return false;
            }
            $(this).attr('is_click', 1);
            var children = $(this).parent('li.parent_li').find(' > ul > li');
            if (children.is(":visible")) {
                children.hide('fast');
                $(this).attr('title', 'Expand this branch').find(' > i').addClass('icon-plus').removeClass('icon-minus');
                $(this).attr('is_click', 0);
            } else {
                children.show('fast');
                $(this).attr('title', 'Collapse this branch').find(' > i').addClass('icon-minus').removeClass('icon-plus');
                if ($(this).hasClass('main')) {
                    $(this).attr('is_click', 0);
                    return;
                }
                if (!$(this).siblings('.child').length) {
                    do_ajax($(this));
                } else {
                    $(this).attr('is_click', 0);
                }
            }
        });

        function do_ajax(e) {
            var note_js = e.attr('note');
            var level_js = e.attr('level');
            var file_name_js = e.attr('file_name');
            var file_path_js = e.attr('file_path');
            $.ajax({
                type: "post",
                cache: false,
                dataType: "json",
                url: "{:U('Admin/Xhprof/ajax')}",
                data: {
                    note: note_js,
                    level: level_js,
                    file_name: file_name_js,
                    file_path: file_path_js
                },
                success: function (data) {
                    if (data.beCalls !== null) {
                        var str = "";
                        for (var i = 0; i < data.beCalls.length; i++) {
                            str += "<ul class='child'>";
                            str += "<li class='parent_li'>";
                            str += "<span title='Collapse this branch' class='load'   note=" + data.beCalls[i].name + " level= " + eval(Number(level_js) + 1) + " file_name= " + file_name_js + " file_path= " + file_path_js + ">";
                            if (data.beCalls[i].status == 1) {
                                str += "<i  class='icon-plus' ></i>";
                            } else {
                                str += "<b style='width:14px;display: inline-block;'> </b>";
                            }
                            str += "<b class='name' title="+ data.beCalls[i].name + ">" + data.beCalls[i].name + '</b>第<b>&nbsp;' + eval(Number(level_js) + 1) + "</b>&nbsp;级&emsp;&emsp;&emsp;ct:<b class='ct'>" + data.beCalls[i].data.ct + "</b>  wt:<b  class= " + (data.beCalls[i].data.wtp < 10 ? 'wt' : 'red') + " >" + data.beCalls[i].data.wt + "(" + data.beCalls[i].data.wtp + "%)</b>  cpu:<b class='bw' >" + data.beCalls[i].data.cpu + "</b>  mu:<b class='bw'>" + data.beCalls[i].data.mu + "</b>   pmu:<b class='bw'>" + data.beCalls[i].data.pmu + "</b></span>";
                            str += '</li>';
                            str += '</ul>';
                        }
                        e.siblings('.child').remove();
                        e.after(str);
                        e.attr('is_click', 0);
                    }
                },
                error: function () {
                }
            })
        }
    });
</script>
</html>

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
php分割中文字符串为数组的简单例子发布时间:2022-07-10
下一篇:
二,PHP会话机制---session的基本使用发布时间:2022-07-10
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap