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

如何将Eloquent查询结果转换为c3.js可用格式以生成饼图

解决Eloquent查询结果与C3.js饼图的数据格式适配问题

我来帮你搞定这个数据格式不匹配的问题~首先得明确核心矛盾:你的Eloquent查询返回的是对象集合(转成JSON后是数组对象),但C3.js的data.columns需要的是二维数组格式——每个子数组第一个元素是分类标签,第二个是对应的数值,比如[["省份A", 50], ["省份B", 30]]。下面给你两种可行的解决方案,选哪种看你习惯:

方案一:后端控制器直接格式化数据(推荐)

在传递数据到视图前,先把Eloquent集合转换成C3需要的格式,这样前端代码更简洁:

// 你的原查询逻辑
$data = MyModel::select('province_id', DB::raw('COUNT(id) AS cnt'))
    ->groupBy('province_id')
    ->get();

// 格式转换:把每个对象转成[标签, 数值]的子数组
$formattedData = $data->map(function($item) {
    // 如果province_id是外键,建议关联省份表获取名称(比如$item->province->name),这里先用province_id做示例
    return [$item->province_id, $item->cnt];
})->toArray();

// 把格式化后的数据传给视图
return view('tool.charts', ['chartData' => $formattedData]);

然后在Blade视图里直接使用:

<script>
var chartData = {!! json_encode($chartData) !!};

c3.generate({
    bindto: '#pie1',
    data: {
        columns: chartData,
        type: 'pie'
    }
});
</script>

方案二:前端JavaScript处理数据

如果你不想改动后端代码,也可以在前端把返回的对象数组转换成C3需要的格式:

<script>
var datax = {!! json_encode($data) !!};

// 把对象数组转成符合要求的二维数组
var chartColumns = datax.map(function(item) {
    return [item.province_id, item.cnt];
});

c3.generate({
    bindto: '#pie1',
    data: {
        columns: chartColumns,
        type: 'pie'
    }
});
</script>

额外优化:显示省份名称(而非ID)

如果province_id是外键,饼图显示ID不够直观,建议关联省份表获取名称:

  1. 先在MyModel里定义关联:
public function province()
{
    return $this->belongsTo(Province::class);
}
  1. 查询时预加载关联,然后格式化数据:
$data = MyModel::select('province_id', DB::raw('COUNT(id) AS cnt'))
    ->groupBy('province_id')
    ->with('province') // 预加载省份关联,避免N+1查询
    ->get();

$formattedData = $data->map(function($item) {
    return [$item->province->name, $item->cnt];
})->toArray();

这样饼图的标签就是直观的省份名称,可读性更强啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:31:05