Jump to content
新域网络技术论坛

echarts数据PHP生成类


Jamers
 Share

Recommended Posts

ECharts,缩写来自Enterprise Charts,商业级数据图表,一个纯Javascript的图表库,可以流畅的运行在PC和移动设备上,兼容当前绝大部分浏览器(IE6/7/8/9/10/11,chrome,firefox,Safari等),底层依赖轻量级的Canvas类库ZRender,提供直观,生动,可交互,可高度个性化定制的数据可视化图表。创新的拖拽重计算、数据视图、值域漫游等特性大大增强了用户体验,赋予了用户对数据进行挖掘、整合的能力。

支持折线图(区域图)、柱状图(条状图)、散点图(气泡图)、K线图、饼图(环形图)、雷达图(填充雷达图)、和弦图、力导向布局图、地图、仪表盘、漏斗图、事件河流图等12类图表,同时提供标题,详情气泡、图例、值域、数据区域、时间轴、工具箱等7个可交互组件,支持多图表、组件的联动和混搭展现。

 

由于它功能强大,生成的图表可以用惊艳来形容,无奈数据项太多,无法用程序完全生成option配置串,所以我写了这个模块直接把图表数据作为参数传入,并配置扩展设置 $opt,生成图表的类型三个参数传进去,就能得到option配置串,你安全可以生成出来后直接到网站进行预览,看是否配置正确。这里说明一下color模块是我写的一个自动生成多种颜色的模块,不是必须的,可以将这个去掉。$opt参数为扩展设置数组,具体请参照示例和官方网站的说明,大概思路就是option串里就是一个数组,自己设置键值和内容。

包括原先的思路也在类代码中特意没有删除,可以供参考。

 

DEMO代码如下:

<?php
 include_once('cls_echarts.php');
 
 //$dary = array('N1'=>array('D1'=>100,'D2'=>129,'D3'=>150,'D4'=>89),'D1'=>array('D2'=>87,'D1'=>103,'D3'=>201,'D4'=>99));
 
 //$dary = array('N1'=>array('D1'=>100,'D2'=>129,'D3'=>150,'D4'=>89),'D1'=>array('D2'=>87,'D1'=>103,'D3'=>201,'D4'=>99),'X1'=>array('D1'=>100,'D2'=>200,'D3'=>150,'D4'=>190),'Y1'=>array('D1'=>99,'D2'=>80,'D3'=>88,'D4'=>100));
 $dary = array('Num1'=>500,'Num2'=>300,'Label1'=>134,'Label2'=>338,'laebl3'=>115);
 $opt = array('series'=>array('radius'=>array('50%','70%')));
 echo "<pre>";
 echo (echarts::build_option($dary,$opt,'pie'));
 echo "</pre>";
  
?>

<?php
/**
* @see color
*/
include_once('cls_color.php');

/**
* 生成echart图标的option参数,用以显示图形化数据
* @example  
 include_once('cls_echarts.php');
 
 //$dary = array('N1'=>array('D1'=>100,'D2'=>129,'D3'=>150,'D4'=>89),'D1'=>array('D2'=>87,'D1'=>103,'D3'=>201,'D4'=>99));
 $dary = array('Num1'=>500,'Num2'=>300,'Label1'=>134,'Label2'=>338,'laebl3'=>115);
 $opt = array('series'=>array('radius'=>array('50%','70%')));
 echo "<pre>";
 echo (echarts::build_option($dary,$opt,'pie'));
 echo "</pre>";
* 
* @author Jamers 2015.11.26
* @since 1.0.0 初版完成 2015.11.26
*/
class echarts {
    /**
    * 默认option数据数组
    * 
    * @var array
    */
    static $def = array(
        'tooltip' => array('trigger'=>'axis'),
        'calculable' => true,
    );
    /**
    * echarts图表类型遍历 值为magicType值
    * 
    * @var mixed
    */
    static $type = array(
        'line'=>'line,bar', //折线图
        'bar'=>'line,bar',  //柱形图
        'scatter' => '',    //散点图
        'k' => '',          //K线图
        'pie' => 'pie,funnel',//饼图
        'radar' => '',      //雷达图
        'chord' => 'force,chord',    //和弦图
        'force' => 'force,chord',    //力导向图
        'map'   =>  '',     //地图
        'gauge' =>  '',     //仪表盘
        'funnel'=>  '',     //漏斗图
        'heatmap' => '',    //热力图
        'eventRiver'  =>  '',     //事件河流图
        'venn'      => '',  //韦恩图
        'treemap'   =>  '', //矩形图
        'tree'      =>  '', //树图
        'wordCloud' =>  '', //字符云
    );

    /**
    * 单组数据类型
    * 
    * @var array
    */
    static $single = array('pie','funnel','venn','treemap','map');
    
    /**
    * 需要添加花括号的键值
    * 
    * @var mixed
    */
    static $na = array('value');

    /**
    * 需要添加方括号的键值
    * 
    * @var mixed
    */
    static $ab = array('series');
    
    /**
    * 默认toolbox样式
    * 
    * @var mixed
    */
    static $toolbox = array( 'toolbox' =>
        array(
            'show' => true,
            'feature' => array(
                'mark' => array('show'=>true,),
                'dataView' => array('show'=>true,'readOnly'=>false),
                'restore' => array('show'=>true),
                'saveAsImage' => array('show'=>true),
            ),
        )
    );
    
    /**
    * 需要使用中括号隔离的字段([])
    * 默认使用花括号({})
    * @since 2015.11.26 启用新算法,此处作废
    * 
    * @var mixed
    */
    //static $bracket = array('data'=>'','series'=>'','xAxis'=>'','yAxis'=>'','center'=>'','color'=>'','type'=>'magicType');
    /**
    * 需要添加花括号的字段
    * @since 2015.11.26 启用新算法,此处作废
    * 
    * @var array
    */
    //static $abracket = array('xAxis','yAxis');
    /**
    * 实在没办法规避,用死方法,直接不加引号
    * @since 2015.11.26 启用新算法,此处作废
    * 
    * @var array
    */
    //static $nquote = array('series');
    
    /**
    * 生成图表数据
    * 
    * @param mixed $dary    数据数组 标题=>数值
    * @param boolean $single 单一数组(True饼图,False折线图)
    * 
    * @example $dary = array('Num1'=>500,'Num2'=>300,'Label1'=>134,'Label2'=>338,'laebl3'=>115);
    * @example $dary = array('N1'=>array('D1'=>100,'D2'=>129,'D3'=>150,'D4'=>89),'D1'=>array('D2'=>87,'D1'=>103,'D3'=>201,'D4'=>99));
    * @return array
    */
    static function general_data($dary,$single=true) {
        $c  = color::general_hex_color(count($dary));
        $o   =  $l  = array();

        $l = array_keys($dary);     //图例数组
        //图例标题
        if ($single) {
            //单组数据

            foreach($dary as $k=>$v) {
                //$o[] = "{value:{$v}, name:'{$k}'}";
                $o[] = array('value'=>$v,'name'=>$k);
            }
            return array('l'=>$l,'d'=>$o,'c'=>$c);
        }else{
            //多组数据
            $x  = array();
            $y  = array();
            foreach ($dary as $k => $v) {
                foreach ($v as $m => $n) {
                    if (!isset($x[$m])) $x[$m] = $m;
                    $y[$k][$m] = $n;
                }
            }
            $o = array();
            foreach ($y as $k => $v) {
                foreach ($x as $m => $n) {
                    $o[$k][$m] = $y[$k][$m];
                }
            }
            
            $yy = array();
            foreach($o as $k=>$v) {
                //$yy[$k]='['.implode(',',$v).']';
                $yy[$k] = array_values($v);
            }
            return array(
                'c'=>$c,
                'l' => $l,
                'x' => array_values($x),
                'y' => $yy,
            );
        }
    }
    
    /**
    * 数组内容中增加引号方便implode
    * 
    * @param mixed $ary
    */
    static function addquote($ary) {
        $r = array();
        foreach ($ary as $k => $v) {
            $r[$k] = "'{$v}'";
        }
        return $r;
    }


    /**
    * 新的数组构造函数,原build_array停用 2015.11.25
    * 
    * @param array $data    数据数组
    * @param boolean $addkey    是否增加主键,暂时未使用
    * @param int $dep       数组深度
    */
    static function build_data($data,$addkey=true,$dep=0) {
        $havekeys = false;
        $r = array();
        if (is_array($data)) {
            foreach ($data as $k=>$v) {
                $a1='{';$a2='}';
                $keys = (is_numeric($k)||!$addkey?'':"{$k}:");
                //非字母数字添加双引号
                preg_match('%[^a-z0-9/\\\\\s\t]*%i',$k,$x);
                //var_dump($x);
                if ($keys && $x[0]) $keys = '"'.$k.'":';
                //TODO: 中文keys要加双引号未处理  geoCoord
                if (!$havekeys && $keys) $havekeys = true;
                $t = '';
                if (is_array($v)) {
                    $b1=$b2='';
                    if (!is_numeric($k) && in_array($k,self::$na)) {$a1='[';$a2=']';$b1='{';$b2='}';}
                    //if (!is_numeric($k)&& in_array($k,self::$ab)) {
                    //    $DAT = self::build_data(array_values($v),$addkey,$dep+1);
                    //}else{
                        $DAT = self::build_data($v,$addkey,$dep+1);
                    //}
                    //var_dump($DATA);
                    if ((!$DAT['k'])) {$a1='[';$a2=']';}
                    if (!is_numeric($k)&& in_array($k,self::$ab)) {$a1 = ($a1=='['?$a1:'['.$a1);$a2 = ($a2==']'?$a2:$a2.']');}
                    $t1 = "{$b1}{$keys}{$a1}".$DAT['d']."{$a2}{$b2}";
                    //echo $t1;
                    $r[] = $t1;
                }else if (is_bool($v)) {
                    if ($v) {
                        $t = 'true';
                    }else{
                        $t = 'false';
                    }
                }else if (is_string($v)) {
                    $t = "'{$v}'";
                }else{
                    $t = $v;
                }
                if ($t) $r[] = "{$keys}{$t}";
            }
        }
        if ($dep>0) {
            $a1='';$a2='';
        }else{
            $a1='[';$a2=']';
        }
        if ($dep==0) {
            $a1='{';$a2='}';
            return $a1.implode(',',$r).$a2;
        }else{
            if (!$data) $havekeys = true;
            return array('d'=>$a1.implode(',',$r).$a2,'k'=>$havekeys);
        }
    }
    
    /**
    * 将数组编译成js结构
    * 
    * @param mixed $ary
    * @param boolean $addkey 是否添加主键
    * @param string $par    父键
    */
/*    static function build_array($ary,$addkey=true,$par='') {
        $r = array();
        if (is_array($ary)) {
            foreach ($ary as $k=>$v) {
                $addkey = ($addkey && (!is_numeric($k)));
                $keys = ($addkey?"{$k}:":"");
                if (is_array($v)) {
                    if (array_key_exists($k,self::$bracket)) {
                        $a1 = $a2 = '';
                        //if ($k=='series') var_dump($v);
                        if (in_array($k,self::$abracket) || (isset($v['type']) && isset($v['data']))) {
                            $a1 = '{';$a2='}';
                        }
                        $r[] = "{$keys}[{$a1}".self::build_array($v,$addkey,$k)."{$a2}]";
                    }else{
                        $r[] = "{$keys}{".self::build_array($v,$addkey,$k)."}";
                    }
                }else{
                    if (is_bool($v)) {
                        if ($v) {
                            $t = 'true';
                        }else{
                            $t = 'false';
                        }
                    } else if (is_string($v)) {
                        $nb = true;
                        if (in_array($par,self::$nquote)) $nb = false;
                        //if ((array_key_exists($k,self::$bracket))||(array_key_exists($par,self::$bracket))) {
                        if ((array_key_exists($k,self::$bracket))) {
                        //if ((array_key_exists($k,self::$bracket))) {
                            //echo "par:{$par},k:{$k},bracket:".self::$bracket[$k]."<br>\r\n";
                            if (isset(self::$bracket[$par])&&(!self::$bracket[$par])&&(!self::$bracket[$k])) {
                                $nb = false;
                            }else if ($par==self::$bracket[$k]) {
                                $nb = false;
                            }else{
                                $nb = true;
                            }
                        }
                        if ($nb) {
                            $t = "'{$v}'";
                        }else{
                            $t = $v;
                        }
                    }else {
                        $t = $v;
                    }
                    $r[] = "{$keys}{$t}";
                }
            }
            return implode(',',$r);
        }
        return '';
    }
*/    
    /**
    * 生成option配置串
    * 
    * @param mixed $data
    * @param array $opt     自定义值,合并进最终option
    * @param string $type 图表类型
    */
    static function build_option($data,$opt=array(),$type='bar') {
        //如果无类型默认BAR
        if (!isset(self::$type[$type])) $type='bar';
        //$opt = array_merge_recursive($data,self::$def);
        $box = self::$toolbox;
        if (self::$type[$type]) {
            //有magictype设置
            $mt = explode(',',self::$type[$type]);
/*            $tt = array();
            foreach ($mt as $v) {
                $tt[] = "'{$v}'";
            }*/
            //$box['toolbox']['feature']['magicType'] = array('show'=>true,'type'=>'['.implode(',',$tt).']',
            $box['toolbox']['feature']['magicType'] = array('show'=>true,'type'=>$mt,
                                                            'option'=>array('funnel'=>array('x'=>'25%','width'=>'50%','funnelAlign'=>'left','max'=>1548))
            );
        }
        //$opt = array_merge_recursive($opt,$box);
        $s = (in_array($type,self::$single)?true:false);
        //if ($s) $box['tooltip']['trigger']='item';
        //var_dump($type);
        //Todo: 单数据还是复杂数据
        $d = self::general_data($data,$s);
        
        $a = array(
            'color' => $d['c'],
            'legend' => array('data'=>$d['l']),
        );
        if (isset($d['x'])) {
            $a['xAxis'] = array('type'=>'category','data'=>$d['x']);
            $a['yAxis'] = array('type'=>'value');
        }
        
        $ed = array();
        if (isset($d['d'])) {
            //单组数据
            $ed['type'] = $type;
            //$ed['data'] = '['.implode(',',$d['d']).']';
            $ed['data'] = $d['d'];
        }
        if (isset($d['y'])) {
            //有多组数据
            //var_dump($d['y']);
            //$ed = $d['y'];
            foreach ($d['y'] as $k=>$v) {
                //var_dump($v);
                //$ed[] = "{name:'{$k}',type:'{$type}',data:{$v}}";
                $ed[] = array('name'=>$k,'type'=>$type,'data'=>$v);
            }
        }

        $a['series'] = $ed;
        $opt = array_merge_recursive($a,$opt,$box,self::$def);
        if ($s) {
            $opt['tooltip']['trigger']='item';
        }
        //var_dump($opt);
        //$r = "option = {".self::build_array($opt)."};";
        $r = "option = ".self::build_data($opt).";";
        return $r;
    }

}
?>

Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...