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

将PHP数组转换为Google Chart可用JS数组的排序问题求助

解决Google Chart数组格式的code顺序异常问题

我来帮你分析并解决这个问题:

问题根源

你的readPerMonth函数里最后一行的ksort($output[$year][$month]);是核心问题:

  • 这行代码只会对最后一次循环处理的月份的code数组进行按键名排序(E、P、T、U),而其他月份的数组保持初始定义的顺序(P、T、U、E)
  • 这种不一致的顺序会导致转换为Google Chart所需的JS数组时,每个月份的类别列对应混乱,最终图表显示错误
  • 另外,函数里的空数组判断分支存在未定义变量$year和$month的问题,会触发PHP警告

修复后的完整代码

$inputArray = [ 
    ['date' => '2016-12-10', 'code' => 'P'], 
    ['date' => '2016-12-15', 'code' => 'P'], 
    ['date' => '2017-02-10', 'code' => 'P'], 
    ['date' => '2017-02-14', 'code' => 'P'], 
    ['date' => '2017-03-10', 'code' => 'P'], 
    ['date' => '2017-03-05', 'code' => 'U'], 
    ['date' => '2017-03-11', 'code' => 'U'], 
    ['date' => '2017-03-12', 'code' => 'P'], 
    ['date' => '2017-04-07', 'code' => 'T'], 
    ['date' => '2017-04-18', 'code' => 'P'], 
    ['date' => '2017-04-19', 'code' => 'T'], 
    ['date' => '2017-07-10', 'code' => 'P'], 
];

function readPerMonth($tmpArray) {
    $output = [];
    // 定义固定的code顺序,确保所有月份的数组顺序一致
    $fixedCodeOrder = ['P', 'T', 'U', 'E'];
    
    if (empty($tmpArray)) {
        // 空数组时返回一个默认的月份统计(可根据需求调整)
        $currentYear = date('Y');
        $currentMonth = date('M');
        $defaultStats = array_fill_keys($fixedCodeOrder, 0);
        $output[$currentYear][$currentMonth] = $defaultStats;
    } else {
        foreach ($tmpArray as $value) {
            $year = date('Y', strtotime($value['date']));
            $month = date('M', strtotime($value['date']));
            
            // 初始化月份统计数组,严格遵循固定顺序
            if (!isset($output[$year][$month])) {
                $output[$year][$month] = array_fill_keys($fixedCodeOrder, 0);
            }
            
            // 只处理预期内的code类型,避免非法键名干扰
            if (in_array($value['code'], $fixedCodeOrder)) {
                $output[$year][$month][$value['code']] += 1;
            }
        }
        
        // 对年份按数字顺序排序
        ksort($output);
        
        // 对每个年份下的月份按时间顺序排序(而非字母顺序)
        foreach ($output as &$yearData) {
            $monthOrder = array_map(function($m) {
                return date('M', strtotime("2000-$m-01"));
            }, range(1, 12));
            uksort($yearData, function($a, $b) use ($monthOrder) {
                return array_search($a, $monthOrder) - array_search($b, $monthOrder);
            });
        }
    }
    
    return $output;
}

function phpToJS($inputPHP) {
    $return = '';
    // 和readPerMonth保持一致的固定code顺序
    $fixedCodeOrder = ['P', 'T', 'U', 'E'];
    
    foreach ($inputPHP as $year => $months) {
        foreach ($months as $monthValue => $codeValues) {
            $sum = 0;
            $return .= "['" . $year . " - " . $monthValue . "', ";
            
            // 严格按固定顺序遍历,保证JS数组列顺序完全统一
            foreach ($fixedCodeOrder as $code) {
                $value = $codeValues[$code];
                $return .= $value . ',';
                $sum += $value;
            }
            
            // 移除最后一个多余逗号,添加总和
            $return = rtrim($return, ',') . ",'" . $sum . "'],";
        }
    }
    
    // 移除末尾多余的逗号,生成合法JS数组格式
    return rtrim($return, ',');
}

$tmpArr = readPerMonth($inputArray);
$output = phpToJS($tmpArr);

关键修复点说明

  1. 统一code顺序:
    • 用$fixedCodeOrder固定code的排列顺序,所有月份的统计数组都严格遵循这个顺序初始化和更新
  2. 移除错误排序:
    • 删除了只处理最后一个月的ksort代码,避免破坏统一的顺序规则
  3. 月份时间排序:
    • 新增月份排序逻辑,确保每个年份下的月份按1-12月的时间顺序排列,而非字母顺序(比如Feb不会排在Apr之后)
  4. JS转换优化:
    • 按照固定顺序生成JS数组,彻底避免列顺序混乱
    • 修复了原函数中的字符串拼接语法错误,自动处理多余逗号问题
  5. 空数组分支修复:
    • 解决了空数组时未定义年份月份的问题,添加合理默认值

最终效果

修复后的代码会生成顺序完全一致的统计数组,转换后的JS数组可以直接用于Google Chart堆叠图,每个月份的code列对应准确,不会出现显示错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:07:10