将highcharts图表与WordPress整合

  因为做了一个统计图的关系,所以用了下highcarts的图表,这是个很棒的的东西,只是不太好直接在wordpress中引用。
  如果要写一段JS代码肯定不会有多少人愿意,所以,直接用了一个短标签来实现,看起来还是很酷的。
  主要实现了两个功能,其一就是加载外部数据的配置文件,其二就是直接将配置文件写在短标签的参数中,当然这个中间也或多或少遇到了些许小坑,还好我够聪明解决了,不得不赞美下自己。先看看效果,用的是官方的例子。

highcarts 官方天气数据

图表加载中....

  整个表格加载的步骤,不用任何JS代码,当然这里将需要的js配置文件base64压缩了一下,相对来说还是略有不同的。


[charts name="highcarts 官方天气数据" cfg="eyJ0aXRsZSI6eyJ0ZXh0IjoiTW9udGhseSBBdmVyYWdlIFRlbXBlcmF0dXJlIiwieCI6LTIwfSwic3VidGl0bGUiOnsidGV4dCI6IlNvdXJjZTogV29ybGRDbGltYXRlLmNvbSIsIngiOi0yMH0sInhBeGlzIjp7ImNhdGVnb3JpZXMiOlsiSmFuIiwiRmViIiwiTWFyIiwiQXByIiwiTWF5IiwiSnVuIiwiSnVsIiwiQXVnIiwiU2VwIiwiT2N0IiwiTm92IiwiRGVjIl19LCJ5QXhpcyI6eyJ0aXRsZSI6eyJ0ZXh0IjoiVGVtcGVyYXR1cmUgKMKwQykifSwicGxvdExpbmVzIjpbeyJ2YWx1ZSI6MCwid2lkdGgiOjEsImNvbG9yIjoiIzgwODA4MCJ9XX0sInRvb2x0aXAiOnsidmFsdWVTdWZmaXgiOiLCsEMifSwibGVnZW5kIjp7ImxheW91dCI6InZlcnRpY2FsIiwiYWxpZ24iOiJyaWdodCIsInZlcnRpY2FsQWxpZ24iOiJtaWRkbGUiLCJib3JkZXJXaWR0aCI6MH0sInNlcmllcyI6W3sibmFtZSI6IlRva3lvIiwiZGF0YSI6WzcsNi45LDkuNSwxNC41LDE4LjIsMjEuNSwyNS4yLDI2LjUsMjMuMywxOC4zLDEzLjksOS42XX0seyJuYW1lIjoiTmV3IFlvcmsiLCJkYXRhIjpbLTAuMiwwLjgsNS43LDExLjMsMTcsMjIsMjQuOCwyNC4xLDIwLjEsMTQuMSw4LjYsMi41XX0seyJuYW1lIjoiQmVybGluIiwiZGF0YSI6Wy0wLjksMC42LDMuNSw4LjQsMTMuNSwxNywxOC42LDE3LjksMTQuMyw5LDMuOSwxXX0seyJuYW1lIjoiTG9uZG9uIiwiZGF0YSI6WzMuOSw0LjIsNS43LDguNSwxMS45LDE1LjIsMTcsMTYuNiwxNC4yLDEwLjMsNi42LDQuOF19XX0"][/charts]

  如何实现这样的效果呢,其一你得去http://www.highcharts.com/download下载个合适的版本,然后放在指定的地方,并且在自己的系统中添加几段这样的代码。


/**
 * 添加图表的短标签
 * @param array $attr
 * @return string
 */

function wpr_charts($attr, $content){
    /**
     * @var string $name   图表名称
     * @var string $width  DIV宽度
     * @var string $height DIV 高度
     * @var string $style  自定义样式
     * @var string $src    配置文件加载地址路径
     * @var string $cfg    Base64编码后的配置文件,需base64_decode然后json_decode,优先级比$src高
     */

    $hash = md5(serialize($attr));//计算一个唯一值
    extract(shortcode_atts(array(
        "name" => '',
        "width" => '100%',
        "height" => '',
        "style" => '',
        "src" => '',
        "cfg" => ""
    ), $attr));
    $name_p = trim(htmlspecialchars($name));
    $name_p = !empty($name_p) ? "<p class='charts_title'><strong>{$name_p}</strong></p>" : "";
    $height = is_numeric($height) ? "{$height}px" : $height;
    $height = empty($height) ? "" : ";height:{$height}";
    if(!is_single() && !is_paged()){
        return empty($name) ? $content : $name;
    }
    static $index = 0;
    if(!isset($GLOBALS['wpr_charts_map'])){
        //如果未定义图表数据则创建一个全局对象
        $GLOBALS['wpr_charts_map'] = [];
    }
    if(!empty($content)){
        $content = "<p>{$content}</p>";
    }
    $html = <<<HTML
<div class="charts_box" style="{$style}">
<div class="charts_show ChartsContainer-{$hash}" style="width: {$width}{$height}">
{$name_p}
<p class="charts_loading">图表加载中....</p>
{$content}
</div>
</div>
HTML
;
    if($index == 0){
        //初次加载,导入js文件,并添加底部执行文件
        wp_enqueue_script('highcharts', get_template_directory_uri() . '/js/highcharts.js', array('jquery'), CDN_VERSION_JS, true);
        add_action('wp_footer', function (){
            /**
             * @var array $wpr_charts_map
             */

            global $wpr_charts_map;
            if(empty($wpr_charts_map)){
                return;
            }
            $code = "";
            foreach($wpr_charts_map as $hash => $data){
                $src = $data['src'];
                $cfg = $data['cfg'];
                if(!empty($cfg)){
                    //使用自定义的配置文件
                    $cfg = base64_decode($data['cfg']);
                    $_code = <<<js
$('.ChartsContainer-{$hash}').each(function(i,elem){
    $(elem).highcharts({$cfg});
});
js
;
                } else{
                    $_code = <<<js
$.get("{$src}", function(cfg){
    $(".ChartsContainer-{$hash}").each(function(i,elem){
        $(elem).highcharts(cfg);
    });
});
js
;
                }
                if(empty($src) && empty($data['cfg'])){
                    $_code = <<<js
                        $(".ChartsContainer-{$hash}").html("<p style='color:red'>配置错误。</p>");
js
;
                }
                $code .= "if($(".ChartsContainer-{$hash}").length>0){\n{$_code}\n}";
            }
            echo "<script type='text/javascript'>jQuery(function($){
    {$code}
});</script>"
;
        });
    }
    if(!isset($GLOBALS['wpr_charts_map'][$hash])){
        //如果重复了,说明被多次解析。取最后一次
        $GLOBALS['wpr_charts_map'][$hash] = array(
            'src' => $src,
            'cfg' => $cfg
        );
    }
    $index++;
    return $html;
}

//注册下短标签
add_shortcode("charts", "wpr_charts");

  这个时候,你就可以实现部分功能,就是利用cfg文件加载配置文件,同时我实现了一种直接利用外部数据的方法,就是直接利用api获取数据并加载,当然这里是从服务器读取整个配置文件,相对于官方的例子可能有些不一样。

  第一步,来实现一个API接口,在wordpress上面,实现这一的接口还是超级简单的,如果你要求不高的话,比如下面这一段,实现一个简单的API接口。


//添加一个api页面的处理程序,这段必须放在functuions.php的最后
do_action("api_page_process", two_heart_api_url());

//注册几个api处理程序
add_action('api_page_process', function ($api){
    if($api === "get_my_weight"){
        header("Content-Type: application/json; charset=utf-8");
        $weight = new MyWeightView();
        $list = $weight->get_charts_list();
        echo json_encode(create_highcharts_obj("最近体重记录|来源:每日计算平均值", "Kg", $list), JSON_UNESCAPED_UNICODE);
        exit;
    }
});

/**
 * 获取当前的API地址
 * @return string|false
 */

function two_heart_api_url(){
    if(!defined('MY_API_PATH')){
        //没定义API路径,无效功能
        return false;
    }
    $url = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : "";
    if(empty($url)){
        return false;
    }
    $urls = explode("?", $url);
    $url = $urls[0];
    $index = strpos($url, MY_API_PATH);
    if($index !== 0){
        return false;
    }
    $api = substr($url, strlen(MY_API_PATH));
    if(empty($api)){
        return false;
    }
    return $api;
}

  第二步,在文章中添加一段短标签,比如我这里是获取体重的数据,写出代码就可以了,就不在具体展示数据了,可以去上一篇文章喵喵。


[charts src="/api/get_my_weight"][/charts]

  最后,wordpress还是很强大的,绝对不要小看,添加各种功能再简单不过。虽然很臃肿,但某一天这些都不会是问题。

2条评论在“将highcharts图表与WordPress整合”

写下你最简单的想法