Jamers Posted November 26, 2015 Report Share Posted November 26, 2015 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 More sharing options...
Recommended Posts
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now