You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chart.js雷达图数据配置故障:循环导致术语计数异常

问题分析

你的核心问题出在**wp_count_posts()函数的误用**——这个函数并不支持传入tax_query参数,所以你的查询逻辑根本没生效,导致统计结果异常,出现第一轮计数为1、其余为0的情况。

解决方案

我们需要替换错误的计数逻辑,改用WP_Query来精准统计指定文章类型+分类术语下的已发布文章数量。同时优化标签收集逻辑,避免重复遍历导致的冗余。

以下是修复后的完整代码:

<?php
/*
 * Plugin Name: Taxonomy Radar Chart
 * Description: 通过短代码展示分类术语的雷达图,支持自定义文章类型、分类法和配色。示例:[taxonomy_radar_chart post_types="content" taxonomies="style,tone,difficulty,content-type" colors="#F44336,#9C27B0,#2196F3,#4CAF50"]
 */

function taxonomy_radar_chart_shortcode( $atts ) {
    // 解析短代码属性
    $atts = shortcode_atts(
        array(
            'post_types' => 'post',
            'taxonomies' => 'category',
            'colors'     => '',
        ),
        $atts,
        'taxonomy_radar_chart'
    );

    // 转换为数组并去除空格
    $post_types = array_map( 'trim', explode( ',', $atts['post_types'] ) );
    $taxonomies = array_map( 'trim', explode( ',', $atts['taxonomies'] ) );

    // 处理配色数组
    if ( empty( $atts['colors'] ) ) {
        $colors = array(
            '#F44336', '#9C27B0', '#2196F3', '#4CAF50',
            '#FFEB3B', '#795548', '#607D8B', '#E91E63',
            '#009688', '#00BCD4', '#FF9800', '#CDDC39'
        );
    } else {
        $colors = array_map( 'trim', explode( ',', $atts['colors'] ) );
    }

    $term_counts = array();
    $all_labels = array();

    // 遍历分类法收集所有术语标签(先统一收集避免重复)
    foreach ( $taxonomies as $taxonomy ) {
        $terms = get_terms( array(
            'taxonomy'   => $taxonomy,
            'hide_empty' => false,
        ) );

        foreach ( $terms as $term ) {
            $all_labels[] = $term->name;
            // 初始化计数数组
            $term_counts[$taxonomy][$term->name] = 0;
        }
    }
    // 去重并保留顺序
    $all_labels = array_unique( $all_labels );

    // 遍历文章类型和分类法统计数量
    foreach ( $post_types as $post_type ) {
        foreach ( $taxonomies as $taxonomy ) {
            $terms = get_terms( array(
                'taxonomy'   => $taxonomy,
                'hide_empty' => false,
            ) );

            foreach ( $terms as $term ) {
                // 用WP_Query统计指定条件的已发布文章数
                $query = new WP_Query( array(
                    'post_type'      => $post_type,
                    'post_status'    => 'publish',
                    'tax_query'      => array(
                        array(
                            'taxonomy' => $taxonomy,
                            'field'    => 'slug',
                            'terms'    => $term->slug,
                        )
                    ),
                    'posts_per_page' => -1,
                    'no_found_rows'  => true, // 优化性能,不需要分页计数
                ) );

                // 累加数量(支持多文章类型)
                $term_counts[$taxonomy][$term->name] += $query->found_posts;
                wp_reset_postdata();
            }
        }
    }

    // 构建雷达图数据集
    $datasets = array();
    foreach ( $term_counts as $taxonomy => $counts ) {
        $dataset = array(
            'label'           => $taxonomy,
            'backgroundColor' => !empty($colors) ? array_shift($colors) : 'rgba(0,0,0,0.2)',
            'data'            => array(),
        );

        foreach ( $all_labels as $label ) {
            $dataset['data'][] = isset( $counts[$label] ) ? $counts[$label] : 0;
        }

        $datasets[] = $dataset;
    }

    // 加载Chart.js
    wp_enqueue_script( 'chartjs', 'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js', array(), '2.9.3', true );

    // 生成唯一图表ID
    $chart_id = uniqid( 'taxonomy_radar_chart_' );
    printf(
        '<canvas id="%s" width="400" height="400"></canvas>',
        esc_attr( $chart_id )
    );

    // 输出图表初始化脚本
    $chart_data = wp_json_encode( array(
        'labels'   => $all_labels,
        'datasets' => $datasets,
    ) );

    $chart_options = wp_json_encode( array(
        'scale' => array(
            'ticks' => array(
                'beginAtZero' => true,
            ),
        ),
    ) );

    printf(
        '<script>
            document.addEventListener("DOMContentLoaded", function() {
                var ctx = document.getElementById("%s").getContext("2d");
                new Chart(ctx, {
                    type: "radar",
                    data: %s,
                    options: %s
                });
            });
        </script>',
        esc_attr( $chart_id ),
        $chart_data,
        $chart_options
    );
}
add_shortcode( 'taxonomy_radar_chart', 'taxonomy_radar_chart_shortcode' );
关键优化点
  1. 修复计数逻辑:用WP_Query替代wp_count_posts(),正确支持tax_query和post_type参数,确保统计结果准确。
  2. 标签预收集:先遍历所有分类法收集术语标签,避免重复添加,提升效率。
  3. 多文章类型支持:对多个文章类型的计数进行累加,符合短代码参数设计。
  4. 性能优化:添加no_found_rows=true减少WP_Query的资源消耗,因为我们只需要总数。
  5. 容错处理:配色数组为空时提供默认透明色,避免报错。

内容的提问来源于stack exchange,提问作者Kyle A

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 20:45:34