import type { IVChartOption } from '@visactor/vchart';
import type { TikTokVideoData } from '../index';
import { TIKTOK_COLORS } from '../index';
/**
* Create a pie chart spec for engagement breakdown
*/
export function createPieChartSpec(data: TikTokVideoData[]): IVChartOption {
// Calculate total engagement metrics
const totalLikes = data.reduce((sum, item) => sum + item.likes, 0);
const totalComments = data.reduce((sum, item) => sum + item.comments, 0);
const totalShares = data.reduce((sum, item) => sum + item.shares, 0);
// Prepare data for pie chart
const chartData = [
{
type: 'Likes',
value: totalLikes,
color: TIKTOK_COLORS.secondary
},
{
type: 'Comments',
value: totalComments,
color: TIKTOK_COLORS.warning
},
{
type: 'Shares',
value: totalShares,
color: TIKTOK_COLORS.success
}
];
return {
type: 'pie',
data: {
values: chartData
},
title: {
visible: true,
text: 'Engagement Breakdown',
textStyle: {
fontSize: 20,
fontWeight: 'bold'
}
},
categoryField: 'type',
valueField: 'value',
radius: 0.8,
innerRadius: 0.5,
pie: {
style: {
stroke: '#fff',
lineWidth: 2
}
},
color: {
type: 'ordinal',
range: [TIKTOK_COLORS.secondary, TIKTOK_COLORS.warning, TIKTOK_COLORS.success]
},
label: {
visible: true,
position: 'outside',
style: {
fontSize: 14,
fontWeight: 'bold'
},
line: {
visible: true,
style: {
stroke: '#999',
lineWidth: 1
}
},
formatMethod: (text: any, datum: any) => {
return datum.type + ': ' + datum.value.toLocaleString();
}
},
legends: [
{
visible: true,
orient: 'bottom',
position: 'middle',
item: {
style: {
fontSize: 14
}
},
data: (data: any) => {
return data.map((item: any) => ({
label: item.type,
value: item.value.toLocaleString(),
shape: {
fill: item.color
}
}));
}
}
],
tooltip: {
visible: true,
mark: {
content: [
{
key: 'type',
value: (datum: any) => datum.type
},
{
key: 'value',
value: (datum: any) => datum.value.toLocaleString()
},
{
key: 'percentage',
value: (datum: any) => {
const total = totalLikes + totalComments + totalShares;
const percentage = ((datum.value / total) * 100).toFixed(1);
return percentage + '%';
}
}
]
}
},
hover: {
enable: true,
arcStyle: {
stroke: '#333',
lineWidth: 2
}
},
animation: {
appear: {
duration: 1500,
easing: 'elasticOut'
}
}
};
}