feat: 泡泡玛特增加年度、半年数据区分

This commit is contained in:
2026-08-30 14:49:27 +08:00
parent d010b107aa
commit d51890a450
69 changed files with 1109 additions and 258 deletions
+33 -5
View File
@@ -123,6 +123,9 @@ button {
.content { min-width: 0; } .content { min-width: 0; }
.tabs { .tabs {
position: sticky;
top: 20px;
z-index: 5;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 6px; gap: 6px;
@@ -142,7 +145,7 @@ button {
background: var(--surface); background: var(--surface);
border-radius: 10px; border-radius: 10px;
box-shadow: 0 1px 3px rgba(0, 0, 0, .06); box-shadow: 0 1px 3px rgba(0, 0, 0, .06);
scroll-margin-top: 20px; scroll-margin-top: 84px;
} }
.card-bar { .card-bar {
@@ -198,14 +201,39 @@ button {
} }
@media (max-width: 880px) { @media (max-width: 880px) {
.app-layout { display: block; padding: 16px 12px 40px; } .app-layout { display: block; padding: 0 12px 40px; }
.sidebar { position: static; margin-bottom: 12px; } .sidebar { margin-bottom: 12px; }
.company-sidebar { padding: 7px; } .company-sidebar {
position: sticky;
top: 0;
z-index: 7;
margin: 0 -12px;
padding: 7px 12px;
border-width: 0 0 1px;
border-radius: 0;
background: rgba(245, 244, 241, .96);
backdrop-filter: blur(10px);
}
.company-sidebar .sidebar-title { display: none; } .company-sidebar .sidebar-title { display: none; }
.company-list { display: flex; overflow-x: auto; } .company-list { display: flex; overflow-x: auto; }
.company-button { flex: 0 0 auto; width: auto; } .company-button { flex: 0 0 auto; width: auto; }
.tabs { overflow-x: auto; flex-wrap: nowrap; } .tabs {
top: 50px;
z-index: 6;
overflow-x: auto;
overflow-y: hidden;
flex-wrap: nowrap;
margin: 0 -12px 18px;
padding: 5px 12px;
border-width: 0 0 1px;
border-radius: 0;
background: rgba(245, 244, 241, .96);
backdrop-filter: blur(10px);
scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }
.tab-button { flex: 0 0 auto; } .tab-button { flex: 0 0 auto; }
.card { scroll-margin-top: 120px; }
.card-bar { align-items: flex-start; flex-wrap: wrap; } .card-bar { align-items: flex-start; flex-wrap: wrap; }
.export-button { margin-left: auto; } .export-button { margin-left: auto; }
.chart { min-width: 560px; } .chart { min-width: 560px; }
+13 -13
View File
@@ -1,13 +1,13 @@
period,total_assets,cash_like,receivables,investment,operating_assets period,total_assets,cash_like,receivables,investment,operating_assets
2020H1,17.89,8.22,0.41,0.46,8.8 2020H1,17.89,8.22,0.41,0.46,8.80
2020H2,69.71,56.8,0.78,0.67,11.45 2020H2,69.71,56.80,0.78,0.67,11.45
2021H1,76.41,57.67,1.35,1.78,15.6 2021H1,76.41,57.67,1.35,1.78,15.60
2021H2,83.24,52.65,1.71,4.11,24.77 2021H2,83.24,52.65,1.71,4.11,24.77
2022H1,85.9,51.63,1.32,5.53,27.42 2022H1,85.90,51.63,1.32,5.53,27.42
2022H2,85.8,50.42,1.94,5.55,27.89 2022H2,85.80,50.42,1.94,5.55,27.89
2023H1,90.65,55.4,2.09,5.75,27.42 2023H1,90.65,55.40,2.09,5.75,27.42
2023H2,99.69,59.63,3.21,5.87,30.97 2023H2,99.69,59.63,3.21,5.87,30.97
2024H1,110.17,70.1,2.64,5.5,31.93 2024H1,110.17,70.10,2.64,5.50,31.93
2024H2,148.71,96.2,4.78,5.6,42.13 2024H2,148.71,96.20,4.78,5.60,42.13
2025H1,213.57,137.66,9.72,5.4,60.79 2025H1,213.57,137.66,9.72,5.40,60.79
2025H2,321.01,172.25,9.21,4.95,132.04 2025H2,321.01,172.25,9.21,4.95,132.04
1 period total_assets cash_like receivables investment operating_assets
2 2020H1 17.89 8.22 0.41 0.46 8.8 8.80
3 2020H2 69.71 56.8 56.80 0.78 0.67 11.45
4 2021H1 76.41 57.67 1.35 1.78 15.6 15.60
5 2021H2 83.24 52.65 1.71 4.11 24.77
6 2022H1 85.9 85.90 51.63 1.32 5.53 27.42
7 2022H2 85.8 85.80 50.42 1.94 5.55 27.89
8 2023H1 90.65 55.4 55.40 2.09 5.75 27.42
9 2023H2 99.69 59.63 3.21 5.87 30.97
10 2024H1 110.17 70.1 70.10 2.64 5.5 5.50 31.93
11 2024H2 148.71 96.2 96.20 4.78 5.6 5.60 42.13
12 2025H1 213.57 137.66 9.72 5.4 5.40 60.79
13 2025H2 321.01 172.25 9.21 4.95 132.04
+7
View File
@@ -0,0 +1,7 @@
period,total_assets,cash_like,receivables,investment,operating_assets
2020FY,69.71,56.80,0.78,0.67,11.45
2021FY,83.24,52.65,1.71,4.11,24.77
2022FY,85.80,50.42,1.94,5.55,27.89
2023FY,99.69,59.63,3.21,5.87,30.97
2024FY,148.71,96.20,4.78,5.60,42.13
2025FY,321.01,172.25,9.21,4.95,132.04
1 period total_assets cash_like receivables investment operating_assets
2 2020FY 69.71 56.80 0.78 0.67 11.45
3 2021FY 83.24 52.65 1.71 4.11 24.77
4 2022FY 85.80 50.42 1.94 5.55 27.89
5 2023FY 99.69 59.63 3.21 5.87 30.97
6 2024FY 148.71 96.20 4.78 5.60 42.13
7 2025FY 321.01 172.25 9.21 4.95 132.04
+13
View File
@@ -0,0 +1,13 @@
period,total_assets,cash_like,receivables,investment,operating_assets
2020H1,17.89,8.22,0.41,0.46,8.80
2020H2,69.71,56.80,0.78,0.67,11.45
2021H1,76.41,57.67,1.35,1.78,15.60
2021H2,83.24,52.65,1.71,4.11,24.77
2022H1,85.90,51.63,1.32,5.53,27.42
2022H2,85.80,50.42,1.94,5.55,27.89
2023H1,90.65,55.40,2.09,5.75,27.42
2023H2,99.69,59.63,3.21,5.87,30.97
2024H1,110.17,70.10,2.64,5.50,31.93
2024H2,148.71,96.20,4.78,5.60,42.13
2025H1,213.57,137.66,9.72,5.40,60.79
2025H2,321.01,172.25,9.21,4.95,132.04
1 period total_assets cash_like receivables investment operating_assets
2 2020H1 17.89 8.22 0.41 0.46 8.80
3 2020H2 69.71 56.80 0.78 0.67 11.45
4 2021H1 76.41 57.67 1.35 1.78 15.60
5 2021H2 83.24 52.65 1.71 4.11 24.77
6 2022H1 85.90 51.63 1.32 5.53 27.42
7 2022H2 85.80 50.42 1.94 5.55 27.89
8 2023H1 90.65 55.40 2.09 5.75 27.42
9 2023H2 99.69 59.63 3.21 5.87 30.97
10 2024H1 110.17 70.10 2.64 5.50 31.93
11 2024H2 148.71 96.20 4.78 5.60 42.13
12 2025H1 213.57 137.66 9.72 5.40 60.79
13 2025H2 321.01 172.25 9.21 4.95 132.04
+12
View File
@@ -1,7 +1,19 @@
period,operating_cash_flow,net_profit,cash_conversion period,operating_cash_flow,net_profit,cash_conversion
2020H1,1.22,1.41,86.5
2020H2,5.81,3.82,152.1
2020FY,7.03,5.23,134.4 2020FY,7.03,5.23,134.4
2021H1,4.42,3.59,123.1
2021H2,3.37,4.96,68.1
2021FY,7.79,8.55,91.2 2021FY,7.79,8.55,91.2
2022H1,3.74,3.33,112.2
2022H2,5.17,1.43,362.2
2022FY,8.91,4.76,187.3 2022FY,8.91,4.76,187.3
2023H1,10.92,4.77,228.9
2023H2,8.98,6.12,146.9
2023FY,19.91,10.89,182.8 2023FY,19.91,10.89,182.8
2024H1,19.05,9.64,197.6
2024H2,30.49,23.44,130.1
2024FY,49.54,33.08,149.7 2024FY,49.54,33.08,149.7
2025H1,59.77,46.82,127.7
2025H2,48.88,83.30,58.7
2025FY,108.65,130.12,83.5 2025FY,108.65,130.12,83.5
1 period operating_cash_flow net_profit cash_conversion
2 2020H1 1.22 1.41 86.5
3 2020H2 5.81 3.82 152.1
4 2020FY 7.03 5.23 134.4
5 2021H1 4.42 3.59 123.1
6 2021H2 3.37 4.96 68.1
7 2021FY 7.79 8.55 91.2
8 2022H1 3.74 3.33 112.2
9 2022H2 5.17 1.43 362.2
10 2022FY 8.91 4.76 187.3
11 2023H1 10.92 4.77 228.9
12 2023H2 8.98 6.12 146.9
13 2023FY 19.91 10.89 182.8
14 2024H1 19.05 9.64 197.6
15 2024H2 30.49 23.44 130.1
16 2024FY 49.54 33.08 149.7
17 2025H1 59.77 46.82 127.7
18 2025H2 48.88 83.30 58.7
19 2025FY 108.65 130.12 83.5
@@ -0,0 +1,7 @@
period,operating_cash_flow,net_profit,cash_conversion
2020FY,7.03,5.23,134.4
2021FY,7.79,8.55,91.2
2022FY,8.91,4.76,187.3
2023FY,19.91,10.89,182.8
2024FY,49.54,33.08,149.7
2025FY,108.65,130.12,83.5
1 period operating_cash_flow net_profit cash_conversion
2 2020FY 7.03 5.23 134.4
3 2021FY 7.79 8.55 91.2
4 2022FY 8.91 4.76 187.3
5 2023FY 19.91 10.89 182.8
6 2024FY 49.54 33.08 149.7
7 2025FY 108.65 130.12 83.5
@@ -0,0 +1,13 @@
period,operating_cash_flow,net_profit,cash_conversion
2020H1,1.22,1.41,86.5
2020H2,5.81,3.82,152.1
2021H1,4.42,3.59,123.1
2021H2,3.37,4.96,68.1
2022H1,3.74,3.33,112.2
2022H2,5.17,1.43,362.2
2023H1,10.92,4.77,228.9
2023H2,8.98,6.12,146.9
2024H1,19.05,9.64,197.6
2024H2,30.49,23.44,130.1
2025H1,59.77,46.82,127.7
2025H2,48.88,83.30,58.7
1 period operating_cash_flow net_profit cash_conversion
2 2020H1 1.22 1.41 86.5
3 2020H2 5.81 3.82 152.1
4 2021H1 4.42 3.59 123.1
5 2021H2 3.37 4.96 68.1
6 2022H1 3.74 3.33 112.2
7 2022H2 5.17 1.43 362.2
8 2023H1 10.92 4.77 228.9
9 2023H2 8.98 6.12 146.9
10 2024H1 19.05 9.64 197.6
11 2024H2 30.49 23.44 130.1
12 2025H1 59.77 46.82 127.7
13 2025H2 48.88 83.30 58.7
+12
View File
@@ -1,7 +1,19 @@
period,operating_cash_flow,investing_cash_flow,financing_cash_flow,net_cash_increase period,operating_cash_flow,investing_cash_flow,financing_cash_flow,net_cash_increase
2020H1,1.22,-0.48,4.24,4.98
2020H2,5.81,-1.69,44.47,48.59
2020FY,7.03,-2.17,48.70,53.57 2020FY,7.03,-2.17,48.70,53.57
2021H1,4.42,-44.98,-1.21,-41.78
2021H2,3.37,38.50,-3.15,38.73
2021FY,7.79,-6.48,-4.36,-3.05 2021FY,7.79,-6.48,-4.36,-3.05
2022H1,3.74,-42.10,-4.81,-43.17
2022H2,5.17,-4.89,-6.97,-6.68
2022FY,8.91,-46.98,-11.77,-49.85 2022FY,8.91,-46.98,-11.77,-49.85
2023H1,10.92,0.82,-5.58,6.16
2023H2,8.98,1.52,-2.83,7.67
2023FY,19.91,2.34,-8.42,13.83 2023FY,19.91,2.34,-8.42,13.83
2024H1,19.05,3.34,-7.16,15.23
2024H2,30.49,-3.25,-2.43,24.82
2024FY,49.54,0.09,-9.59,40.05 2024FY,49.54,0.09,-9.59,40.05
2025H1,59.77,12.34,-14.05,58.07
2025H2,48.88,-22.23,-3.62,23.02
2025FY,108.65,-9.89,-17.67,81.09 2025FY,108.65,-9.89,-17.67,81.09
1 period operating_cash_flow investing_cash_flow financing_cash_flow net_cash_increase
2 2020H1 1.22 -0.48 4.24 4.98
3 2020H2 5.81 -1.69 44.47 48.59
4 2020FY 7.03 -2.17 48.70 53.57
5 2021H1 4.42 -44.98 -1.21 -41.78
6 2021H2 3.37 38.50 -3.15 38.73
7 2021FY 7.79 -6.48 -4.36 -3.05
8 2022H1 3.74 -42.10 -4.81 -43.17
9 2022H2 5.17 -4.89 -6.97 -6.68
10 2022FY 8.91 -46.98 -11.77 -49.85
11 2023H1 10.92 0.82 -5.58 6.16
12 2023H2 8.98 1.52 -2.83 7.67
13 2023FY 19.91 2.34 -8.42 13.83
14 2024H1 19.05 3.34 -7.16 15.23
15 2024H2 30.49 -3.25 -2.43 24.82
16 2024FY 49.54 0.09 -9.59 40.05
17 2025H1 59.77 12.34 -14.05 58.07
18 2025H2 48.88 -22.23 -3.62 23.02
19 2025FY 108.65 -9.89 -17.67 81.09
@@ -0,0 +1,7 @@
period,operating_cash_flow,investing_cash_flow,financing_cash_flow,net_cash_increase
2020FY,7.03,-2.17,48.70,53.57
2021FY,7.79,-6.48,-4.36,-3.05
2022FY,8.91,-46.98,-11.77,-49.85
2023FY,19.91,2.34,-8.42,13.83
2024FY,49.54,0.09,-9.59,40.05
2025FY,108.65,-9.89,-17.67,81.09
1 period operating_cash_flow investing_cash_flow financing_cash_flow net_cash_increase
2 2020FY 7.03 -2.17 48.70 53.57
3 2021FY 7.79 -6.48 -4.36 -3.05
4 2022FY 8.91 -46.98 -11.77 -49.85
5 2023FY 19.91 2.34 -8.42 13.83
6 2024FY 49.54 0.09 -9.59 40.05
7 2025FY 108.65 -9.89 -17.67 81.09
@@ -0,0 +1,13 @@
period,operating_cash_flow,investing_cash_flow,financing_cash_flow,net_cash_increase
2020H1,1.22,-0.48,4.24,4.98
2020H2,5.81,-1.69,44.47,48.59
2021H1,4.42,-44.98,-1.21,-41.78
2021H2,3.37,38.50,-3.15,38.73
2022H1,3.74,-42.10,-4.81,-43.17
2022H2,5.17,-4.89,-6.97,-6.68
2023H1,10.92,0.82,-5.58,6.16
2023H2,8.98,1.52,-2.83,7.67
2024H1,19.05,3.34,-7.16,15.23
2024H2,30.49,-3.25,-2.43,24.82
2025H1,59.77,12.34,-14.05,58.07
2025H2,48.88,-22.23,-3.62,23.02
1 period operating_cash_flow investing_cash_flow financing_cash_flow net_cash_increase
2 2020H1 1.22 -0.48 4.24 4.98
3 2020H2 5.81 -1.69 44.47 48.59
4 2021H1 4.42 -44.98 -1.21 -41.78
5 2021H2 3.37 38.50 -3.15 38.73
6 2022H1 3.74 -42.10 -4.81 -43.17
7 2022H2 5.17 -4.89 -6.97 -6.68
8 2023H1 10.92 0.82 -5.58 6.16
9 2023H2 8.98 1.52 -2.83 7.67
10 2024H1 19.05 3.34 -7.16 15.23
11 2024H2 30.49 -3.25 -2.43 24.82
12 2025H1 59.77 12.34 -14.05 58.07
13 2025H2 48.88 -22.23 -3.62 23.02
+7 -6
View File
@@ -1,6 +1,7 @@
period,plush,figure,mega,other period,plush,figure,mega,other
品类,毛绒,手办,MEGA,衍生品及其他 2024H1,4.46,26.57,5.86,8.69
2024H1,4.46105,26.56781,5.8613,8.68815 2024H2,23.86,42.79,10.98,7.17
2024H2,23.85973,42.79306,10.9765,7.16989 2024FY,28.32,69.36,16.84,15.86
2025H1,61.39236,51.75875,10.07147,15.54018 2025H1,61.39,51.76,10.07,15.54
2025H2,125.68838,68.46694,9.08935,29.19309 2025H2,125.69,68.47,9.09,29.19
2025FY,187.08,120.23,19.16,44.73
1 period plush figure mega other
2 品类 2024H1 毛绒 4.46 手办 26.57 MEGA 5.86 衍生品及其他 8.69
3 2024H1 2024H2 4.46105 23.86 26.56781 42.79 5.8613 10.98 8.68815 7.17
4 2024H2 2024FY 23.85973 28.32 42.79306 69.36 10.9765 16.84 7.16989 15.86
5 2025H1 61.39236 61.39 51.75875 51.76 10.07147 10.07 15.54018 15.54
6 2025H2 125.68838 125.69 68.46694 68.47 9.08935 9.09 29.19309 29.19
7 2025FY 187.08 120.23 19.16 44.73
+3
View File
@@ -0,0 +1,3 @@
period,plush,figure,mega,other
2024FY,28.32,69.36,16.84,15.86
2025FY,187.08,120.23,19.16,44.73
1 period plush figure mega other
2 2024FY 28.32 69.36 16.84 15.86
3 2025FY 187.08 120.23 19.16 44.73
+5
View File
@@ -0,0 +1,5 @@
period,plush,figure,mega,other
2024H1,4.46,26.57,5.86,8.69
2024H2,23.86,42.79,10.98,7.17
2025H1,61.39,51.76,10.07,15.54
2025H2,125.69,68.47,9.09,29.19
1 period plush figure mega other
2 2024H1 4.46 26.57 5.86 8.69
3 2024H2 23.86 42.79 10.98 7.17
4 2025H1 61.39 51.76 10.07 15.54
5 2025H2 125.69 68.47 9.09 29.19
+6
View File
@@ -1,14 +1,20 @@
period,retail,online,robot_store,wholesale,total_revenue,revenue_yoy period,retail,online,robot_store,wholesale,total_revenue,revenue_yoy
2020H1,3.13,3.34,1.05,0.64,8.18,50.5 2020H1,3.13,3.34,1.05,0.64,8.18,50.5
2020H2,6.89,6.18,2.23,1.44,16.96,48.7
2020FY,10.02,9.52,3.29,2.07,25.13,49.3 2020FY,10.02,9.52,3.29,2.07,25.13,49.3
2021H1,6.75,6.78,2.28,1.91,17.73,116.8 2021H1,6.75,6.78,2.28,1.91,17.73,116.8
2021H2,9.98,12.01,2.42,2.53,27.18,60.3
2021FY,16.73,18.79,4.70,4.45,44.91,78.7 2021FY,16.73,18.79,4.70,4.45,44.91,78.7
2022H1,9.26,10.13,2.08,2.12,23.59,33.1 2022H1,9.26,10.13,2.08,2.12,23.59,33.1
2022H2,9.00,9.07,1.86,2.65,22.59,-16.9
2022FY,18.27,19.20,3.94,4.77,46.17,2.8 2022FY,18.27,19.20,3.94,4.77,46.17,2.8
2023H1,13.44,8.74,2.96,2.99,28.14,19.3 2023H1,13.44,8.74,2.96,2.99,28.14,19.3
2023H2,17.18,9.92,3.10,4.68,34.87,54.4
2023FY,30.62,18.66,6.06,7.67,63.01,36.5 2023FY,30.62,18.66,6.06,7.67,63.01,36.5
2024H1,23.65,13.43,3.68,4.82,45.58,62.0 2024H1,23.65,13.43,3.68,4.82,45.58,62.0
2024H2,44.01,28.10,4.63,8.06,84.80,143.2
2024FY,67.66,41.53,8.31,12.88,130.38,106.9 2024FY,67.66,41.53,8.31,12.88,130.38,106.9
2025H1,69.08,54.98,8.21,6.50,138.76,204.4 2025H1,69.08,54.98,8.21,6.50,138.76,204.4
2025H2,103.46,109.36,8.69,10.93,232.44,174.1
2025FY,172.54,164.34,16.89,17.42,371.20,184.7 2025FY,172.54,164.34,16.89,17.42,371.20,184.7
2026H1,91.12,62.12,9.51,8.98,171.73,23.8 2026H1,91.12,62.12,9.51,8.98,171.73,23.8
1 period retail online robot_store wholesale total_revenue revenue_yoy
2 2020H1 3.13 3.34 1.05 0.64 8.18 50.5
3 2020H2 6.89 6.18 2.23 1.44 16.96 48.7
4 2020FY 10.02 9.52 3.29 2.07 25.13 49.3
5 2021H1 6.75 6.78 2.28 1.91 17.73 116.8
6 2021H2 9.98 12.01 2.42 2.53 27.18 60.3
7 2021FY 16.73 18.79 4.70 4.45 44.91 78.7
8 2022H1 9.26 10.13 2.08 2.12 23.59 33.1
9 2022H2 9.00 9.07 1.86 2.65 22.59 -16.9
10 2022FY 18.27 19.20 3.94 4.77 46.17 2.8
11 2023H1 13.44 8.74 2.96 2.99 28.14 19.3
12 2023H2 17.18 9.92 3.10 4.68 34.87 54.4
13 2023FY 30.62 18.66 6.06 7.67 63.01 36.5
14 2024H1 23.65 13.43 3.68 4.82 45.58 62.0
15 2024H2 44.01 28.10 4.63 8.06 84.80 143.2
16 2024FY 67.66 41.53 8.31 12.88 130.38 106.9
17 2025H1 69.08 54.98 8.21 6.50 138.76 204.4
18 2025H2 103.46 109.36 8.69 10.93 232.44 174.1
19 2025FY 172.54 164.34 16.89 17.42 371.20 184.7
20 2026H1 91.12 62.12 9.51 8.98 171.73 23.8
@@ -0,0 +1,7 @@
period,retail,online,robot_store,wholesale,total_revenue,revenue_yoy
2020FY,10.02,9.52,3.29,2.07,25.13,49.3
2021FY,16.73,18.79,4.70,4.45,44.91,78.7
2022FY,18.27,19.20,3.94,4.77,46.17,2.8
2023FY,30.62,18.66,6.06,7.67,63.01,36.5
2024FY,67.66,41.53,8.31,12.88,130.38,106.9
2025FY,172.54,164.34,16.89,17.42,371.20,184.7
1 period retail online robot_store wholesale total_revenue revenue_yoy
2 2020FY 10.02 9.52 3.29 2.07 25.13 49.3
3 2021FY 16.73 18.79 4.70 4.45 44.91 78.7
4 2022FY 18.27 19.20 3.94 4.77 46.17 2.8
5 2023FY 30.62 18.66 6.06 7.67 63.01 36.5
6 2024FY 67.66 41.53 8.31 12.88 130.38 106.9
7 2025FY 172.54 164.34 16.89 17.42 371.20 184.7
@@ -0,0 +1,14 @@
period,retail,online,robot_store,wholesale,total_revenue,revenue_yoy
2020H1,3.13,3.34,1.05,0.64,8.18,50.5
2020H2,6.89,6.18,2.23,1.44,16.96,48.7
2021H1,6.75,6.78,2.28,1.91,17.73,116.8
2021H2,9.98,12.01,2.42,2.53,27.18,60.3
2022H1,9.26,10.13,2.08,2.12,23.59,33.1
2022H2,9.00,9.07,1.86,2.65,22.59,-16.9
2023H1,13.44,8.74,2.96,2.99,28.14,19.3
2023H2,17.18,9.92,3.10,4.68,34.87,54.4
2024H1,23.65,13.43,3.68,4.82,45.58,62.0
2024H2,44.01,28.10,4.63,8.06,84.80,143.2
2025H1,69.08,54.98,8.21,6.50,138.76,204.4
2025H2,103.46,109.36,8.69,10.93,232.44,174.1
2026H1,91.12,62.12,9.51,8.98,171.73,23.8
1 period retail online robot_store wholesale total_revenue revenue_yoy
2 2020H1 3.13 3.34 1.05 0.64 8.18 50.5
3 2020H2 6.89 6.18 2.23 1.44 16.96 48.7
4 2021H1 6.75 6.78 2.28 1.91 17.73 116.8
5 2021H2 9.98 12.01 2.42 2.53 27.18 60.3
6 2022H1 9.26 10.13 2.08 2.12 23.59 33.1
7 2022H2 9.00 9.07 1.86 2.65 22.59 -16.9
8 2023H1 13.44 8.74 2.96 2.99 28.14 19.3
9 2023H2 17.18 9.92 3.10 4.68 34.87 54.4
10 2024H1 23.65 13.43 3.68 4.82 45.58 62.0
11 2024H2 44.01 28.10 4.63 8.06 84.80 143.2
12 2025H1 69.08 54.98 8.21 6.50 138.76 204.4
13 2025H2 103.46 109.36 8.69 10.93 232.44 174.1
14 2026H1 91.12 62.12 9.51 8.98 171.73 23.8
+20 -14
View File
@@ -1,14 +1,20 @@
period,core_margin period,core_margin
2020H1,22.6 2020H1,22.6
2020H2,27.2 2020H2,29.4
2021H1,25.8 2020FY,27.2
2021H2,24.4 2021H1,25.8
2022H1,15.0 2021H2,23.5
2022H2,10.8 2021FY,24.4
2023H1,17.4 2022H1,15.0
2023H2,18.3 2022H2,6.3
2024H1,24.8 2022FY,10.8
2024H2,31.5 2023H1,17.4
2025H1,41.8 2023H2,19.0
2025H2,45.6 2023FY,18.3
2026H1,41.4 2024H1,24.8
2024H2,35.1
2024FY,31.5
2025H1,41.8
2025H2,47.8
2025FY,45.6
2026H1,41.4
1 period core_margin
2 2020H1 22.6
3 2020H2 27.2 29.4
4 2021H1 2020FY 25.8 27.2
5 2021H2 2021H1 24.4 25.8
6 2022H1 2021H2 15.0 23.5
7 2022H2 2021FY 10.8 24.4
8 2023H1 2022H1 17.4 15.0
9 2023H2 2022H2 18.3 6.3
10 2024H1 2022FY 24.8 10.8
11 2024H2 2023H1 31.5 17.4
12 2025H1 2023H2 41.8 19.0
13 2025H2 2023FY 45.6 18.3
14 2026H1 2024H1 41.4 24.8
15 2024H2 35.1
16 2024FY 31.5
17 2025H1 41.8
18 2025H2 47.8
19 2025FY 45.6
20 2026H1 41.4
+7
View File
@@ -0,0 +1,7 @@
period,core_margin
2020FY,27.2
2021FY,24.4
2022FY,10.8
2023FY,18.3
2024FY,31.5
2025FY,45.6
1 period core_margin
2 2020FY 27.2
3 2021FY 24.4
4 2022FY 10.8
5 2023FY 18.3
6 2024FY 31.5
7 2025FY 45.6
+14
View File
@@ -0,0 +1,14 @@
period,core_margin
2020H1,22.6
2020H2,29.4
2021H1,25.8
2021H2,23.5
2022H1,15.0
2022H2,6.3
2023H1,17.4
2023H2,19.0
2024H1,24.8
2024H2,35.1
2025H1,41.8
2025H2,47.8
2026H1,41.4
1 period core_margin
2 2020H1 22.6
3 2020H2 29.4
4 2021H1 25.8
5 2021H2 23.5
6 2022H1 15.0
7 2022H2 6.3
8 2023H1 17.4
9 2023H2 19.0
10 2024H1 24.8
11 2024H2 35.1
12 2025H1 41.8
13 2025H2 47.8
14 2026H1 41.4
+20 -14
View File
@@ -1,14 +1,20 @@
period,core_profit,yoy period,core_profit,yoy
2020H1,1.9,25.0 2020H1,1.85,25.2
2020H2,6.8,17.1 2020H2,4.99,14.4
2021H1,4.6,147.0 2020FY,6.84,17.1
2021H2,11.0,60.1 2021H1,4.58,147.3
2022H1,3.5,-22.5 2021H2,6.37,27.7
2022H2,5.0,-54.5 2021FY,10.95,60.1
2023H1,4.9,38.1 2022H1,3.54,-22.5
2023H2,11.5,131.3 2022H2,1.43,-77.6
2024H1,11.3,131.5 2022FY,4.98,-54.6
2024H2,41.1,256.9 2023H1,4.89,37.9
2025H1,58.0,412.2 2023H2,6.63,363.8
2025H2,169.1,311.4 2023FY,11.52,131.6
2026H1,71.1,22.6 2024H1,11.31,131.5
2024H2,29.79,349.1
2024FY,41.10,256.8
2025H1,57.98,412.4
2025H2,111.14,273.1
2025FY,169.12,311.5
2026H1,71.08,22.6
1 period core_profit yoy
2 2020H1 1.9 1.85 25.0 25.2
3 2020H2 6.8 4.99 17.1 14.4
4 2021H1 2020FY 4.6 6.84 147.0 17.1
5 2021H2 2021H1 11.0 4.58 60.1 147.3
6 2022H1 2021H2 3.5 6.37 -22.5 27.7
7 2022H2 2021FY 5.0 10.95 -54.5 60.1
8 2023H1 2022H1 4.9 3.54 38.1 -22.5
9 2023H2 2022H2 11.5 1.43 131.3 -77.6
10 2024H1 2022FY 11.3 4.98 131.5 -54.6
11 2024H2 2023H1 41.1 4.89 256.9 37.9
12 2025H1 2023H2 58.0 6.63 412.2 363.8
13 2025H2 2023FY 169.1 11.52 311.4 131.6
14 2026H1 2024H1 71.1 11.31 22.6 131.5
15 2024H2 29.79 349.1
16 2024FY 41.10 256.8
17 2025H1 57.98 412.4
18 2025H2 111.14 273.1
19 2025FY 169.12 311.5
20 2026H1 71.08 22.6
+7
View File
@@ -0,0 +1,7 @@
period,core_profit,yoy
2020FY,6.84,17.1
2021FY,10.95,60.1
2022FY,4.98,-54.6
2023FY,11.52,131.6
2024FY,41.10,256.8
2025FY,169.12,311.5
1 period core_profit yoy
2 2020FY 6.84 17.1
3 2021FY 10.95 60.1
4 2022FY 4.98 -54.6
5 2023FY 11.52 131.6
6 2024FY 41.10 256.8
7 2025FY 169.12 311.5
+14
View File
@@ -0,0 +1,14 @@
period,core_profit,yoy
2020H1,1.85,25.2
2020H2,4.99,14.4
2021H1,4.58,147.3
2021H2,6.37,27.7
2022H1,3.54,-22.5
2022H2,1.43,-77.6
2023H1,4.89,37.9
2023H2,6.63,363.8
2024H1,11.31,131.5
2024H2,29.79,349.1
2025H1,57.98,412.4
2025H2,111.14,273.1
2026H1,71.08,22.6
1 period core_profit yoy
2 2020H1 1.85 25.2
3 2020H2 4.99 14.4
4 2021H1 4.58 147.3
5 2021H2 6.37 27.7
6 2022H1 3.54 -22.5
7 2022H2 1.43 -77.6
8 2023H1 4.89 37.9
9 2023H2 6.63 363.8
10 2024H1 11.31 131.5
11 2024H2 29.79 349.1
12 2025H1 57.98 412.4
13 2025H2 111.14 273.1
14 2026H1 71.08 22.6
+13
View File
@@ -1,7 +1,20 @@
period,sales_expense,admin_expense,financial_expense,four_expense_rate period,sales_expense,admin_expense,financial_expense,four_expense_rate
2020H1,2.23,1.25,0.04,43.1
2020H2,4.07,1.55,0.05,33.4
2020FY,6.30,2.80,0.09,36.6 2020FY,6.30,2.80,0.09,36.6
2021H1,4.20,2.40,-0.06,36.9
2021H2,6.86,3.18,-0.02,36.9
2021FY,11.06,5.58,-0.07,36.9 2021FY,11.06,5.58,-0.07,36.9
2022H1,6.93,3.23,-0.07,42.8
2022H2,7.78,3.64,-0.22,49.5
2022FY,14.71,6.86,-0.29,46.1 2022FY,14.71,6.86,-0.29,46.1
2023H1,8.78,3.31,-0.63,40.7
2023H2,11.26,3.76,-0.88,40.5
2023FY,20.05,7.07,-1.52,40.6 2023FY,20.05,7.07,-1.52,40.6
2024H1,13.53,4.34,-0.84,37.4
2024H2,22.97,5.13,-0.80,32.2
2024FY,36.50,9.47,-1.63,34.0 2024FY,36.50,9.47,-1.63,34.0
2025H1,31.93,7.70,-0.66,28.1
2025H2,48.90,10.00,-0.11,25.3
2025FY,80.82,17.70,-0.76,26.3 2025FY,80.82,17.70,-0.76,26.3
2026H1,39.31,9.27,-0.11,28.2
1 period sales_expense admin_expense financial_expense four_expense_rate
2 2020H1 2.23 1.25 0.04 43.1
3 2020H2 4.07 1.55 0.05 33.4
4 2020FY 6.30 2.80 0.09 36.6
5 2021H1 4.20 2.40 -0.06 36.9
6 2021H2 6.86 3.18 -0.02 36.9
7 2021FY 11.06 5.58 -0.07 36.9
8 2022H1 6.93 3.23 -0.07 42.8
9 2022H2 7.78 3.64 -0.22 49.5
10 2022FY 14.71 6.86 -0.29 46.1
11 2023H1 8.78 3.31 -0.63 40.7
12 2023H2 11.26 3.76 -0.88 40.5
13 2023FY 20.05 7.07 -1.52 40.6
14 2024H1 13.53 4.34 -0.84 37.4
15 2024H2 22.97 5.13 -0.80 32.2
16 2024FY 36.50 9.47 -1.63 34.0
17 2025H1 31.93 7.70 -0.66 28.1
18 2025H2 48.90 10.00 -0.11 25.3
19 2025FY 80.82 17.70 -0.76 26.3
20 2026H1 39.31 9.27 -0.11 28.2
@@ -0,0 +1,7 @@
period,sales_expense,admin_expense,financial_expense,four_expense_rate
2020FY,6.30,2.80,0.09,36.6
2021FY,11.06,5.58,-0.07,36.9
2022FY,14.71,6.86,-0.29,46.1
2023FY,20.05,7.07,-1.52,40.6
2024FY,36.50,9.47,-1.63,34.0
2025FY,80.82,17.70,-0.76,26.3
1 period sales_expense admin_expense financial_expense four_expense_rate
2 2020FY 6.30 2.80 0.09 36.6
3 2021FY 11.06 5.58 -0.07 36.9
4 2022FY 14.71 6.86 -0.29 46.1
5 2023FY 20.05 7.07 -1.52 40.6
6 2024FY 36.50 9.47 -1.63 34.0
7 2025FY 80.82 17.70 -0.76 26.3
@@ -0,0 +1,14 @@
period,sales_expense,admin_expense,financial_expense,four_expense_rate
2020H1,2.23,1.25,0.04,43.1
2020H2,4.07,1.55,0.05,33.4
2021H1,4.20,2.40,-0.06,36.9
2021H2,6.86,3.18,-0.02,36.9
2022H1,6.93,3.23,-0.07,42.8
2022H2,7.78,3.64,-0.22,49.5
2023H1,8.78,3.31,-0.63,40.7
2023H2,11.26,3.76,-0.88,40.5
2024H1,13.53,4.34,-0.84,37.4
2024H2,22.97,5.13,-0.80,32.2
2025H1,31.93,7.70,-0.66,28.1
2025H2,48.90,10.00,-0.11,25.3
2026H1,39.31,9.27,-0.11,28.2
1 period sales_expense admin_expense financial_expense four_expense_rate
2 2020H1 2.23 1.25 0.04 43.1
3 2020H2 4.07 1.55 0.05 33.4
4 2021H1 4.20 2.40 -0.06 36.9
5 2021H2 6.86 3.18 -0.02 36.9
6 2022H1 6.93 3.23 -0.07 42.8
7 2022H2 7.78 3.64 -0.22 49.5
8 2023H1 8.78 3.31 -0.63 40.7
9 2023H2 11.26 3.76 -0.88 40.5
10 2024H1 13.53 4.34 -0.84 37.4
11 2024H2 22.97 5.13 -0.80 32.2
12 2025H1 31.93 7.70 -0.66 28.1
13 2025H2 48.90 10.00 -0.11 25.3
14 2026H1 39.31 9.27 -0.11 28.2
+20 -14
View File
@@ -1,14 +1,20 @@
period,non_gaap_net_profit,gross_profit,revenue,cost period,non_gaap_net_profit,gross_profit,revenue,cost
2020H1,23.7,61.0,50.6,33.3 2020H1,24.4,61.4,50.5,33.6
2020H2,16.2,46.2,49.3,55.0 2020H2,33.1,39.6,48.7,67.0
2021H1,154.6,109.6,116.7,131.0 2020FY,30.9,46.2,49.3,55.0
2021H2,69.5,73.1,78.7,88.5 2021H1,208.0,109.4,116.8,130.5
2022H1,-13.6,22.6,33.1,50.6 2021H2,26.1,54.8,60.3,69.5
2022H2,-42.7,-3.8,2.8,13.3 2021FY,69.6,73.1,78.7,88.4
2023H1,42.3,23.9,19.3,12.9 2022H1,-13.5,22.7,33.1,50.8
2023H2,107.5,45.5,36.5,24.1 2022H2,-65.2,-21.8,-16.9,-9.5
2024H1,90.3,71.9,62.0,47.0 2022FY,-42.7,-3.8,2.8,13.3
2024H2,185.7,125.4,106.9,77.7 2023H1,42.3,23.9,19.3,12.9
2025H1,362.7,234.4,204.4,151.1 2023H2,232.1,68.7,54.4,35.6
2025H2,284.5,207.4,184.7,139.1 2023FY,107.6,45.6,36.5,24.2
2026H1,9.5,22.6,23.8,26.5 2024H1,90.1,71.9,62.0,46.9
2024H2,264.1,167.3,143.2,103.7
2024FY,185.9,125.4,106.9,77.7
2025H1,362.8,234.4,204.4,151.1
2025H2,251.0,193.7,174.1,131.9
2025FY,284.5,207.4,184.7,139.1
2026H1,9.5,22.6,23.8,26.5
1 period non_gaap_net_profit gross_profit revenue cost
2 2020H1 23.7 24.4 61.0 61.4 50.6 50.5 33.3 33.6
3 2020H2 16.2 33.1 46.2 39.6 49.3 48.7 55.0 67.0
4 2021H1 2020FY 154.6 30.9 109.6 46.2 116.7 49.3 131.0 55.0
5 2021H2 2021H1 69.5 208.0 73.1 109.4 78.7 116.8 88.5 130.5
6 2022H1 2021H2 -13.6 26.1 22.6 54.8 33.1 60.3 50.6 69.5
7 2022H2 2021FY -42.7 69.6 -3.8 73.1 2.8 78.7 13.3 88.4
8 2023H1 2022H1 42.3 -13.5 23.9 22.7 19.3 33.1 12.9 50.8
9 2023H2 2022H2 107.5 -65.2 45.5 -21.8 36.5 -16.9 24.1 -9.5
10 2024H1 2022FY 90.3 -42.7 71.9 -3.8 62.0 2.8 47.0 13.3
11 2024H2 2023H1 185.7 42.3 125.4 23.9 106.9 19.3 77.7 12.9
12 2025H1 2023H2 362.7 232.1 234.4 68.7 204.4 54.4 151.1 35.6
13 2025H2 2023FY 284.5 107.6 207.4 45.6 184.7 36.5 139.1 24.2
14 2026H1 2024H1 9.5 90.1 22.6 71.9 23.8 62.0 26.5 46.9
15 2024H2 264.1 167.3 143.2 103.7
16 2024FY 185.9 125.4 106.9 77.7
17 2025H1 362.8 234.4 204.4 151.1
18 2025H2 251.0 193.7 174.1 131.9
19 2025FY 284.5 207.4 184.7 139.1
20 2026H1 9.5 22.6 23.8 26.5
+7
View File
@@ -0,0 +1,7 @@
period,non_gaap_net_profit,gross_profit,revenue,cost
2020FY,30.9,46.2,49.3,55.0
2021FY,69.6,73.1,78.7,88.4
2022FY,-42.7,-3.8,2.8,13.3
2023FY,107.6,45.6,36.5,24.2
2024FY,185.9,125.4,106.9,77.7
2025FY,284.5,207.4,184.7,139.1
1 period non_gaap_net_profit gross_profit revenue cost
2 2020FY 30.9 46.2 49.3 55.0
3 2021FY 69.6 73.1 78.7 88.4
4 2022FY -42.7 -3.8 2.8 13.3
5 2023FY 107.6 45.6 36.5 24.2
6 2024FY 185.9 125.4 106.9 77.7
7 2025FY 284.5 207.4 184.7 139.1
+14
View File
@@ -0,0 +1,14 @@
period,non_gaap_net_profit,gross_profit,revenue,cost
2020H1,24.4,61.4,50.5,33.6
2020H2,33.1,39.6,48.7,67.0
2021H1,208.0,109.4,116.8,130.5
2021H2,26.1,54.8,60.3,69.5
2022H1,-13.5,22.7,33.1,50.8
2022H2,-65.2,-21.8,-16.9,-9.5
2023H1,42.3,23.9,19.3,12.9
2023H2,232.1,68.7,54.4,35.6
2024H1,90.1,71.9,62.0,46.9
2024H2,264.1,167.3,143.2,103.7
2025H1,362.8,234.4,204.4,151.1
2025H2,251.0,193.7,174.1,131.9
2026H1,9.5,22.6,23.8,26.5
1 period non_gaap_net_profit gross_profit revenue cost
2 2020H1 24.4 61.4 50.5 33.6
3 2020H2 33.1 39.6 48.7 67.0
4 2021H1 208.0 109.4 116.8 130.5
5 2021H2 26.1 54.8 60.3 69.5
6 2022H1 -13.5 22.7 33.1 50.8
7 2022H2 -65.2 -21.8 -16.9 -9.5
8 2023H1 42.3 23.9 19.3 12.9
9 2023H2 232.1 68.7 54.4 35.6
10 2024H1 90.1 71.9 62.0 46.9
11 2024H2 264.1 167.3 143.2 103.7
12 2025H1 362.8 234.4 204.4 151.1
13 2025H2 251.0 193.7 174.1 131.9
14 2026H1 9.5 22.6 23.8 26.5
+9 -9
View File
@@ -1,9 +1,9 @@
ip,2021H1,2021H2,2022H1,2022H2,2023H1,2023H2,2024H1,2024H2,2025H1,2025H2 ip,2021H1,2021H2,2021FY,2022H1,2022H2,2022FY,2023H1,2023H2,2023FY,2024H1,2024H2,2024FY,2025H1,2025H2,2025FY
THE MONSTERS,1.45789,1.58642,1.34887,1.28115,1.59829,2.08042,6.26806,24.13858,48.14017,93.47047 THE MONSTERS,1.45789,1.58642,3.04431,1.34887,1.28115,2.63002,1.59829,2.08042,3.67871,6.26806,24.13858,30.406640000000003,48.14017,93.47047,141.61064
MOLLY,2.039,5.01198,4.04347,3.97808,4.11433,6.08872,7.8216,13.11012,13.57248,15.39836 MOLLY,2.039,5.01198,7.050980000000001,4.04347,3.97808,8.02155,4.11433,6.08872,10.203050000000001,7.8216,13.11012,20.93172,13.57248,15.39836,28.970840000000003
SKULLPANDA,1.83042,4.12214,4.61766,3.89845,5.26383,4.98405,5.74562,7.337,12.20504,23.19038 SKULLPANDA,1.83042,4.12214,5.95256,4.61766,3.89845,8.51611,5.26383,4.98405,10.247879999999999,5.74562,7.337,13.082619999999999,12.20504,23.19038,35.39542
CRYBABY,0,0,0,0,0.26603,0.44546,3.49382,8.15503,12.1817,17.10836 CRYBABY,0,0,0,0,0,0,0.26603,0.44546,0.71149,3.49382,8.15503,11.64885,12.1817,17.10836,29.29006
DIMOO,2.04993,3.61742,2.98442,2.79506,3.62032,3.75634,3.77838,5.31723,11.05135,16.7156 DIMOO,2.04993,3.61742,5.66735,2.98442,2.79506,5.7794799999999995,3.62032,3.75634,7.376659999999999,3.77838,5.31723,9.09561,11.05135,16.7156,27.766949999999998
HIRONO-小野,0,0,0.37538,1.0323,1.09352,2.41849,2.45247,4.81278,7.2842,10.06815 HIRONO-小野,0,0,0,0.37538,1.0323,1.40768,1.09352,2.41849,3.51201,2.45247,4.81278,7.26525,7.2842,10.06815,17.35235
HACIPUPU,0,0,0,0.42797,0.69171,0.82587,0.94991,1.29297,3.32122,5.15899 HACIPUPU,0,0,0,0,0.42797,0.42797,0.69171,0.82587,1.5175800000000002,0.94991,1.29297,2.24288,3.32122,5.15899,8.48021
星星人,0,0,0,0,0,0,0,0,3.89363,16.66217 星星人,0,0,0,0,0,0,0,0,0,0,0,0,3.89363,16.66217,20.555799999999998
1 ip 2021H1 2021H2 2021FY 2022H1 2022H2 2022FY 2023H1 2023H2 2023FY 2024H1 2024H2 2024FY 2025H1 2025H2 2025FY
2 THE MONSTERS 1.45789 1.58642 3.04431 1.34887 1.28115 2.63002 1.59829 2.08042 3.67871 6.26806 24.13858 30.406640000000003 48.14017 93.47047 141.61064
3 MOLLY 2.039 5.01198 7.050980000000001 4.04347 3.97808 8.02155 4.11433 6.08872 10.203050000000001 7.8216 13.11012 20.93172 13.57248 15.39836 28.970840000000003
4 SKULLPANDA 1.83042 4.12214 5.95256 4.61766 3.89845 8.51611 5.26383 4.98405 10.247879999999999 5.74562 7.337 13.082619999999999 12.20504 23.19038 35.39542
5 CRYBABY 0 0 0 0 0 0 0.26603 0.44546 0.71149 3.49382 8.15503 11.64885 12.1817 17.10836 29.29006
6 DIMOO 2.04993 3.61742 5.66735 2.98442 2.79506 5.7794799999999995 3.62032 3.75634 7.376659999999999 3.77838 5.31723 9.09561 11.05135 16.7156 27.766949999999998
7 HIRONO-小野 0 0 0 0.37538 1.0323 1.40768 1.09352 2.41849 3.51201 2.45247 4.81278 7.26525 7.2842 10.06815 17.35235
8 HACIPUPU 0 0 0 0 0.42797 0.42797 0.69171 0.82587 1.5175800000000002 0.94991 1.29297 2.24288 3.32122 5.15899 8.48021
9 星星人 0 0 0 0 0 0 0 0 0 0 0 0 3.89363 16.66217 20.555799999999998
+9
View File
@@ -0,0 +1,9 @@
ip,2021FY,2022FY,2023FY,2024FY,2025FY
THE MONSTERS,3.04431,2.63002,3.67871,30.406640000000003,141.61064
MOLLY,7.050980000000001,8.02155,10.203050000000001,20.93172,28.970840000000003
SKULLPANDA,5.95256,8.51611,10.247879999999999,13.082619999999999,35.39542
CRYBABY,0,0,0.71149,11.64885,29.29006
DIMOO,5.66735,5.7794799999999995,7.376659999999999,9.09561,27.766949999999998
HIRONO-小野,0,1.40768,3.51201,7.26525,17.35235
HACIPUPU,0,0.42797,1.5175800000000002,2.24288,8.48021
星星人,0,0,0,0,20.555799999999998
1 ip 2021FY 2022FY 2023FY 2024FY 2025FY
2 THE MONSTERS 3.04431 2.63002 3.67871 30.406640000000003 141.61064
3 MOLLY 7.050980000000001 8.02155 10.203050000000001 20.93172 28.970840000000003
4 SKULLPANDA 5.95256 8.51611 10.247879999999999 13.082619999999999 35.39542
5 CRYBABY 0 0 0.71149 11.64885 29.29006
6 DIMOO 5.66735 5.7794799999999995 7.376659999999999 9.09561 27.766949999999998
7 HIRONO-小野 0 1.40768 3.51201 7.26525 17.35235
8 HACIPUPU 0 0.42797 1.5175800000000002 2.24288 8.48021
9 星星人 0 0 0 0 20.555799999999998
+5
View File
@@ -1,12 +1,17 @@
period,revenue,yoy period,revenue,yoy
2021H1,16.27, 2021H1,16.27,
2021H2,25.59, 2021H2,25.59,
2021FY,41.86,
2022H1,22.24,36.7 2022H1,22.24,36.7
2022H2,21.30,-16.8 2022H2,21.30,-16.8
2022FY,43.54,4.0
2023H1,26.54,19.3 2023H1,26.54,19.3
2023H2,32.79,53.9 2023H2,32.79,53.9
2023FY,59.33,36.3
2024H1,39.31,48.1 2024H1,39.31,48.1
2024H2,60.66,85.0 2024H2,60.66,85.0
2024FY,99.97,68.5
2025H1,90.62,130.5 2025H1,90.62,130.5
2025H2,138.97,129.1 2025H2,138.97,129.1
2025FY,229.59,129.7
2026H1,127.19,40.4 2026H1,127.19,40.4
1 period revenue yoy
2 2021H1 16.27
3 2021H2 25.59
4 2021FY 41.86
5 2022H1 22.24 36.7
6 2022H2 21.30 -16.8
7 2022FY 43.54 4.0
8 2023H1 26.54 19.3
9 2023H2 32.79 53.9
10 2023FY 59.33 36.3
11 2024H1 39.31 48.1
12 2024H2 60.66 85.0
13 2024FY 99.97 68.5
14 2025H1 90.62 130.5
15 2025H2 138.97 129.1
16 2025FY 229.59 129.7
17 2026H1 127.19 40.4
+6
View File
@@ -0,0 +1,6 @@
period,revenue,yoy
2021FY,41.86,
2022FY,43.54,4.0
2023FY,59.33,36.3
2024FY,99.97,68.5
2025FY,229.59,129.7
1 period revenue yoy
2 2021FY 41.86
3 2022FY 43.54 4.0
4 2023FY 59.33 36.3
5 2024FY 99.97 68.5
6 2025FY 229.59 129.7
@@ -0,0 +1,12 @@
period,revenue,yoy
2021H1,16.27,
2021H2,25.59,
2022H1,22.24,36.7
2022H2,21.30,-16.8
2023H1,26.54,19.3
2023H2,32.79,53.9
2024H1,39.31,48.1
2024H2,60.66,85.0
2025H1,90.62,130.5
2025H2,138.97,129.1
2026H1,127.19,40.4
1 period revenue yoy
2 2021H1 16.27
3 2021H2 25.59
4 2022H1 22.24 36.7
5 2022H2 21.30 -16.8
6 2023H1 26.54 19.3
7 2023H2 32.79 53.9
8 2024H1 39.31 48.1
9 2024H2 60.66 85.0
10 2025H1 90.62 130.5
11 2025H2 138.97 129.1
12 2026H1 127.19 40.4
+9
View File
@@ -0,0 +1,9 @@
ip,2021H1,2021H2,2022H1,2022H2,2023H1,2023H2,2024H1,2024H2,2025H1,2025H2
THE MONSTERS,1.45789,1.58642,1.34887,1.28115,1.59829,2.08042,6.26806,24.13858,48.14017,93.47047
MOLLY,2.039,5.01198,4.04347,3.97808,4.11433,6.08872,7.8216,13.11012,13.57248,15.39836
SKULLPANDA,1.83042,4.12214,4.61766,3.89845,5.26383,4.98405,5.74562,7.337,12.20504,23.19038
CRYBABY,0,0,0,0,0.26603,0.44546,3.49382,8.15503,12.1817,17.10836
DIMOO,2.04993,3.61742,2.98442,2.79506,3.62032,3.75634,3.77838,5.31723,11.05135,16.7156
HIRONO-小野,0,0,0.37538,1.0323,1.09352,2.41849,2.45247,4.81278,7.2842,10.06815
HACIPUPU,0,0,0,0.42797,0.69171,0.82587,0.94991,1.29297,3.32122,5.15899
星星人,0,0,0,0,0,0,0,0,3.89363,16.66217
1 ip 2021H1 2021H2 2022H1 2022H2 2023H1 2023H2 2024H1 2024H2 2025H1 2025H2
2 THE MONSTERS 1.45789 1.58642 1.34887 1.28115 1.59829 2.08042 6.26806 24.13858 48.14017 93.47047
3 MOLLY 2.039 5.01198 4.04347 3.97808 4.11433 6.08872 7.8216 13.11012 13.57248 15.39836
4 SKULLPANDA 1.83042 4.12214 4.61766 3.89845 5.26383 4.98405 5.74562 7.337 12.20504 23.19038
5 CRYBABY 0 0 0 0 0.26603 0.44546 3.49382 8.15503 12.1817 17.10836
6 DIMOO 2.04993 3.61742 2.98442 2.79506 3.62032 3.75634 3.77838 5.31723 11.05135 16.7156
7 HIRONO-小野 0 0 0.37538 1.0323 1.09352 2.41849 2.45247 4.81278 7.2842 10.06815
8 HACIPUPU 0 0 0 0.42797 0.69171 0.82587 0.94991 1.29297 3.32122 5.15899
9 星星人 0 0 0 0 0 0 0 0 3.89363 16.66217
+12 -12
View File
@@ -1,12 +1,12 @@
ip,2021H1,2021H2,2022H1,2022H2,2023H1,2023H2,2024H1,2024H2,2025H1,2025H2,2026H1 ip,2021H1,2021H2,2021FY,2022H1,2022H2,2022FY,2023H1,2023H2,2023FY,2024H1,2024H2,2024FY,2025H1,2025H2,2025FY,2026H1
THE MONSTERS,1.46,1.59,1.35,1.28,1.60,2.08,6.27,24.14,48.14,93.47,44.54 THE MONSTERS,1.46,1.59,3.05,1.35,1.28,2.63,1.6,2.08,3.68,6.27,24.14,30.41,48.14,93.47,141.61,44.54
星星人,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,3.89,16.66,26.50 星星人,0,0,0,0,0,0,0,0,0,0,0,0,3.89,16.66,20.55,26.5
授权IP(非独家),2.88,3.33,3.01,2.50,4.22,6.14,6.95,9.06,15.25,18.57,17.71 授权IP(非独家),2.88,3.33,6.21,3.01,2.5,5.51,4.22,6.14,10.36,6.95,9.06,16.01,15.25,18.57,33.82,17.71
CRYBABY,0.00,0.00,0.00,0.00,0.27,0.45,3.49,8.16,12.18,17.11,16.33 CRYBABY,0,0,0,0,0,0,0.27,0.45,0.72,3.49,8.16,11.65,12.18,17.11,29.29,16.33
DIMOO,2.05,3.62,2.98,2.80,3.62,3.76,3.78,5.32,11.05,16.72,16.19 DIMOO,2.05,3.62,5.67,2.98,2.8,5.779999999999999,3.62,3.76,7.38,3.78,5.32,9.1,11.05,16.72,27.77,16.19
SKULLPANDA,1.83,4.12,4.62,3.90,5.26,4.98,5.75,7.34,12.21,23.19,15.51 SKULLPANDA,1.83,4.12,5.95,4.62,3.9,8.52,5.26,4.98,10.24,5.75,7.34,13.09,12.21,23.19,35.400000000000006,15.51
其他艺术家IP,1.43,2.47,4.37,3.00,4.54,5.44,6.37,7.72,10.64,14.00,11.74 其他艺术家IP,1.43,2.47,3.9000000000000004,4.37,3,7.37,4.54,5.44,9.98,6.37,7.72,14.09,10.64,14,24.64,11.74
HIRONO-小野,0.00,0.00,0.38,1.03,1.09,2.42,2.45,4.81,7.28,10.07,10.09 HIRONO-小野,0,0,0,0.38,1.03,1.4100000000000001,1.09,2.42,3.51,2.45,4.81,7.26,7.28,10.07,17.35,10.09
MOLLY,2.04,5.01,4.04,3.98,4.11,6.09,7.82,13.11,13.57,15.40,9.01 MOLLY,2.04,5.01,7.05,4.04,3.98,8.02,4.11,6.09,10.2,7.82,13.11,20.93,13.57,15.4,28.97,9.01
其他IP(含已停单列),4.14,4.51,0.81,1.86,1.15,1.37,0.95,3.74,3.32,5.16,2.98 其他IP(含已停单列),4.14,4.51,8.649999999999999,0.81,1.86,2.67,1.15,1.37,2.52,0.95,3.74,4.69,3.32,5.16,8.48,2.98
外采及其他,1.90,2.53,2.03,2.24,2.28,2.15,1.75,1.41,1.23,2.09,1.12 外采及其他,1.9,2.53,4.43,2.03,2.24,4.27,2.28,2.15,4.43,1.75,1.41,3.16,1.23,2.09,3.32,1.12
1 ip 2021H1 2021H2 2021FY 2022H1 2022H2 2022FY 2023H1 2023H2 2023FY 2024H1 2024H2 2024FY 2025H1 2025H2 2025FY 2026H1
2 THE MONSTERS 1.46 1.59 3.05 1.35 1.28 2.63 1.60 1.6 2.08 3.68 6.27 24.14 30.41 48.14 93.47 141.61 44.54
3 星星人 0.00 0 0.00 0 0 0.00 0 0.00 0 0 0.00 0 0.00 0 0 0.00 0 0.00 0 0 3.89 16.66 20.55 26.50 26.5
4 授权IP(非独家) 2.88 3.33 6.21 3.01 2.50 2.5 5.51 4.22 6.14 10.36 6.95 9.06 16.01 15.25 18.57 33.82 17.71
5 CRYBABY 0.00 0 0.00 0 0 0.00 0 0.00 0 0 0.27 0.45 0.72 3.49 8.16 11.65 12.18 17.11 29.29 16.33
6 DIMOO 2.05 3.62 5.67 2.98 2.80 2.8 5.779999999999999 3.62 3.76 7.38 3.78 5.32 9.1 11.05 16.72 27.77 16.19
7 SKULLPANDA 1.83 4.12 5.95 4.62 3.90 3.9 8.52 5.26 4.98 10.24 5.75 7.34 13.09 12.21 23.19 35.400000000000006 15.51
8 其他艺术家IP 1.43 2.47 3.9000000000000004 4.37 3.00 3 7.37 4.54 5.44 9.98 6.37 7.72 14.09 10.64 14.00 14 24.64 11.74
9 HIRONO-小野 0.00 0 0.00 0 0 0.38 1.03 1.4100000000000001 1.09 2.42 3.51 2.45 4.81 7.26 7.28 10.07 17.35 10.09
10 MOLLY 2.04 5.01 7.05 4.04 3.98 8.02 4.11 6.09 10.2 7.82 13.11 20.93 13.57 15.40 15.4 28.97 9.01
11 其他IP(含已停单列) 4.14 4.51 8.649999999999999 0.81 1.86 2.67 1.15 1.37 2.52 0.95 3.74 4.69 3.32 5.16 8.48 2.98
12 外采及其他 1.90 1.9 2.53 4.43 2.03 2.24 4.27 2.28 2.15 4.43 1.75 1.41 3.16 1.23 2.09 3.32 1.12
@@ -0,0 +1,12 @@
ip,2021FY,2022FY,2023FY,2024FY,2025FY
THE MONSTERS,3.05,2.63,3.68,30.41,141.61
星星人,0,0,0,0,20.55
授权IP(非独家),6.21,5.51,10.36,16.01,33.82
CRYBABY,0,0,0.72,11.65,29.29
DIMOO,5.67,5.779999999999999,7.38,9.1,27.77
SKULLPANDA,5.95,8.52,10.24,13.09,35.400000000000006
其他艺术家IP,3.9000000000000004,7.37,9.98,14.09,24.64
HIRONO-小野,0,1.4100000000000001,3.51,7.26,17.35
MOLLY,7.05,8.02,10.2,20.93,28.97
其他IP(含已停单列),8.649999999999999,2.67,2.52,4.69,8.48
外采及其他,4.43,4.27,4.43,3.16,3.32
1 ip 2021FY 2022FY 2023FY 2024FY 2025FY
2 THE MONSTERS 3.05 2.63 3.68 30.41 141.61
3 星星人 0 0 0 0 20.55
4 授权IP(非独家) 6.21 5.51 10.36 16.01 33.82
5 CRYBABY 0 0 0.72 11.65 29.29
6 DIMOO 5.67 5.779999999999999 7.38 9.1 27.77
7 SKULLPANDA 5.95 8.52 10.24 13.09 35.400000000000006
8 其他艺术家IP 3.9000000000000004 7.37 9.98 14.09 24.64
9 HIRONO-小野 0 1.4100000000000001 3.51 7.26 17.35
10 MOLLY 7.05 8.02 10.2 20.93 28.97
11 其他IP(含已停单列) 8.649999999999999 2.67 2.52 4.69 8.48
12 外采及其他 4.43 4.27 4.43 3.16 3.32
@@ -0,0 +1,12 @@
ip,2021H1,2021H2,2022H1,2022H2,2023H1,2023H2,2024H1,2024H2,2025H1,2025H2,2026H1
THE MONSTERS,1.46,1.59,1.35,1.28,1.6,2.08,6.27,24.14,48.14,93.47,44.54
星星人,0,0,0,0,0,0,0,0,3.89,16.66,26.5
授权IP(非独家),2.88,3.33,3.01,2.5,4.22,6.14,6.95,9.06,15.25,18.57,17.71
CRYBABY,0,0,0,0,0.27,0.45,3.49,8.16,12.18,17.11,16.33
DIMOO,2.05,3.62,2.98,2.8,3.62,3.76,3.78,5.32,11.05,16.72,16.19
SKULLPANDA,1.83,4.12,4.62,3.9,5.26,4.98,5.75,7.34,12.21,23.19,15.51
其他艺术家IP,1.43,2.47,4.37,3,4.54,5.44,6.37,7.72,10.64,14,11.74
HIRONO-小野,0,0,0.38,1.03,1.09,2.42,2.45,4.81,7.28,10.07,10.09
MOLLY,2.04,5.01,4.04,3.98,4.11,6.09,7.82,13.11,13.57,15.4,9.01
其他IP(含已停单列),4.14,4.51,0.81,1.86,1.15,1.37,0.95,3.74,3.32,5.16,2.98
外采及其他,1.9,2.53,2.03,2.24,2.28,2.15,1.75,1.41,1.23,2.09,1.12
1 ip 2021H1 2021H2 2022H1 2022H2 2023H1 2023H2 2024H1 2024H2 2025H1 2025H2 2026H1
2 THE MONSTERS 1.46 1.59 1.35 1.28 1.6 2.08 6.27 24.14 48.14 93.47 44.54
3 星星人 0 0 0 0 0 0 0 0 3.89 16.66 26.5
4 授权IP(非独家) 2.88 3.33 3.01 2.5 4.22 6.14 6.95 9.06 15.25 18.57 17.71
5 CRYBABY 0 0 0 0 0.27 0.45 3.49 8.16 12.18 17.11 16.33
6 DIMOO 2.05 3.62 2.98 2.8 3.62 3.76 3.78 5.32 11.05 16.72 16.19
7 SKULLPANDA 1.83 4.12 4.62 3.9 5.26 4.98 5.75 7.34 12.21 23.19 15.51
8 其他艺术家IP 1.43 2.47 4.37 3 4.54 5.44 6.37 7.72 10.64 14 11.74
9 HIRONO-小野 0 0 0.38 1.03 1.09 2.42 2.45 4.81 7.28 10.07 10.09
10 MOLLY 2.04 5.01 4.04 3.98 4.11 6.09 7.82 13.11 13.57 15.4 9.01
11 其他IP(含已停单列) 4.14 4.51 0.81 1.86 1.15 1.37 0.95 3.74 3.32 5.16 2.98
12 外采及其他 1.9 2.53 2.03 2.24 2.28 2.15 1.75 1.41 1.23 2.09 1.12
+6 -6
View File
@@ -1,14 +1,14 @@
period,cash,total_liabilities,net_working_capital period,cash,total_liabilities,net_working_capital
2020H1,8.22,5.47,8.66 2020H1,8.22,5.47,8.66
2020FY,56.80,8.40,55.91 2020H2,56.80,8.40,55.91
2021H1,57.67,13.26,55.92 2021H1,57.67,13.26,55.92
2021FY,52.65,15.04,56.65 2021H2,52.65,15.04,56.65
2022H1,51.63,14.76,58.16 2022H1,51.63,14.76,58.16
2022FY,50.42,16.15,54.85 2022H2,50.42,16.15,54.85
2023H1,55.40,17.59,57.33 2023H1,55.40,17.59,57.33
2023FY,59.63,21.88,59.50 2023H2,59.63,21.88,59.50
2024H1,70.10,25.65,66.47 2024H1,70.10,25.65,66.47
2024FY,96.20,39.86,88.66 2024H2,96.20,39.86,88.66
2025H1,137.66,69.27,119.27 2025H1,137.66,69.27,119.27
2025FY,172.25,94.49,177.46 2025H2,172.25,94.49,177.46
2026H1,139.62,77.40,174.20 2026H1,139.62,77.40,174.20
1 period cash total_liabilities net_working_capital
2 2020H1 8.22 5.47 8.66
3 2020FY 2020H2 56.80 8.40 55.91
4 2021H1 57.67 13.26 55.92
5 2021FY 2021H2 52.65 15.04 56.65
6 2022H1 51.63 14.76 58.16
7 2022FY 2022H2 50.42 16.15 54.85
8 2023H1 55.40 17.59 57.33
9 2023FY 2023H2 59.63 21.88 59.50
10 2024H1 70.10 25.65 66.47
11 2024FY 2024H2 96.20 39.86 88.66
12 2025H1 137.66 69.27 119.27
13 2025FY 2025H2 172.25 94.49 177.46
14 2026H1 139.62 77.40 174.20
@@ -0,0 +1,7 @@
period,cash,total_liabilities,net_working_capital
2020FY,56.80,8.40,55.91
2021FY,52.65,15.04,56.65
2022FY,50.42,16.15,54.85
2023FY,59.63,21.88,59.50
2024FY,96.20,39.86,88.66
2025FY,172.25,94.49,177.46
1 period cash total_liabilities net_working_capital
2 2020FY 56.80 8.40 55.91
3 2021FY 52.65 15.04 56.65
4 2022FY 50.42 16.15 54.85
5 2023FY 59.63 21.88 59.50
6 2024FY 96.20 39.86 88.66
7 2025FY 172.25 94.49 177.46
@@ -0,0 +1,14 @@
period,cash,total_liabilities,net_working_capital
2020H1,8.22,5.47,8.66
2020H2,56.80,8.40,55.91
2021H1,57.67,13.26,55.92
2021H2,52.65,15.04,56.65
2022H1,51.63,14.76,58.16
2022H2,50.42,16.15,54.85
2023H1,55.40,17.59,57.33
2023H2,59.63,21.88,59.50
2024H1,70.10,25.65,66.47
2024H2,96.20,39.86,88.66
2025H1,137.66,69.27,119.27
2025H2,172.25,94.49,177.46
2026H1,139.62,77.40,174.20
1 period cash total_liabilities net_working_capital
2 2020H1 8.22 5.47 8.66
3 2020H2 56.80 8.40 55.91
4 2021H1 57.67 13.26 55.92
5 2021H2 52.65 15.04 56.65
6 2022H1 51.63 14.76 58.16
7 2022H2 50.42 16.15 54.85
8 2023H1 55.40 17.59 57.33
9 2023H2 59.63 21.88 59.50
10 2024H1 70.10 25.65 66.47
11 2024H2 96.20 39.86 88.66
12 2025H1 137.66 69.27 119.27
13 2025H2 172.25 94.49 177.46
14 2026H1 139.62 77.40 174.20
+20 -14
View File
@@ -1,14 +1,20 @@
period,gross_margin,sales_expense_rate,admin_expense_rate,non_gaap_net_margin period,gross_margin,sales_expense_rate,admin_expense_rate,non_gaap_net_margin
2020H1,65.23,27.27,15.33,17.24 2020H1,65.23,27.27,15.33,17.28
2020H2,63.42,25.07,11.14,23.52 2020H2,62.55,24.00,9.12,26.49
2021H1,63.02,23.68,13.52,24.53 2020FY,63.42,25.07,11.14,23.49
2021H2,61.43,24.63,12.41,22.31 2021H1,63.02,23.68,13.52,24.55
2022H1,58.1,29.39,13.68,15.94 2021H2,60.39,25.25,11.69,20.84
2022H2,57.49,31.85,14.86,12.43 2021FY,61.43,24.63,12.41,22.30
2023H1,60.36,31.21,11.77,19.01 2022H1,58.10,29.39,13.68,15.95
2023H2,61.32,31.82,11.23,18.9 2022H2,56.86,34.43,16.10,8.73
2024H1,64.05,29.69,9.53,22.33 2022FY,57.49,31.85,14.86,12.42
2024H2,66.79,28.0,7.26,26.1 2023H1,60.36,31.21,11.77,19.03
2025H1,70.34,23.01,5.55,33.94 2023H2,62.10,32.30,10.78,18.79
2025H2,72.1,21.77,4.77,35.25 2023FY,61.32,31.82,11.23,18.89
2026H1,69.68,22.89,5.4,30.02 2024H1,64.05,29.69,9.53,22.33
2024H2,68.26,27.09,6.05,28.13
2024FY,66.79,28.00,7.26,26.10
2025H1,70.34,23.01,5.55,33.94
2025H2,73.15,21.04,4.30,36.03
2025FY,72.10,21.77,4.77,35.25
2026H1,69.68,22.89,5.40,30.02
1 period gross_margin sales_expense_rate admin_expense_rate non_gaap_net_margin
2 2020H1 65.23 27.27 15.33 17.24 17.28
3 2020H2 63.42 62.55 25.07 24.00 11.14 9.12 23.52 26.49
4 2021H1 2020FY 63.02 63.42 23.68 25.07 13.52 11.14 24.53 23.49
5 2021H2 2021H1 61.43 63.02 24.63 23.68 12.41 13.52 22.31 24.55
6 2022H1 2021H2 58.1 60.39 29.39 25.25 13.68 11.69 15.94 20.84
7 2022H2 2021FY 57.49 61.43 31.85 24.63 14.86 12.41 12.43 22.30
8 2023H1 2022H1 60.36 58.10 31.21 29.39 11.77 13.68 19.01 15.95
9 2023H2 2022H2 61.32 56.86 31.82 34.43 11.23 16.10 18.9 8.73
10 2024H1 2022FY 64.05 57.49 29.69 31.85 9.53 14.86 22.33 12.42
11 2024H2 2023H1 66.79 60.36 28.0 31.21 7.26 11.77 26.1 19.03
12 2025H1 2023H2 70.34 62.10 23.01 32.30 5.55 10.78 33.94 18.79
13 2025H2 2023FY 72.1 61.32 21.77 31.82 4.77 11.23 35.25 18.89
14 2026H1 2024H1 69.68 64.05 22.89 29.69 5.4 9.53 30.02 22.33
15 2024H2 68.26 27.09 6.05 28.13
16 2024FY 66.79 28.00 7.26 26.10
17 2025H1 70.34 23.01 5.55 33.94
18 2025H2 73.15 21.04 4.30 36.03
19 2025FY 72.10 21.77 4.77 35.25
20 2026H1 69.68 22.89 5.40 30.02
+7
View File
@@ -0,0 +1,7 @@
period,gross_margin,sales_expense_rate,admin_expense_rate,non_gaap_net_margin
2020FY,63.42,25.07,11.14,23.49
2021FY,61.43,24.63,12.41,22.30
2022FY,57.49,31.85,14.86,12.42
2023FY,61.32,31.82,11.23,18.89
2024FY,66.79,28.00,7.26,26.10
2025FY,72.10,21.77,4.77,35.25
1 period gross_margin sales_expense_rate admin_expense_rate non_gaap_net_margin
2 2020FY 63.42 25.07 11.14 23.49
3 2021FY 61.43 24.63 12.41 22.30
4 2022FY 57.49 31.85 14.86 12.42
5 2023FY 61.32 31.82 11.23 18.89
6 2024FY 66.79 28.00 7.26 26.10
7 2025FY 72.10 21.77 4.77 35.25
+14
View File
@@ -0,0 +1,14 @@
period,gross_margin,sales_expense_rate,admin_expense_rate,non_gaap_net_margin
2020H1,65.23,27.27,15.33,17.28
2020H2,62.55,24.00,9.12,26.49
2021H1,63.02,23.68,13.52,24.55
2021H2,60.39,25.25,11.69,20.84
2022H1,58.10,29.39,13.68,15.95
2022H2,56.86,34.43,16.10,8.73
2023H1,60.36,31.21,11.77,19.03
2023H2,62.10,32.30,10.78,18.79
2024H1,64.05,29.69,9.53,22.33
2024H2,68.26,27.09,6.05,28.13
2025H1,70.34,23.01,5.55,33.94
2025H2,73.15,21.04,4.30,36.03
2026H1,69.68,22.89,5.40,30.02
1 period gross_margin sales_expense_rate admin_expense_rate non_gaap_net_margin
2 2020H1 65.23 27.27 15.33 17.28
3 2020H2 62.55 24.00 9.12 26.49
4 2021H1 63.02 23.68 13.52 24.55
5 2021H2 60.39 25.25 11.69 20.84
6 2022H1 58.10 29.39 13.68 15.95
7 2022H2 56.86 34.43 16.10 8.73
8 2023H1 60.36 31.21 11.77 19.03
9 2023H2 62.10 32.30 10.78 18.79
10 2024H1 64.05 29.69 9.53 22.33
11 2024H2 68.26 27.09 6.05 28.13
12 2025H1 70.34 23.01 5.55 33.94
13 2025H2 73.15 21.04 4.30 36.03
14 2026H1 69.68 22.89 5.40 30.02
+20 -18
View File
@@ -1,18 +1,20 @@
period,revenue,gross_profit,gross_margin,net_profit period,revenue,gross_profit,gross_margin,net_profit
2026H1,171.73,119.66,69.67999999999999,50.38 2020H1,8.18,5.33,65.23,1.41
2025H2,371.2,267.65,72.1,127.76 2020H2,16.96,10.61,62.55,3.82
2025H1,138.76,97.61,70.34,45.74 2020FY,25.13,15.94,63.42,5.23
2024H2,130.38,87.08,66.79,31.25 2021H1,17.73,11.17,63.02,3.59
2024H1,45.58,29.19,64.05,9.21 2021H2,27.18,16.42,60.39,4.96
2023H2,63.01,38.64,61.31999999999999,10.82 2021FY,44.91,27.59,61.43,8.55
2023H1,28.14,16.98,60.36,4.77 2022H1,23.59,13.70,58.10,3.33
2022H2,46.17,26.55,57.489999999999995,4.76 2022H2,22.59,12.84,56.86,1.43
2022H1,23.59,13.7,58.099999999999994,3.33 2022FY,46.17,26.55,57.49,4.76
2021H2,44.91,27.59,61.42999999999999,8.54 2023H1,28.14,16.98,60.36,4.77
2021H1,17.73,11.17,63.019999999999996,3.59 2023H2,34.87,21.66,62.10,6.12
2020H2,25.13,15.94,63.42,5.24 2023FY,63.01,38.64,61.32,10.89
2020H1,8.18,5.33,65.23,1.41 2024H1,45.58,29.19,64.05,9.64
2019H2,16.83,10.9,64.77000000000001,4.51 2024H2,84.80,57.89,68.26,23.44
2019H1,5.43,3.31,60.84,1.14 2024FY,130.38,87.08,66.79,33.08
2018H2,5.15,2.98,57.92,1 2025H1,138.76,97.61,70.34,46.82
2017H2,1.58,0.75,47.61,0.02 2025H2,232.44,170.04,73.15,83.30
2025FY,371.20,267.65,72.10,130.12
2026H1,171.73,119.66,69.68,51.00
1 period revenue gross_profit gross_margin net_profit
2 2026H1 2020H1 171.73 8.18 119.66 5.33 69.67999999999999 65.23 50.38 1.41
3 2025H2 2020H2 371.2 16.96 267.65 10.61 72.1 62.55 127.76 3.82
4 2025H1 2020FY 138.76 25.13 97.61 15.94 70.34 63.42 45.74 5.23
5 2024H2 2021H1 130.38 17.73 87.08 11.17 66.79 63.02 31.25 3.59
6 2024H1 2021H2 45.58 27.18 29.19 16.42 64.05 60.39 9.21 4.96
7 2023H2 2021FY 63.01 44.91 38.64 27.59 61.31999999999999 61.43 10.82 8.55
8 2023H1 2022H1 28.14 23.59 16.98 13.70 60.36 58.10 4.77 3.33
9 2022H2 46.17 22.59 26.55 12.84 57.489999999999995 56.86 4.76 1.43
10 2022H1 2022FY 23.59 46.17 13.7 26.55 58.099999999999994 57.49 3.33 4.76
11 2021H2 2023H1 44.91 28.14 27.59 16.98 61.42999999999999 60.36 8.54 4.77
12 2021H1 2023H2 17.73 34.87 11.17 21.66 63.019999999999996 62.10 3.59 6.12
13 2020H2 2023FY 25.13 63.01 15.94 38.64 63.42 61.32 5.24 10.89
14 2020H1 2024H1 8.18 45.58 5.33 29.19 65.23 64.05 1.41 9.64
15 2019H2 2024H2 16.83 84.80 10.9 57.89 64.77000000000001 68.26 4.51 23.44
16 2019H1 2024FY 5.43 130.38 3.31 87.08 60.84 66.79 1.14 33.08
17 2018H2 2025H1 5.15 138.76 2.98 97.61 57.92 70.34 1 46.82
18 2017H2 2025H2 1.58 232.44 0.75 170.04 47.61 73.15 0.02 83.30
19 2025FY 371.20 267.65 72.10 130.12
20 2026H1 171.73 119.66 69.68 51.00
+7
View File
@@ -0,0 +1,7 @@
period,revenue,gross_profit,gross_margin,net_profit
2020FY,25.13,15.94,63.42,5.23
2021FY,44.91,27.59,61.43,8.55
2022FY,46.17,26.55,57.49,4.76
2023FY,63.01,38.64,61.32,10.89
2024FY,130.38,87.08,66.79,33.08
2025FY,371.20,267.65,72.10,130.12
1 period revenue gross_profit gross_margin net_profit
2 2020FY 25.13 15.94 63.42 5.23
3 2021FY 44.91 27.59 61.43 8.55
4 2022FY 46.17 26.55 57.49 4.76
5 2023FY 63.01 38.64 61.32 10.89
6 2024FY 130.38 87.08 66.79 33.08
7 2025FY 371.20 267.65 72.10 130.12
+14
View File
@@ -0,0 +1,14 @@
period,revenue,gross_profit,gross_margin,net_profit
2020H1,8.18,5.33,65.23,1.41
2020H2,16.96,10.61,62.55,3.82
2021H1,17.73,11.17,63.02,3.59
2021H2,27.18,16.42,60.39,4.96
2022H1,23.59,13.70,58.10,3.33
2022H2,22.59,12.84,56.86,1.43
2023H1,28.14,16.98,60.36,4.77
2023H2,34.87,21.66,62.10,6.12
2024H1,45.58,29.19,64.05,9.64
2024H2,84.80,57.89,68.26,23.44
2025H1,138.76,97.61,70.34,46.82
2025H2,232.44,170.04,73.15,83.30
2026H1,171.73,119.66,69.68,51.00
1 period revenue gross_profit gross_margin net_profit
2 2020H1 8.18 5.33 65.23 1.41
3 2020H2 16.96 10.61 62.55 3.82
4 2021H1 17.73 11.17 63.02 3.59
5 2021H2 27.18 16.42 60.39 4.96
6 2022H1 23.59 13.70 58.10 3.33
7 2022H2 22.59 12.84 56.86 1.43
8 2023H1 28.14 16.98 60.36 4.77
9 2023H2 34.87 21.66 62.10 6.12
10 2024H1 45.58 29.19 64.05 9.64
11 2024H2 84.80 57.89 68.26 23.44
12 2025H1 138.76 97.61 70.34 46.82
13 2025H2 232.44 170.04 73.15 83.30
14 2026H1 171.73 119.66 69.68 51.00
+3 -1
View File
@@ -147,7 +147,9 @@ js/main.js + js/ui.js ← 解析引用、渲染三栏、导出和
} }
``` ```
页面仅在声明多个视图时显示切换按钮,并将选择写入 URL query。当前泡泡玛特图表没有强制启用这一功能;基础能力已保留,等真实数据需要时再登记。 页面仅在声明多个视图时显示切换按钮,并将选择写入 URL query;尚未启用多视图的图表维持单一 CSV,不显示控制器。
泡泡玛特已在 15 张连续图启用该能力:盈利能力、营收到利润的增速对比、核心利润及同比增速、核心利润率、利润率与费用率拆解、资产结构演变、主要 IP 收入趋势、各 IP 收入占比、除 THE MONSTERS 外 IP 收入及同比、品类收入结构、经营现金流与净利润、现金/负债/净营运资本、三大现金流与现金净增加、费用结构与费用率、渠道收入结构与增速。默认显示“全部”,并提供“年度 / 半年”;其原始披露没有可靠 Q1/Q3 数据,故不展示“季度”。其中 `FY` 为全年、`H1/H2` 为单独半年,流量类指标的 H2 在数据归一化阶段由 `FY − H1` 生成,比率与同比也在数据层重算;资产负债表类则为期末余额,H2 对应年末时点而非累计金额。
--- ---
+6 -5
View File
@@ -1,6 +1,7 @@
import { col } from '../csv.js'; import { col } from '../csv.js';
import { import {
PALETTE, FONT, axisCommon, periodAxis, titleStyle, legendStyle, PALETTE, FONT, axisCommon, standalonePeriodAxis, titleStyle, legendStyle,
financialViewLabel,
lineSeries, footnote, watermarks, LAYOUT, lineSeries, footnote, watermarks, LAYOUT,
} from '../theme.js'; } from '../theme.js';
@@ -8,15 +9,15 @@ import {
* 泡泡玛特资产结构演变图 * 泡泡玛特资产结构演变图
* 堆叠柱状图展示资产配置,折线图展示总资产增长 * 堆叠柱状图展示资产配置,折线图展示总资产增长
*/ */
export function assetsChart(rows, { width, height }) { export function assetsChart(rows, { width, height, view = 'all' }) {
const periods = col(rows, 'period'); const periods = col(rows, 'period');
return { return {
backgroundColor: '#fff', backgroundColor: '#fff',
title: { title: {
...titleStyle, ...titleStyle,
text: '泡泡玛特资产结构演变(2020H1-2026H1)', text: `泡泡玛特资产结构演变(${financialViewLabel(view)})`,
subtext: '单位:亿元', subtext: '单位:亿元;资产负债表为期末余额,H2 为年末时点而非全年累计',
}, },
legend: { legend: {
...legendStyle, ...legendStyle,
@@ -29,7 +30,7 @@ export function assetsChart(rows, { width, height }) {
axisPointer: { type: 'shadow' }, axisPointer: { type: 'shadow' },
textStyle: { fontFamily: FONT }, textStyle: { fontFamily: FONT },
}, },
xAxis: { ...periodAxis, data: periods }, xAxis: { ...standalonePeriodAxis, data: periods },
yAxis: [ yAxis: [
{ {
...axisCommon, ...axisCommon,
+14 -10
View File
@@ -1,19 +1,23 @@
import { col } from '../csv.js'; import { col } from '../csv.js';
import { import {
FINANCIAL_COLORS, PALETTE, FONT, axisCommon, periodAxis, titleStyle, legendStyle, FINANCIAL_COLORS, PALETTE, FONT, axisCommon, standalonePeriodAxis, titleStyle, legendStyle,
financialViewDisclosure, financialViewLabel,
lineSeries, footnote, watermarks, LAYOUT, lineSeries, footnote, watermarks, LAYOUT,
} from '../theme.js'; } from '../theme.js';
/** 泡泡玛特经营现金流与净利润:观察利润的现金兑现能力。 */ /** 泡泡玛特经营现金流与净利润:观察利润的现金兑现能力。 */
export function cashConversionChart(rows, { width, height }) { export function cashConversionChart(rows, { width, height, view = 'all' }) {
const periods = col(rows, 'period'); const periods = col(rows, 'period');
const conversionMax = Math.max(...col(rows, 'cash_conversion').filter(Number.isFinite));
const conversionAxisMax = Math.max(200, Math.ceil((conversionMax * 1.1) / 100) * 100);
const barWidth = view === 'all' ? 14 : view === 'halfyear' ? 24.96 : 31.2;
return { return {
backgroundColor: '#fff', backgroundColor: '#fff',
title: { title: {
...titleStyle, ...titleStyle,
text: '泡泡玛特经营现金流与净利润(年度)', text: `泡泡玛特经营现金流与净利润(${financialViewLabel(view)})`,
subtext: '现金转换率 = 经营活动现金流净额 / 净利润;单位:亿元', subtext: ['现金转换率 = 经营活动现金流净额 / 净利润;单位:亿元', financialViewDisclosure(view)].filter(Boolean).join('\n'),
}, },
legend: { legend: {
...legendStyle, ...legendStyle,
@@ -27,7 +31,7 @@ export function cashConversionChart(rows, { width, height }) {
textStyle: { fontFamily: FONT }, textStyle: { fontFamily: FONT },
valueFormatter: (value) => `${value.toFixed(1)}`, valueFormatter: (value) => `${value.toFixed(1)}`,
}, },
xAxis: { ...periodAxis, data: periods }, xAxis: { ...standalonePeriodAxis, data: periods },
yAxis: [ yAxis: [
{ {
...axisCommon, ...axisCommon,
@@ -48,8 +52,8 @@ export function cashConversionChart(rows, { width, height }) {
nameRotate: -90, nameRotate: -90,
nameTextStyle: { color: PALETTE.grey, fontSize: 13, fontFamily: FONT }, nameTextStyle: { color: PALETTE.grey, fontSize: 13, fontFamily: FONT },
min: 0, min: 0,
max: 200, max: conversionAxisMax,
interval: 50, interval: conversionAxisMax / 4,
axisLabel: { ...axisCommon.axisLabel, formatter: '{value}%' }, axisLabel: { ...axisCommon.axisLabel, formatter: '{value}%' },
splitLine: { show: false }, splitLine: { show: false },
}, },
@@ -59,7 +63,7 @@ export function cashConversionChart(rows, { width, height }) {
name: '经营活动现金流净额', name: '经营活动现金流净额',
type: 'bar', type: 'bar',
data: col(rows, 'operating_cash_flow'), data: col(rows, 'operating_cash_flow'),
barWidth: 31.2, barWidth,
itemStyle: { color: FINANCIAL_COLORS.operatingCashFlow }, itemStyle: { color: FINANCIAL_COLORS.operatingCashFlow },
label: { show: true, position: 'top', color: PALETTE.ink, fontFamily: FONT, fontSize: 11, formatter: (p) => p.value.toFixed(1) }, label: { show: true, position: 'top', color: PALETTE.ink, fontFamily: FONT, fontSize: 11, formatter: (p) => p.value.toFixed(1) },
}, },
@@ -67,7 +71,7 @@ export function cashConversionChart(rows, { width, height }) {
name: '净利润', name: '净利润',
type: 'bar', type: 'bar',
data: col(rows, 'net_profit'), data: col(rows, 'net_profit'),
barWidth: 31.2, barWidth,
itemStyle: { color: FINANCIAL_COLORS.netProfit }, itemStyle: { color: FINANCIAL_COLORS.netProfit },
label: { show: true, position: 'top', color: PALETTE.ink, fontFamily: FONT, fontSize: 11, formatter: (p) => p.value.toFixed(1) }, label: { show: true, position: 'top', color: PALETTE.ink, fontFamily: FONT, fontSize: 11, formatter: (p) => p.value.toFixed(1) },
}, },
@@ -85,7 +89,7 @@ export function cashConversionChart(rows, { width, height }) {
], ],
graphic: [ graphic: [
...watermarks(width, height), ...watermarks(width, height),
footnote('数据来源:泡泡玛特合并现金流量表、利润表(年度口径)| @思考的Joey'), footnote('数据来源:泡泡玛特合并现金流量表、利润表;H2为单独半年 | @思考的Joey'),
], ],
}; };
} }
+11 -9
View File
@@ -1,12 +1,14 @@
import { col } from '../csv.js'; import { col } from '../csv.js';
import { import {
FINANCIAL_COLORS, PALETTE, FONT, axisCommon, periodAxis, titleStyle, standardLegend, FINANCIAL_COLORS, PALETTE, FONT, axisCommon, standalonePeriodAxis, titleStyle, standardLegend,
financialViewDisclosure, financialViewLabel,
lineDataWithSafeLabels, lineDataWithSafeLabels,
lineSeries, footnote, watermarks, LAYOUT, lineSeries, footnote, watermarks, LAYOUT,
} from '../theme.js'; } from '../theme.js';
/** 泡泡玛特三大现金流:展示经营造血、投资投入与筹资变化。 */ /** 泡泡玛特三大现金流:展示经营造血、投资投入与筹资变化。 */
export function cashflowCompositionChart(rows, { width, height }) { export function cashflowCompositionChart(rows, { width, height, view = 'all' }) {
const barWidth = view === 'all' ? 10 : view === 'halfyear' ? 18.2 : 26;
const netCashIncrease = lineDataWithSafeLabels(rows, { const netCashIncrease = lineDataWithSafeLabels(rows, {
lineKey: 'net_cash_increase', lineKey: 'net_cash_increase',
barKeys: ['operating_cash_flow', 'investing_cash_flow', 'financing_cash_flow'], barKeys: ['operating_cash_flow', 'investing_cash_flow', 'financing_cash_flow'],
@@ -16,8 +18,8 @@ export function cashflowCompositionChart(rows, { width, height }) {
backgroundColor: '#fff', backgroundColor: '#fff',
title: { title: {
...titleStyle, ...titleStyle,
text: '泡泡玛特三大现金流与现金净增加(年度)', text: `泡泡玛特三大现金流与现金净增加(${financialViewLabel(view)})`,
subtext: '单位:亿元;正值为流入,负值为流出', subtext: ['单位:亿元;正值为流入,负值为流出', financialViewDisclosure(view)].filter(Boolean).join('\n'),
}, },
// 不手工指定 icon,让 ECharts 按系列类型生成:柱为矩形、折线为短线 + 空心圆。 // 不手工指定 icon,让 ECharts 按系列类型生成:柱为矩形、折线为短线 + 空心圆。
legend: standardLegend(['经营活动现金流', '投资活动现金流', '筹资活动现金流', '现金净增加']), legend: standardLegend(['经营活动现金流', '投资活动现金流', '筹资活动现金流', '现金净增加']),
@@ -28,7 +30,7 @@ export function cashflowCompositionChart(rows, { width, height }) {
textStyle: { fontFamily: FONT }, textStyle: { fontFamily: FONT },
valueFormatter: (value) => `${value.toFixed(1)} 亿元`, valueFormatter: (value) => `${value.toFixed(1)} 亿元`,
}, },
xAxis: { ...periodAxis, data: col(rows, 'period') }, xAxis: { ...standalonePeriodAxis, data: col(rows, 'period') },
yAxis: { yAxis: {
...axisCommon, ...axisCommon,
type: 'value', type: 'value',
@@ -38,9 +40,9 @@ export function cashflowCompositionChart(rows, { width, height }) {
nameTextStyle: { color: PALETTE.grey, fontSize: 13, fontFamily: FONT }, nameTextStyle: { color: PALETTE.grey, fontSize: 13, fontFamily: FONT },
}, },
series: [ series: [
{ name: '经营活动现金流', type: 'bar', data: col(rows, 'operating_cash_flow'), barWidth: 26, itemStyle: { color: FINANCIAL_COLORS.operatingCashFlow } }, { name: '经营活动现金流', type: 'bar', data: col(rows, 'operating_cash_flow'), barWidth, itemStyle: { color: FINANCIAL_COLORS.operatingCashFlow } },
{ name: '投资活动现金流', type: 'bar', data: col(rows, 'investing_cash_flow'), barWidth: 26, itemStyle: { color: FINANCIAL_COLORS.investingCashFlow } }, { name: '投资活动现金流', type: 'bar', data: col(rows, 'investing_cash_flow'), barWidth, itemStyle: { color: FINANCIAL_COLORS.investingCashFlow } },
{ name: '筹资活动现金流', type: 'bar', data: col(rows, 'financing_cash_flow'), barWidth: 26, itemStyle: { color: FINANCIAL_COLORS.financingCashFlow } }, { name: '筹资活动现金流', type: 'bar', data: col(rows, 'financing_cash_flow'), barWidth, itemStyle: { color: FINANCIAL_COLORS.financingCashFlow } },
{ {
...lineSeries({ ...lineSeries({
name: '现金净增加', name: '现金净增加',
@@ -55,7 +57,7 @@ export function cashflowCompositionChart(rows, { width, height }) {
], ],
graphic: [ graphic: [
...watermarks(width, height), ...watermarks(width, height),
footnote('数据来源:泡泡玛特合并现金流量表(年度口径)| @思考的Joey'), footnote('数据来源:泡泡玛特合并现金流量表;H2为单独半年 | @思考的Joey'),
], ],
}; };
} }
+6 -12
View File
@@ -1,6 +1,7 @@
import { col } from '../csv.js'; import { col } from '../csv.js';
import { import {
PALETTE, FONT, axisCommon, categoryAxis, titleStyle, legendStyle, PALETTE, FONT, axisCommon, standalonePeriodAxis, titleStyle, legendStyle,
financialViewDisclosure, financialViewLabel,
footnote, watermarks, LAYOUT, footnote, watermarks, LAYOUT,
} from '../theme.js'; } from '../theme.js';
@@ -8,7 +9,7 @@ import {
* 泡泡玛特品类收入结构图 * 泡泡玛特品类收入结构图
* 堆叠柱状图展示各品类的收入占比和增长 * 堆叠柱状图展示各品类的收入占比和增长
*/ */
export function categoryChart(rows, { width, height }) { export function categoryChart(rows, { width, height, view = 'all' }) {
// 过滤掉表头行("品类"那一行) // 过滤掉表头行("品类"那一行)
const dataRows = rows.filter(r => r.period && r.period !== '品类'); const dataRows = rows.filter(r => r.period && r.period !== '品类');
const periods = col(dataRows, 'period'); const periods = col(dataRows, 'period');
@@ -17,8 +18,8 @@ export function categoryChart(rows, { width, height }) {
backgroundColor: '#fff', backgroundColor: '#fff',
title: { title: {
...titleStyle, ...titleStyle,
text: '泡泡玛特品类收入结构(2024H1-2025H2)', text: `泡泡玛特品类收入结构(${financialViewLabel(view)})`,
subtext: '单位:亿元', subtext: ['单位:亿元;H2为下半年单期', financialViewDisclosure(view)].filter(Boolean).join('\n'),
}, },
legend: { legend: {
...legendStyle, ...legendStyle,
@@ -41,14 +42,7 @@ export function categoryChart(rows, { width, height }) {
return result; return result;
}, },
}, },
xAxis: { xAxis: { ...standalonePeriodAxis, data: periods },
...categoryAxis,
data: periods,
axisLabel: {
...categoryAxis.axisLabel,
formatter: (value) => String(value).replace(/^20/, ''),
},
},
yAxis: { yAxis: {
...axisCommon, ...axisCommon,
type: 'value', type: 'value',
+6 -5
View File
@@ -1,11 +1,12 @@
import { col } from '../csv.js'; import { col } from '../csv.js';
import { import {
CHANNEL_COLORS, PALETTE, FONT, axisCommon, periodAxis, titleStyle, legendStyle, CHANNEL_COLORS, PALETTE, FONT, axisCommon, standalonePeriodAxis, titleStyle, legendStyle,
financialViewDisclosure, financialViewLabel,
lineSeries, footnote, watermarks, LAYOUT, lineSeries, footnote, watermarks, LAYOUT,
} from '../theme.js'; } from '../theme.js';
/** 泡泡玛特渠道收入结构与增速。 */ /** 泡泡玛特渠道收入结构与增速。 */
export function channelRevenueChart(rows, { width, height }) { export function channelRevenueChart(rows, { width, height, view = 'all' }) {
const channels = [ const channels = [
{ key: 'retail', name: '零售店', color: CHANNEL_COLORS.retail }, { key: 'retail', name: '零售店', color: CHANNEL_COLORS.retail },
{ key: 'online', name: '线上', color: CHANNEL_COLORS.online }, { key: 'online', name: '线上', color: CHANNEL_COLORS.online },
@@ -17,8 +18,8 @@ export function channelRevenueChart(rows, { width, height }) {
backgroundColor: '#fff', backgroundColor: '#fff',
title: { title: {
...titleStyle, ...titleStyle,
text: '泡泡玛特渠道收入结构与增速', text: `泡泡玛特渠道收入结构与增速(${financialViewLabel(view)})`,
subtext: '渠道收入为堆叠柱;折线为营业收入同比增速', subtext: ['渠道收入为堆叠柱;折线为营业收入同比增速', financialViewDisclosure(view)].filter(Boolean).join('\n'),
}, },
legend: { legend: {
...legendStyle, ...legendStyle,
@@ -32,7 +33,7 @@ export function channelRevenueChart(rows, { width, height }) {
textStyle: { fontFamily: FONT }, textStyle: { fontFamily: FONT },
valueFormatter: (value) => value.toFixed(1), valueFormatter: (value) => value.toFixed(1),
}, },
xAxis: { ...periodAxis, data: col(rows, 'period') }, xAxis: { ...standalonePeriodAxis, data: col(rows, 'period') },
yAxis: [ yAxis: [
{ {
...axisCommon, ...axisCommon,
+6 -5
View File
@@ -1,6 +1,7 @@
import { col } from '../csv.js'; import { col } from '../csv.js';
import { import {
PALETTE, FONT, axisCommon, periodAxis, titleStyle, PALETTE, FONT, axisCommon, standalonePeriodAxis, titleStyle,
financialViewDisclosure, financialViewLabel,
lineSeries, standardLegend, footnote, watermarks, LAYOUT, lineSeries, standardLegend, footnote, watermarks, LAYOUT,
} from '../theme.js'; } from '../theme.js';
@@ -15,15 +16,15 @@ import {
*/ */
const LINE_COLOR = '#7B2D42'; const LINE_COLOR = '#7B2D42';
export function ppmtCoreMarginChart(rows, { width, height }) { export function ppmtCoreMarginChart(rows, { width, height, view = 'all' }) {
const pct = (p) => `${p.value.toFixed(1)}%`; const pct = (p) => `${p.value.toFixed(1)}%`;
return { return {
backgroundColor: '#fff', backgroundColor: '#fff',
title: { title: {
...titleStyle, ...titleStyle,
text: '泡泡玛特核心利润率(20H1-26H1)', text: `泡泡玛特核心利润率(${financialViewLabel(view)})`,
subtext: '核心利润率 = 毛利率 − 销售费用率 − 管理费用率,剔除汇兑与投资等非主业扰动', subtext: ['核心利润率 = 毛利率 − 销售费用率 − 管理费用率,剔除汇兑与投资等非主业扰动', financialViewDisclosure(view)].filter(Boolean).join('\n'),
}, },
legend: standardLegend(['核心利润率'], { itemGap: 32 }), legend: standardLegend(['核心利润率'], { itemGap: 32 }),
grid: { left: 78, right: 60, top: LAYOUT.gridTop, bottom: 90 }, grid: { left: 78, right: 60, top: LAYOUT.gridTop, bottom: 90 },
@@ -32,7 +33,7 @@ export function ppmtCoreMarginChart(rows, { width, height }) {
valueFormatter: (v) => `${v.toFixed(1)}%`, valueFormatter: (v) => `${v.toFixed(1)}%`,
textStyle: { fontFamily: FONT }, textStyle: { fontFamily: FONT },
}, },
xAxis: { ...periodAxis, data: col(rows, 'period') }, xAxis: { ...standalonePeriodAxis, data: col(rows, 'period') },
yAxis: { yAxis: {
...axisCommon, ...axisCommon,
type: 'value', type: 'value',
+6 -5
View File
@@ -1,6 +1,7 @@
import { col } from '../csv.js'; import { col } from '../csv.js';
import { import {
PALETTE, FINANCIAL_COLORS, FONT, axisCommon, periodAxis, titleStyle, legendStyle, PALETTE, FINANCIAL_COLORS, FONT, axisCommon, standalonePeriodAxis, titleStyle, legendStyle,
financialViewDisclosure, financialViewLabel,
footnote, watermarks, LAYOUT, footnote, watermarks, LAYOUT,
} from '../theme.js'; } from '../theme.js';
@@ -9,7 +10,7 @@ import {
* 核心利润 = 毛利 - 销售费用 - 管理费用,反映主业盈利能力去除营销和管理成本后的净额。 * 核心利润 = 毛利 - 销售费用 - 管理费用,反映主业盈利能力去除营销和管理成本后的净额。
* 柱状图展示绝对值(亿元),折线图展示同比增速(%)。 * 柱状图展示绝对值(亿元),折线图展示同比增速(%)。
*/ */
export function ppmtCoreProfitChart(rows, { width, height }) { export function ppmtCoreProfitChart(rows, { width, height, view = 'all' }) {
const periods = col(rows, 'period'); const periods = col(rows, 'period');
const core = col(rows, 'core_profit'); const core = col(rows, 'core_profit');
const yoy = col(rows, 'yoy'); const yoy = col(rows, 'yoy');
@@ -18,8 +19,8 @@ export function ppmtCoreProfitChart(rows, { width, height }) {
backgroundColor: '#fff', backgroundColor: '#fff',
title: { title: {
...titleStyle, ...titleStyle,
text: '泡泡玛特核心利润及同比增速(20H1-26H1)', text: `泡泡玛特核心利润及同比增速(${financialViewLabel(view)})`,
subtext: '核心利润 = 毛利 - 销售费用 - 管理费用,单位:亿元', subtext: ['核心利润 = 毛利 - 销售费用 - 管理费用,单位:亿元', financialViewDisclosure(view)].filter(Boolean).join('\n'),
}, },
legend: { legend: {
...legendStyle, ...legendStyle,
@@ -49,7 +50,7 @@ export function ppmtCoreProfitChart(rows, { width, height }) {
return result; return result;
}, },
}, },
xAxis: { ...periodAxis, data: periods }, xAxis: { ...standalonePeriodAxis, data: periods },
yAxis: [ yAxis: [
{ {
// 左轴:核心利润(亿元) // 左轴:核心利润(亿元)
+7 -6
View File
@@ -1,17 +1,18 @@
import { col } from '../csv.js'; import { col } from '../csv.js';
import { import {
PALETTE, FONT, axisCommon, periodAxis, titleStyle, legendStyle, PALETTE, FONT, axisCommon, standalonePeriodAxis, titleStyle, legendStyle,
financialViewDisclosure, financialViewLabel,
lineSeries, footnote, watermarks, LAYOUT, lineSeries, footnote, watermarks, LAYOUT,
} from '../theme.js'; } from '../theme.js';
/** 泡泡玛特期间费用结构:观察销售投入、管理成本与费用率的规模效应。 */ /** 泡泡玛特期间费用结构:观察销售投入、管理成本与费用率的规模效应。 */
export function expenseStructureChart(rows, { width, height }) { export function expenseStructureChart(rows, { width, height, view = 'all' }) {
return { return {
backgroundColor: '#fff', backgroundColor: '#fff',
title: { title: {
...titleStyle, ...titleStyle,
text: '泡泡玛特费用结构与费用率(年度)', text: `泡泡玛特费用结构与费用率(${financialViewLabel(view)})`,
subtext: '销售、管理、财务费用;折线为四项费用率', subtext: ['销售、管理、财务费用;折线为四项费用率', financialViewDisclosure(view)].filter(Boolean).join('\n'),
}, },
legend: { legend: {
...legendStyle, ...legendStyle,
@@ -25,7 +26,7 @@ export function expenseStructureChart(rows, { width, height }) {
textStyle: { fontFamily: FONT }, textStyle: { fontFamily: FONT },
valueFormatter: (value) => value.toFixed(1), valueFormatter: (value) => value.toFixed(1),
}, },
xAxis: { ...periodAxis, data: col(rows, 'period') }, xAxis: { ...standalonePeriodAxis, data: col(rows, 'period') },
yAxis: [ yAxis: [
{ {
...axisCommon, ...axisCommon,
@@ -68,7 +69,7 @@ export function expenseStructureChart(rows, { width, height }) {
], ],
graphic: [ graphic: [
...watermarks(width, height), ...watermarks(width, height),
footnote('数据来源:泡泡玛特合并利润表(年度口径)| @思考的Joey'), footnote('数据来源:泡泡玛特合并利润表;H2为单独半年 | @思考的Joey'),
], ],
}; };
} }
+7 -6
View File
@@ -1,6 +1,7 @@
import { col } from '../csv.js'; import { col } from '../csv.js';
import { import {
PALETTE, FONT, axisCommon, periodAxis, titleStyle, standardLegend, PALETTE, FONT, axisCommon, standalonePeriodAxis, titleStyle, standardLegend,
financialViewDisclosure, financialViewLabel,
lineSeries, footnote, watermarks, LAYOUT, lineSeries, footnote, watermarks, LAYOUT,
} from '../theme.js'; } from '../theme.js';
@@ -43,15 +44,15 @@ function labeledData(rows, key) {
}); });
} }
export function ppmtGrowthChart(rows, { width, height }) { export function ppmtGrowthChart(rows, { width, height, view = 'all' }) {
const pct = (p) => `${p.value}%`; const pct = (p) => `${p.value}%`;
return { return {
backgroundColor: '#fff', backgroundColor: '#fff',
title: { title: {
...titleStyle, ...titleStyle,
text: '泡泡玛特营收到利润的增速对比(2020H1-2026H1)', text: `泡泡玛特营收到利润的增速对比(${financialViewLabel(view)})`,
subtext: '同比增速(%),净利增速显著高于营收增速体现利润弹性', subtext: ['同比增速(%),净利增速显著高于营收增速体现利润弹性', financialViewDisclosure(view)].filter(Boolean).join('\n'),
}, },
legend: standardLegend(['非GAAP归母净利', '毛利润', '营业收入', '营业成本'], { itemGap: 34 }), legend: standardLegend(['非GAAP归母净利', '毛利润', '营业收入', '营业成本'], { itemGap: 34 }),
grid: { left: 84, right: 56, top: LAYOUT.gridTop, bottom: 80 }, grid: { left: 84, right: 56, top: LAYOUT.gridTop, bottom: 80 },
@@ -60,7 +61,7 @@ export function ppmtGrowthChart(rows, { width, height }) {
valueFormatter: (v) => `${v}%`, valueFormatter: (v) => `${v}%`,
textStyle: { fontFamily: FONT }, textStyle: { fontFamily: FONT },
}, },
xAxis: { ...periodAxis, data: col(rows, 'period') }, xAxis: { ...standalonePeriodAxis, data: col(rows, 'period') },
yAxis: { yAxis: {
...axisCommon, ...axisCommon,
type: 'value', type: 'value',
@@ -105,7 +106,7 @@ export function ppmtGrowthChart(rows, { width, height }) {
})), })),
graphic: [ graphic: [
...watermarks(width, height), ...watermarks(width, height),
footnote('数据来源:泡泡玛特财报,2020H1/H2非GAAP净利用归母净利替代 | @思考的Joey'), footnote('数据来源:泡泡玛特财报;2020H1/H2非GAAP净利用归母净利替代 | @思考的Joey'),
], ],
}; };
} }
+5 -4
View File
@@ -1,6 +1,7 @@
import { col } from '../csv.js'; import { col } from '../csv.js';
import { import {
PALETTE, FONT, axisCommon, categoryAxis, titleStyle, legendStyle, PALETTE, FONT, axisCommon, categoryAxis, titleStyle, legendStyle,
financialViewDisclosure, financialViewLabel, shortStandalonePeriod,
lineSeries, footnote, watermarks, LAYOUT, lineSeries, footnote, watermarks, LAYOUT,
} from '../theme.js'; } from '../theme.js';
@@ -8,7 +9,7 @@ import {
* 泡泡玛特主要IP收入趋势图 * 泡泡玛特主要IP收入趋势图
* 多条折线展示各IP的收入变化 * 多条折线展示各IP的收入变化
*/ */
export function ipChart(rows, { width, height }) { export function ipChart(rows, { width, height, view = 'all' }) {
// 提取时期(从第一行的列名) // 提取时期(从第一行的列名)
const periods = Object.keys(rows[0]).filter(k => k !== 'ip'); const periods = Object.keys(rows[0]).filter(k => k !== 'ip');
@@ -42,8 +43,8 @@ export function ipChart(rows, { width, height }) {
backgroundColor: '#fff', backgroundColor: '#fff',
title: { title: {
...titleStyle, ...titleStyle,
text: '泡泡玛特主要IP收入趋势(2021H1-2025H2)', text: `泡泡玛特主要IP收入趋势(${financialViewLabel(view)})`,
subtext: '单位:亿元', subtext: ['单位:亿元;H2为单独半年', financialViewDisclosure(view)].filter(Boolean).join('\n'),
}, },
legend: { legend: {
...legendStyle, ...legendStyle,
@@ -62,7 +63,7 @@ export function ipChart(rows, { width, height }) {
data: periods, data: periods,
axisLabel: { axisLabel: {
...categoryAxis.axisLabel, ...categoryAxis.axisLabel,
formatter: (value) => String(value).replace(/^20/, ''), formatter: shortStandalonePeriod,
}, },
}, },
yAxis: { yAxis: {
+10 -15
View File
@@ -1,6 +1,7 @@
import { col } from '../csv.js'; import { col } from '../csv.js';
import { import {
PALETTE, FONT, axisCommon, categoryAxis, titleStyle, labelStyle, PALETTE, FONT, axisCommon, standalonePeriodAxis, titleStyle, labelStyle,
financialViewDisclosure, financialViewLabel,
barSeries, lineSeries, standardLegend, footnote, watermarks, LAYOUT, barSeries, lineSeries, standardLegend, footnote, watermarks, LAYOUT,
} from '../theme.js'; } from '../theme.js';
@@ -34,13 +35,13 @@ const BAR_COLOR = '#176B52'; // 墨翡翠
const LINE_COLOR = '#7A3FE0'; // 鲜亮紫 const LINE_COLOR = '#7A3FE0'; // 鲜亮紫
const LINE_ON_BAR = '#DCC9FF'; // 压在翡翠柱面上时用的浅紫(对比度约 6:1) const LINE_ON_BAR = '#DCC9FF'; // 压在翡翠柱面上时用的浅紫(对比度约 6:1)
const Y_MAX = 160; // 左轴上限
const YOY_MIN = -50; // 右轴下限 const YOY_MIN = -50; // 右轴下限
const YOY_MAX = 150; // 右轴上限 const YOY_MAX = 150; // 右轴上限
export function ppmtIpExMonstersChart(rows, { width, height }) { export function ppmtIpExMonstersChart(rows, { width, height, view = 'all' }) {
const periods = col(rows, 'period'); const periods = col(rows, 'period');
const revenue = col(rows, 'revenue'); const revenue = col(rows, 'revenue');
const yMax = Math.max(...revenue) > 160 ? 300 : 160;
// 前两期无同比基数,CSV 里留空;parseCSV 会给出 '',统一转成 null // 前两期无同比基数,CSV 里留空;parseCSV 会给出 '',统一转成 null
const yoy = col(rows, 'yoy').map((v) => (v === '' ? null : v)); const yoy = col(rows, 'yoy').map((v) => (v === '' ? null : v));
@@ -50,7 +51,7 @@ export function ppmtIpExMonstersChart(rows, { width, height }) {
const labelGap = (8 + 13) / plotH; // labelStyle 的 distance + 字高,换成占比 const labelGap = (8 + 13) / plotH; // labelStyle 的 distance + 字高,换成占比
const yoyData = yoy.map((v, i) => { const yoyData = yoy.map((v, i) => {
if (v === null) return null; if (v === null) return null;
const barFrac = revenue[i] / Y_MAX; const barFrac = revenue[i] / yMax;
const lineFrac = (v - YOY_MIN) / (YOY_MAX - YOY_MIN); const lineFrac = (v - YOY_MIN) / (YOY_MAX - YOY_MIN);
// 标签整体(底边到顶边)都落在柱子高度以内 → 压在柱面上 // 标签整体(底边到顶边)都落在柱子高度以内 → 压在柱面上
const onBar = lineFrac + labelGap < barFrac; const onBar = lineFrac + labelGap < barFrac;
@@ -61,8 +62,8 @@ export function ppmtIpExMonstersChart(rows, { width, height }) {
backgroundColor: '#fff', backgroundColor: '#fff',
title: { title: {
...titleStyle, ...titleStyle,
text: '泡泡玛特除 THE MONSTERS 外的IP收入及同比(21H1-26H1)', text: `泡泡玛特除 THE MONSTERS 外的IP收入及同比(${financialViewLabel(view)})`,
subtext: 'IP收入合计 − THE MONSTERS,单位:亿元;H2 为下半年单期,非全年累计', subtext: ['IP收入合计 − THE MONSTERS,单位:亿元;H2为下半年单期,非全年累计', financialViewDisclosure(view)].filter(Boolean).join('\n'),
}, },
legend: standardLegend(['除MONSTERS外收入', '同比增速'], { itemGap: 32 }), legend: standardLegend(['除MONSTERS外收入', '同比增速'], { itemGap: 32 }),
grid: { left: 78, right: 128, top: LAYOUT.gridTop, bottom: 90 }, grid: { left: 78, right: 128, top: LAYOUT.gridTop, bottom: 90 },
@@ -82,12 +83,7 @@ export function ppmtIpExMonstersChart(rows, { width, height }) {
return out; return out;
}, },
}, },
xAxis: { xAxis: { ...standalonePeriodAxis, data: periods },
...categoryAxis,
data: periods,
// 只去世纪前缀:这张表的 H2 是单半年,不能简写成「全年」
axisLabel: { ...categoryAxis.axisLabel, formatter: (v) => v.replace(/^20/, '') },
},
yAxis: [ yAxis: [
{ {
...axisCommon, ...axisCommon,
@@ -97,9 +93,8 @@ export function ppmtIpExMonstersChart(rows, { width, height }) {
nameGap: 50, nameGap: 50,
nameTextStyle: { color: PALETTE.grey, fontSize: 13, fontFamily: FONT }, nameTextStyle: { color: PALETTE.grey, fontSize: 13, fontFamily: FONT },
min: 0, min: 0,
// 定死 160:留出顶部余量,最高柱(139.0)不会顶到绘图区上沿 max: yMax,
max: Y_MAX, interval: yMax === 160 ? 20 : 50,
interval: 20,
}, },
{ {
type: 'value', type: 'value',
+5 -4
View File
@@ -1,5 +1,6 @@
import { import {
PALETTE, FONT, axisCommon, categoryAxis, titleStyle, LEGEND_ITEM_WIDTH, PALETTE, FONT, axisCommon, categoryAxis, titleStyle, LEGEND_ITEM_WIDTH,
financialViewDisclosure, financialViewLabel, shortStandalonePeriod,
barSeries, footnote, watermarks, LAYOUT, barSeries, footnote, watermarks, LAYOUT,
} from '../theme.js'; } from '../theme.js';
@@ -38,7 +39,7 @@ const COLORS = {
const LEGEND_WIDTH = 160; const LEGEND_WIDTH = 160;
const LEGEND_RIGHT = 20; const LEGEND_RIGHT = 20;
export function ppmtIpShareHistoryChart(rows, { width, height }) { export function ppmtIpShareHistoryChart(rows, { width, height, view = 'all' }) {
const periods = Object.keys(rows[0]).filter((k) => k !== 'ip'); const periods = Object.keys(rows[0]).filter((k) => k !== 'ip');
const names = rows.map((r) => r.ip); const names = rows.map((r) => r.ip);
const totals = periods.map((p) => rows.reduce((s, r) => s + r[p], 0)); const totals = periods.map((p) => rows.reduce((s, r) => s + r[p], 0));
@@ -49,8 +50,8 @@ export function ppmtIpShareHistoryChart(rows, { width, height }) {
backgroundColor: '#fff', backgroundColor: '#fff',
title: { title: {
...titleStyle, ...titleStyle,
text: '泡泡玛特各IP半年收入占比(21H1-26H1)', text: `泡泡玛特各IP收入占比(${financialViewLabel(view)})`,
subtext: '占当期IP收入合计的比重;H2 为下半年单期,非全年累计', subtext: ['占当期IP收入合计的比重;H2为下半年单期,非全年累计', financialViewDisclosure(view)].filter(Boolean).join('\n'),
}, },
legend: { legend: {
orient: 'vertical', orient: 'vertical',
@@ -89,7 +90,7 @@ export function ppmtIpShareHistoryChart(rows, { width, height }) {
...categoryAxis, ...categoryAxis,
data: periods, data: periods,
// 只去世纪前缀:这张表的 H2 是单半年,不能简写成「全年」 // 只去世纪前缀:这张表的 H2 是单半年,不能简写成「全年」
axisLabel: { ...categoryAxis.axisLabel, formatter: (v) => v.replace(/^20/, '') }, axisLabel: { ...categoryAxis.axisLabel, formatter: shortStandalonePeriod },
}, },
yAxis: { yAxis: {
...axisCommon, ...axisCommon,
+6 -5
View File
@@ -1,19 +1,20 @@
import { col } from '../csv.js'; import { col } from '../csv.js';
import { import {
PALETTE, FINANCIAL_COLORS, FONT, axisCommon, periodAxis, titleStyle, legendStyle, PALETTE, FINANCIAL_COLORS, FONT, axisCommon, standalonePeriodAxis, titleStyle, legendStyle,
financialViewLabel,
lineDataWithSafeLabels, lineSeries, barSeries, footnote, watermarks, LAYOUT, lineDataWithSafeLabels, lineSeries, barSeries, footnote, watermarks, LAYOUT,
} from '../theme.js'; } from '../theme.js';
/** 泡泡玛特现金、负债与净营运资本:观察流动性与资金占用。 */ /** 泡泡玛特现金、负债与净营运资本:观察流动性与资金占用。 */
export function liquidityWorkingCapitalChart(rows, { width, height }) { export function liquidityWorkingCapitalChart(rows, { width, height, view = 'all' }) {
const periods = col(rows, 'period'); const periods = col(rows, 'period');
return { return {
backgroundColor: '#fff', backgroundColor: '#fff',
title: { title: {
...titleStyle, ...titleStyle,
text: '泡泡玛特现金、负债与净营运资本', text: `泡泡玛特现金、负债与净营运资本(${financialViewLabel(view)})`,
subtext: '净营运资本 = 流动资产 − 流动负债;单位:亿元', subtext: '净营运资本 = 流动资产 − 流动负债;单位:亿元;H2 为年末时点',
}, },
legend: { legend: {
...legendStyle, ...legendStyle,
@@ -27,7 +28,7 @@ export function liquidityWorkingCapitalChart(rows, { width, height }) {
textStyle: { fontFamily: FONT }, textStyle: { fontFamily: FONT },
valueFormatter: (value) => `${value.toFixed(1)} 亿元`, valueFormatter: (value) => `${value.toFixed(1)} 亿元`,
}, },
xAxis: { ...periodAxis, data: periods }, xAxis: { ...standalonePeriodAxis, data: periods },
yAxis: { yAxis: {
...axisCommon, ...axisCommon,
type: 'value', type: 'value',
+6 -5
View File
@@ -1,6 +1,7 @@
import { col } from '../csv.js'; import { col } from '../csv.js';
import { import {
PALETTE, FONT, axisCommon, periodAxis, titleStyle, standardLegend, PALETTE, FONT, axisCommon, standalonePeriodAxis, titleStyle, standardLegend,
financialViewDisclosure, financialViewLabel,
lineSeries, footnote, watermarks, LAYOUT, lineSeries, footnote, watermarks, LAYOUT,
} from '../theme.js'; } from '../theme.js';
@@ -54,15 +55,15 @@ function labeledData(rows, key) {
}); });
} }
export function ppmtMarginsChart(rows, { width, height }) { export function ppmtMarginsChart(rows, { width, height, view = 'all' }) {
const pct = (p) => `${p.value}%`; const pct = (p) => `${p.value}%`;
return { return {
backgroundColor: '#fff', backgroundColor: '#fff',
title: { title: {
...titleStyle, ...titleStyle,
text: '泡泡玛特利润率与费用率拆解(2020H1-2026H1)', text: `泡泡玛特利润率与费用率拆解(${financialViewLabel(view)})`,
subtext: '毛利率抬升叠加费用率下降,共同推动净利率走高(H1为半年,H2为全年累计)', subtext: ['毛利率抬升叠加费用率下降,共同推动净利率走高', financialViewDisclosure(view)].filter(Boolean).join('\n'),
}, },
legend: standardLegend(SERIES.map((series) => series.name)), legend: standardLegend(SERIES.map((series) => series.name)),
grid: { left: 78, right: 56, top: LAYOUT.gridTop, bottom: 80 }, grid: { left: 78, right: 56, top: LAYOUT.gridTop, bottom: 80 },
@@ -71,7 +72,7 @@ export function ppmtMarginsChart(rows, { width, height }) {
valueFormatter: (v) => `${v}%`, valueFormatter: (v) => `${v}%`,
textStyle: { fontFamily: FONT }, textStyle: { fontFamily: FONT },
}, },
xAxis: { ...periodAxis, data: col(rows, 'period') }, xAxis: { ...standalonePeriodAxis, data: col(rows, 'period') },
yAxis: { yAxis: {
...axisCommon, ...axisCommon,
type: 'value', type: 'value',
+12 -11
View File
@@ -1,6 +1,7 @@
import { col } from '../csv.js'; import { col } from '../csv.js';
import { import {
PALETTE, FONT, axisCommon, periodAxis, titleStyle, legendStyle, PALETTE, FONT, axisCommon, standalonePeriodAxis, titleStyle, legendStyle,
financialViewDisclosure, financialViewLabel,
lineSeries, footnote, watermarks, LAYOUT, lineSeries, footnote, watermarks, LAYOUT,
} from '../theme.js'; } from '../theme.js';
@@ -8,19 +9,19 @@ import {
* 泡泡玛特盈利能力分析图 * 泡泡玛特盈利能力分析图
* 柱状图展示收入和利润,折线图展示毛利率 * 柱状图展示收入和利润,折线图展示毛利率
*/ */
export function profitChart(rows, { width, height }) { export function profitChart(rows, { width, height, view = 'all' }) {
const periods = col(rows, 'period').reverse(); // 按时间正序 const periods = col(rows, 'period');
const revenue = col(rows, 'revenue').reverse(); const revenue = col(rows, 'revenue');
const grossProfit = col(rows, 'gross_profit').reverse(); const grossProfit = col(rows, 'gross_profit');
const netProfit = col(rows, 'net_profit').reverse(); const netProfit = col(rows, 'net_profit');
const grossMargin = col(rows, 'gross_margin').reverse(); const grossMargin = col(rows, 'gross_margin');
return { return {
backgroundColor: '#fff', backgroundColor: '#fff',
title: { title: {
...titleStyle, ...titleStyle,
text: '泡泡玛特盈利能力分析(2022H2-2026H1)', text: `泡泡玛特盈利能力分析(${financialViewLabel(view)})`,
subtext: '营收、毛利、净利润及毛利率变化', subtext: ['营收、毛利、净利润及毛利率变化', financialViewDisclosure(view)].filter(Boolean).join('\n'),
}, },
legend: { legend: {
...legendStyle, ...legendStyle,
@@ -33,7 +34,7 @@ export function profitChart(rows, { width, height }) {
axisPointer: { type: 'shadow' }, axisPointer: { type: 'shadow' },
textStyle: { fontFamily: FONT }, textStyle: { fontFamily: FONT },
}, },
xAxis: { ...periodAxis, data: periods }, xAxis: { ...standalonePeriodAxis, data: periods },
yAxis: [ yAxis: [
{ {
...axisCommon, ...axisCommon,
@@ -122,7 +123,7 @@ export function profitChart(rows, { width, height }) {
], ],
graphic: [ graphic: [
...watermarks(width, height), ...watermarks(width, height),
footnote('数据来源:泡泡玛特财报(累计数据)| @思考的Joey'), footnote('数据来源:泡泡玛特财报;H2为单独半年 | @思考的Joey'),
], ],
}; };
} }
+35 -5
View File
@@ -11,6 +11,7 @@ import {
const instances = new Map(); const instances = new Map();
const activeViews = new Map(); const activeViews = new Map();
const chartRenderVersions = new Map();
let manifest; let manifest;
let shell; let shell;
let state; let state;
@@ -106,25 +107,47 @@ function chartSource(chart) {
return chart.views[view]; return chart.views[view];
} }
async function renderChart(chart, version) { async function renderChart(chart, version, chartVersion) {
const el = document.getElementById(`chart-${chart.instanceId}`); const el = document.getElementById(`chart-${chart.instanceId}`);
if (!el) return; if (!el) return;
const source = chartSource(chart); const source = chartSource(chart);
const view = chart.views
? activeViews.get(chart.viewKey) || chart.defaultView
: undefined;
try { try {
const rows = await loadCSV(`${source}?t=${cacheToken}`); const rows = await loadCSV(`${source}?t=${cacheToken}`);
if (version !== renderVersion || !document.body.contains(el)) return; if (version !== renderVersion || chartVersion !== chartRenderVersions.get(chart.instanceId) || !document.body.contains(el)) return;
const instance = echarts.init(el, null, { renderer: 'canvas' }); const instance = echarts.init(el, null, { renderer: 'canvas' });
instances.set(chart.instanceId, instance); instances.set(chart.instanceId, instance);
const { width, height } = el.getBoundingClientRect(); const { width, height } = el.getBoundingClientRect();
instance.setOption(getChartBuilder(chart.key)(rows, { width, height }), true); instance.setOption(getChartBuilder(chart.key)(rows, { width, height, view }), true);
} catch (error) { } catch (error) {
if (version === renderVersion) showChartError(chart.instanceId, error.message); if (version === renderVersion) showChartError(chart.instanceId, error.message);
console.error(`渲染图表失败:${chart.id}`, error); console.error(`渲染图表失败:${chart.id}`, error);
} }
} }
function renderSingleChart(chart) {
const previous = instances.get(chart.instanceId);
previous?.dispose();
instances.delete(chart.instanceId);
const chartVersion = (chartRenderVersions.get(chart.instanceId) || 0) + 1;
chartRenderVersions.set(chart.instanceId, chartVersion);
renderChart(chart, renderVersion, chartVersion);
}
function updateViewControls(chart, view) {
const card = document.getElementById(`card-${chart.instanceId}`);
if (!card) return;
card.querySelectorAll('.view-button').forEach((button) => {
button.dataset.active = String(button.dataset.view === view);
});
const source = card.querySelector('.src');
if (source) source.textContent = chartSource(chart);
}
function exportPNG(chartId, filename) { function exportPNG(chartId, filename) {
const instance = instances.get(chartId); const instance = instances.get(chartId);
if (!instance) return; if (!instance) return;
@@ -167,12 +190,19 @@ function renderCurrent() {
renderCards(shell.cards, charts, activeViews, { renderCards(shell.cards, charts, activeViews, {
onExport: exportPNG, onExport: exportPNG,
onSelectView: (chart, view) => { onSelectView: (chart, view) => {
if (activeViews.get(chart.viewKey) === view) return;
activeViews.set(chart.viewKey, view); activeViews.set(chart.viewKey, view);
updateHash({ companyId: company.id, tabId: tab.id, chartId: chart.id, view }); state = normalizeState({ companyId: company.id, tabId: tab.id, chartId: chart.id, view });
history.pushState(null, '', serializeHash(state));
updateViewControls(chart, view);
renderSingleChart(chart);
}, },
}); });
renderAnchors(shell.chartNav, charts, selectAnchor); renderAnchors(shell.chartNav, charts, selectAnchor);
Promise.all(charts.map((chart) => renderChart(chart, version))); charts.forEach((chart) => {
chartRenderVersions.set(chart.instanceId, (chartRenderVersions.get(chart.instanceId) || 0) + 1);
});
Promise.all(charts.map((chart) => renderChart(chart, version, chartRenderVersions.get(chart.instanceId))));
} }
async function start() { async function start() {
+26
View File
@@ -108,6 +108,32 @@ export const periodAxis = {
}, },
}; };
/**
* 独立期间轴:FY 为全年,H1/H2 为单独半年。
* 用于已拆分累计值的多时间维度图,避免把 H2 错写为全年。
*/
export function shortStandalonePeriod(label) {
return String(label)
.replace(/^20(\d{2})FY$/, '$1全年')
.replace(/^20(\d{2})/, '$1');
}
export const standalonePeriodAxis = {
...categoryAxis,
axisLabel: {
...categoryAxis.axisLabel,
formatter: shortStandalonePeriod,
},
};
export function financialViewLabel(view) {
return ({ all: '全部期间', annual: '年度', halfyear: '半年', quarter: '季度' })[view] || '全部期间';
}
export function financialViewDisclosure(view) {
return '';
}
export const titleStyle = { export const titleStyle = {
left: 'center', left: 'center',
top: 18, top: 18,
+5 -3
View File
@@ -79,13 +79,15 @@ export function renderCards(container, charts, activeViews, { onExport, onSelect
if (viewNames.length > 1) { if (viewNames.length > 1) {
const switcher = element('div', 'view-switcher'); const switcher = element('div', 'view-switcher');
const labels = { annual: '年度', halfyear: '半年', quarter: '季度' }; const labels = { all: '全部', annual: '年度', halfyear: '半年', quarter: '季度' };
viewNames.forEach((view) => { viewNames.forEach((view) => {
switcher.append(button(labels[view] || view, { const viewButton = button(labels[view] || view, {
active: view === activeView, active: view === activeView,
onClick: () => onSelectView(chart, view), onClick: () => onSelectView(chart, view),
className: 'view-button', className: 'view-button',
})); });
viewButton.dataset.view = view;
switcher.append(viewButton);
}); });
bar.append(switcher); bar.append(switcher);
} }
+15 -15
View File
@@ -4,28 +4,28 @@
"id": "ppmt", "id": "ppmt",
"name": "泡泡玛特", "name": "泡泡玛特",
"chartCatalog": { "chartCatalog": {
"ppmt-profit": { "key": "ppmt-profit", "title": "盈利能力", "csv": "data/ppmt/ppmt_profit.csv", "height": 680, "filename": "泡泡玛特盈利能力" }, "ppmt-profit": { "key": "ppmt-profit", "title": "盈利能力", "defaultView": "all", "views": { "all": "data/ppmt/ppmt_profit.csv", "annual": "data/ppmt/ppmt_profit_annual.csv", "halfyear": "data/ppmt/ppmt_profit_halfyear.csv" }, "height": 680, "filename": "泡泡玛特盈利能力" },
"ppmt-sankey": { "key": "ppmt-sankey", "title": "利润流向", "csv": "data/ppmt/ppmt_sankey_2026h1.csv", "height": 800, "filename": "泡泡玛特利润流向2026H1" }, "ppmt-sankey": { "key": "ppmt-sankey", "title": "利润流向", "csv": "data/ppmt/ppmt_sankey_2026h1.csv", "height": 800, "filename": "泡泡玛特利润流向2026H1" },
"ppmt-growth": { "key": "ppmt-growth", "title": "营收到利润的增速对比", "csv": "data/ppmt/ppmt_growth.csv", "height": 700, "filename": "泡泡玛特营收到利润增速对比" }, "ppmt-growth": { "key": "ppmt-growth", "title": "营收到利润的增速对比", "defaultView": "all", "views": { "all": "data/ppmt/ppmt_growth.csv", "annual": "data/ppmt/ppmt_growth_annual.csv", "halfyear": "data/ppmt/ppmt_growth_halfyear.csv" }, "height": 700, "filename": "泡泡玛特营收到利润增速对比" },
"ppmt-core-profit": { "key": "ppmt-core-profit", "title": "核心利润及同比增速", "csv": "data/ppmt/ppmt_core_profit.csv", "height": 720, "filename": "泡泡玛特核心利润及同比增速" }, "ppmt-core-profit": { "key": "ppmt-core-profit", "title": "核心利润及同比增速", "defaultView": "all", "views": { "all": "data/ppmt/ppmt_core_profit.csv", "annual": "data/ppmt/ppmt_core_profit_annual.csv", "halfyear": "data/ppmt/ppmt_core_profit_halfyear.csv" }, "height": 720, "filename": "泡泡玛特核心利润及同比增速" },
"ppmt-core-margin": { "key": "ppmt-core-margin", "title": "核心利润率", "csv": "data/ppmt/ppmt_core_margin.csv", "height": 680, "filename": "泡泡玛特核心利润率" }, "ppmt-core-margin": { "key": "ppmt-core-margin", "title": "核心利润率", "defaultView": "all", "views": { "all": "data/ppmt/ppmt_core_margin.csv", "annual": "data/ppmt/ppmt_core_margin_annual.csv", "halfyear": "data/ppmt/ppmt_core_margin_halfyear.csv" }, "height": 680, "filename": "泡泡玛特核心利润率" },
"ppmt-bridge": { "key": "ppmt-bridge", "title": "净利率同比拆解", "csv": "data/ppmt/ppmt_margin_bridge.csv", "height": 700, "filename": "泡泡玛特净利率同比拆解" }, "ppmt-bridge": { "key": "ppmt-bridge", "title": "净利率同比拆解", "csv": "data/ppmt/ppmt_margin_bridge.csv", "height": 700, "filename": "泡泡玛特净利率同比拆解" },
"ppmt-margins": { "key": "ppmt-margins", "title": "利润率与费用率拆解", "csv": "data/ppmt/ppmt_margins.csv", "height": 680, "filename": "泡泡玛特利润率与费用率拆解" }, "ppmt-margins": { "key": "ppmt-margins", "title": "利润率与费用率拆解", "defaultView": "all", "views": { "all": "data/ppmt/ppmt_margins.csv", "annual": "data/ppmt/ppmt_margins_annual.csv", "halfyear": "data/ppmt/ppmt_margins_halfyear.csv" }, "height": 680, "filename": "泡泡玛特利润率与费用率拆解" },
"ppmt-assets": { "key": "ppmt-assets", "title": "资产结构演变", "csv": "data/ppmt/ppmt_assets.csv", "height": 680, "filename": "泡泡玛特资产结构" }, "ppmt-assets": { "key": "ppmt-assets", "title": "资产结构演变", "defaultView": "all", "views": { "all": "data/ppmt/ppmt_assets.csv", "annual": "data/ppmt/ppmt_assets_annual.csv", "halfyear": "data/ppmt/ppmt_assets_halfyear.csv" }, "height": 680, "filename": "泡泡玛特资产结构" },
"ppmt-ip": { "key": "ppmt-ip", "title": "主要 IP 收入趋势", "csv": "data/ppmt/ppmt_ip.csv", "height": 720, "filename": "泡泡玛特IP收入趋势" }, "ppmt-ip": { "key": "ppmt-ip", "title": "主要 IP 收入趋势", "defaultView": "all", "views": { "all": "data/ppmt/ppmt_ip.csv", "annual": "data/ppmt/ppmt_ip_annual.csv", "halfyear": "data/ppmt/ppmt_ip_halfyear.csv" }, "height": 720, "filename": "泡泡玛特IP收入趋势" },
"ppmt-ip-share": { "key": "ppmt-ip-share", "title": "主要 IP 收入占比", "csv": "data/ppmt/ppmt_ip_share_2026h1.csv", "height": 720, "filename": "泡泡玛特IP收入占比2026H1" }, "ppmt-ip-share": { "key": "ppmt-ip-share", "title": "主要 IP 收入占比", "csv": "data/ppmt/ppmt_ip_share_2026h1.csv", "height": 720, "filename": "泡泡玛特IP收入占比2026H1" },
"ppmt-ip-share-history": { "key": "ppmt-ip-share-history", "title": "各 IP 半年收入占比", "csv": "data/ppmt/ppmt_ip_share_history.csv", "height": 700, "filename": "泡泡玛特各IP半年收入占比" }, "ppmt-ip-share-history": { "key": "ppmt-ip-share-history", "title": "各 IP 半年收入占比", "defaultView": "all", "views": { "all": "data/ppmt/ppmt_ip_share_history.csv", "annual": "data/ppmt/ppmt_ip_share_history_annual.csv", "halfyear": "data/ppmt/ppmt_ip_share_history_halfyear.csv" }, "height": 700, "filename": "泡泡玛特各IP半年收入占比" },
"ppmt-ip-ex-monsters": { "key": "ppmt-ip-ex-monsters", "title": "除 THE MONSTERS 外的 IP 收入及同比", "csv": "data/ppmt/ppmt_ip_ex_monsters.csv", "height": 700, "filename": "泡泡玛特除MONSTERS外IP收入及同比" }, "ppmt-ip-ex-monsters": { "key": "ppmt-ip-ex-monsters", "title": "除 THE MONSTERS 外的 IP 收入及同比", "defaultView": "all", "views": { "all": "data/ppmt/ppmt_ip_ex_monsters.csv", "annual": "data/ppmt/ppmt_ip_ex_monsters_annual.csv", "halfyear": "data/ppmt/ppmt_ip_ex_monsters_halfyear.csv" }, "height": 700, "filename": "泡泡玛特除MONSTERS外IP收入及同比" },
"ppmt-category": { "key": "ppmt-category", "title": "品类收入结构", "csv": "data/ppmt/ppmt_category.csv", "height": 680, "filename": "泡泡玛特品类结构" }, "ppmt-category": { "key": "ppmt-category", "title": "品类收入结构", "defaultView": "all", "views": { "all": "data/ppmt/ppmt_category.csv", "annual": "data/ppmt/ppmt_category_annual.csv", "halfyear": "data/ppmt/ppmt_category_halfyear.csv" }, "height": 680, "filename": "泡泡玛特品类结构" },
"ppmt-region-channel": { "key": "ppmt-region-channel", "title": "区域渠道分布", "csv": "data/ppmt/ppmt_region_channel_2026h1.csv", "height": 680, "filename": "泡泡玛特区域渠道分布2026H1" }, "ppmt-region-channel": { "key": "ppmt-region-channel", "title": "区域渠道分布", "csv": "data/ppmt/ppmt_region_channel_2026h1.csv", "height": 680, "filename": "泡泡玛特区域渠道分布2026H1" },
"ppmt-region-yoy": { "key": "ppmt-region-yoy", "title": "区域渠道同比增速", "csv": "data/ppmt/ppmt_region_channel_yoy.csv", "height": 620, "filename": "泡泡玛特区域渠道同比增速" }, "ppmt-region-yoy": { "key": "ppmt-region-yoy", "title": "区域渠道同比增速", "csv": "data/ppmt/ppmt_region_channel_yoy.csv", "height": 620, "filename": "泡泡玛特区域渠道同比增速" },
"ppmt-region-yoy-timeseries": { "key": "ppmt-region-yoy-timeseries", "title": "区域渠道同比增速趋势", "csv": "data/ppmt/ppmt_region_channel_yoy_timeseries.csv", "height": 760, "filename": "泡泡玛特区域渠道同比增速趋势" }, "ppmt-region-yoy-timeseries": { "key": "ppmt-region-yoy-timeseries", "title": "区域渠道同比增速趋势", "csv": "data/ppmt/ppmt_region_channel_yoy_timeseries.csv", "height": 760, "filename": "泡泡玛特区域渠道同比增速趋势" },
"ppmt-cash-conversion": { "key": "ppmt-cash-conversion", "title": "经营现金流与净利润(年度)", "csv": "data/ppmt/ppmt_cash_conversion.csv", "height": 700, "filename": "泡泡玛特经营现金流与净利润" }, "ppmt-cash-conversion": { "key": "ppmt-cash-conversion", "title": "经营现金流与净利润", "defaultView": "all", "views": { "all": "data/ppmt/ppmt_cash_conversion.csv", "annual": "data/ppmt/ppmt_cash_conversion_annual.csv", "halfyear": "data/ppmt/ppmt_cash_conversion_halfyear.csv" }, "height": 700, "filename": "泡泡玛特经营现金流与净利润" },
"ppmt-liquidity-working-capital": { "key": "ppmt-liquidity-working-capital", "title": "现金、负债与净营运资本", "csv": "data/ppmt/ppmt_liquidity_working_capital.csv", "height": 720, "filename": "泡泡玛特现金负债与净营运资本" }, "ppmt-liquidity-working-capital": { "key": "ppmt-liquidity-working-capital", "title": "现金、负债与净营运资本", "defaultView": "all", "views": { "all": "data/ppmt/ppmt_liquidity_working_capital.csv", "annual": "data/ppmt/ppmt_liquidity_working_capital_annual.csv", "halfyear": "data/ppmt/ppmt_liquidity_working_capital_halfyear.csv" }, "height": 720, "filename": "泡泡玛特现金负债与净营运资本" },
"ppmt-cashflow-composition": { "key": "ppmt-cashflow-composition", "title": "三大现金流与现金净增加(年度)", "csv": "data/ppmt/ppmt_cashflow_composition.csv", "height": 700, "filename": "泡泡玛特三大现金流与现金净增加" }, "ppmt-cashflow-composition": { "key": "ppmt-cashflow-composition", "title": "三大现金流与现金净增加", "defaultView": "all", "views": { "all": "data/ppmt/ppmt_cashflow_composition.csv", "annual": "data/ppmt/ppmt_cashflow_composition_annual.csv", "halfyear": "data/ppmt/ppmt_cashflow_composition_halfyear.csv" }, "height": 700, "filename": "泡泡玛特三大现金流与现金净增加" },
"ppmt-working-capital-days": { "key": "ppmt-working-capital-days", "title": "营运资本效率", "csv": "data/ppmt/ppmt_working_capital_days.csv", "height": 700, "filename": "泡泡玛特营运资本效率" }, "ppmt-working-capital-days": { "key": "ppmt-working-capital-days", "title": "营运资本效率", "csv": "data/ppmt/ppmt_working_capital_days.csv", "height": 700, "filename": "泡泡玛特营运资本效率" },
"ppmt-expense-structure": { "key": "ppmt-expense-structure", "title": "费用结构与费用率(年度)", "csv": "data/ppmt/ppmt_expense_structure.csv", "height": 700, "filename": "泡泡玛特费用结构与费用率" }, "ppmt-expense-structure": { "key": "ppmt-expense-structure", "title": "费用结构与费用率", "defaultView": "all", "views": { "all": "data/ppmt/ppmt_expense_structure.csv", "annual": "data/ppmt/ppmt_expense_structure_annual.csv", "halfyear": "data/ppmt/ppmt_expense_structure_halfyear.csv" }, "height": 700, "filename": "泡泡玛特费用结构与费用率" },
"ppmt-channel-revenue": { "key": "ppmt-channel-revenue", "title": "渠道收入结构与增速", "csv": "data/ppmt/ppmt_channel_revenue.csv", "height": 720, "filename": "泡泡玛特渠道收入结构与增速" } "ppmt-channel-revenue": { "key": "ppmt-channel-revenue", "title": "渠道收入结构与增速", "defaultView": "all", "views": { "all": "data/ppmt/ppmt_channel_revenue.csv", "annual": "data/ppmt/ppmt_channel_revenue_annual.csv", "halfyear": "data/ppmt/ppmt_channel_revenue_halfyear.csv" }, "height": 720, "filename": "泡泡玛特渠道收入结构与增速" }
}, },
"tabs": [ "tabs": [
{ "id": "overview", "name": "概览", "chartRefs": ["ppmt-growth", "ppmt-profit", "ppmt-ip-share", "ppmt-region-channel"] }, { "id": "overview", "name": "概览", "chartRefs": ["ppmt-growth", "ppmt-profit", "ppmt-ip-share", "ppmt-region-channel"] },
+1 -1
View File
@@ -23,5 +23,5 @@
"echarts": "5.5.1", "echarts": "5.5.1",
"vite": "^8.2.2" "vite": "^8.2.2"
}, },
"packageManager": "pnpm@10.32.1+sha512.a706938f0e89ac1456b6563eab4edf1d1faf3368d1191fc5c59790e96dc918e4456ab2e67d613de1043d2e8c81f87303e6b40d4ffeca9df15ef1ad567348f2be" "packageManager": "pnpm@11.24.0"
} }
+386
View File
@@ -258,3 +258,389 @@ writeCSV('ppmt_channel_revenue.csv', [
], channelRows); ], channelRows);
console.log(`已生成现金转换 ${cashConversionRows.length}、流动性 ${liquidityRows.length}、现金流 ${cashflowCompositionRows.length}、营运资本 ${workingCapitalDaysRows.length}、费用 ${expenseRows.length}、渠道 ${channelRows.length} 行数据。`); console.log(`已生成现金转换 ${cashConversionRows.length}、流动性 ${liquidityRows.length}、现金流 ${cashflowCompositionRows.length}、营运资本 ${workingCapitalDaysRows.length}、费用 ${expenseRows.length}、渠道 ${channelRows.length} 行数据。`);
// 多维度图表:FY 为全年,H1/H2 为独立半年。所有拆分和同比均在数据层完成。
const VIEW_YEARS = Array.from({ length: 8 }, (_, index) => 2019 + index);
const OUTPUT_START_YEAR = 2020;
const HUNDRED_MILLION = 100000000;
function isComplete(values) {
return values && Object.values(values).every((value) => Number.isFinite(value));
}
function subtractPeriod(fullYear, firstHalf) {
if (!isComplete(fullYear) || !isComplete(firstHalf)) return null;
return Object.fromEntries(Object.keys(fullYear).map((key) => [key, fullYear[key] - firstHalf[key]]));
}
function buildViews(readPeriod) {
const views = { all: [], annual: [], halfyear: [] };
VIEW_YEARS.forEach((year) => {
const h1 = readPeriod(year, 'H1');
const fy = readPeriod(year, 'FY');
const h2 = subtractPeriod(fy, h1);
if (h1) {
const row = { period: `${year}H1`, ...h1 };
views.halfyear.push(row);
views.all.push(row);
}
if (h2) {
const row = { period: `${year}H2`, ...h2 };
views.halfyear.push(row);
views.all.push(row);
}
if (fy) {
const row = { period: `${year}FY`, ...fy };
views.annual.push(row);
views.all.push(row);
}
});
return views;
}
function addPeriods(firstHalf, secondHalf) {
if (!isComplete(firstHalf) || !isComplete(secondHalf)) return null;
return Object.fromEntries(Object.keys(firstHalf).map((key) => [key, firstHalf[key] + secondHalf[key]]));
}
// IP、品类等运营数据的 H2 已是单独半年,年度值应由 H1 + H2 汇总。
function buildViewsFromHalfYears(readPeriod) {
const views = { all: [], annual: [], halfyear: [] };
VIEW_YEARS.forEach((year) => {
const h1 = readPeriod(year, 'H1');
const h2 = readPeriod(year, 'H2');
const fy = addPeriods(h1, h2);
if (h1) {
const row = { period: `${year}H1`, ...h1 };
views.halfyear.push(row);
views.all.push(row);
}
if (h2) {
const row = { period: `${year}H2`, ...h2 };
views.halfyear.push(row);
views.all.push(row);
}
if (fy) {
const row = { period: `${year}FY`, ...fy };
views.annual.push(row);
views.all.push(row);
}
});
return views;
}
function yoyFor(rows, key, outputKey = key) {
const byPeriod = new Map(rows.map((row) => [row.period, row]));
return rows.map((row) => {
const year = Number(row.period.slice(0, 4));
const prior = byPeriod.get(`${year - 1}${row.period.slice(4)}`);
return {
...row,
[outputKey]: prior && prior[key] !== 0 ? (row[key] / prior[key] - 1) * 100 : null,
};
});
}
function toOutputRows(rows, headers, digits = {}) {
return rows
.filter((row) => Number(row.period.slice(0, 4)) >= OUTPUT_START_YEAR)
.map((row) => headers.map((header) => {
if (header === 'period') return row.period;
const value = row[header];
return Number.isFinite(value) ? value.toFixed(digits[header] ?? 2) : '';
}));
}
function writeViewFiles(base, headers, views, digits) {
const filenames = {
all: `${base}.csv`,
annual: `${base}_annual.csv`,
halfyear: `${base}_halfyear.csv`,
};
Object.entries(filenames).forEach(([view, filename]) => {
writeCSV(filename, headers, toOutputRows(views[view], headers, digits));
});
}
const incomeDateIndex = new Map(income.dates.map((date, index) => [date, index]));
const incomeColumns = {
revenue: row(income, '一、营业总收入'),
cost: row(income, '营业成本'),
sales_expense: row(income, '减:销售费用'),
admin_expense: row(income, '管理费用'),
net_profit: row(income, '三、净利润'),
non_gaap_net_profit: row(income, '非国际公认会计准则净利润'),
};
function incomePeriod(year, type) {
const date = `${year}-${type === 'H1' ? '06-30' : '12-31'}`;
const index = incomeDateIndex.get(date);
if (index === undefined) return null;
const result = Object.fromEntries(Object.entries(incomeColumns).map(([key, values]) => [key, values[index]]));
// 2020 年非 GAAP 净利未披露,沿用现有图表的归母净利替代口径。
result.non_gaap_net_profit ??= result.net_profit;
return isComplete(result) ? result : null;
}
const cashflowDateIndex = new Map(cashflow.dates.map((date, index) => [date, index]));
const cashflowColumns = {
operating_cash_flow: row(cashflow, '经营活动产生的现金流量净额'),
investing_cash_flow: row(cashflow, '投资活动产生的现金流量净额'),
financing_cash_flow: row(cashflow, '筹资活动产生的现金流量净额'),
net_cash_increase: row(cashflow, '现金及现金等价物的净增加额'),
};
function cashflowPeriod(year, type) {
const date = `${year}-${type === 'H1' ? '06-30' : '12-31'}`;
const index = cashflowDateIndex.get(date);
if (index === undefined) return null;
const result = Object.fromEntries(Object.entries(cashflowColumns).map(([key, values]) => [key, values[index]]));
return isComplete(result) ? result : null;
}
function inBillion(values) {
return Object.fromEntries(Object.entries(values).map(([key, value]) => [key, value / HUNDRED_MILLION]));
}
const growthViews = buildViews((year, type) => {
const values = incomePeriod(year, type);
return values && {
non_gaap_net_profit: values.non_gaap_net_profit,
gross_profit: values.revenue - values.cost,
revenue: values.revenue,
cost: values.cost,
};
});
Object.keys(growthViews).forEach((view) => {
['non_gaap_net_profit', 'gross_profit', 'revenue', 'cost'].forEach((key) => {
growthViews[view] = yoyFor(growthViews[view], key);
});
});
writeViewFiles('ppmt_growth', ['period', 'non_gaap_net_profit', 'gross_profit', 'revenue', 'cost'], growthViews, {
non_gaap_net_profit: 1, gross_profit: 1, revenue: 1, cost: 1,
});
const coreProfitViews = buildViews((year, type) => {
const values = incomePeriod(year, type);
return values && { core_profit: (values.revenue - values.cost - values.sales_expense - values.admin_expense) / HUNDRED_MILLION };
});
Object.keys(coreProfitViews).forEach((view) => {
coreProfitViews[view] = yoyFor(coreProfitViews[view], 'core_profit', 'yoy');
});
writeViewFiles('ppmt_core_profit', ['period', 'core_profit', 'yoy'], coreProfitViews, { core_profit: 2, yoy: 1 });
const marginAmountViews = buildViews((year, type) => {
const values = incomePeriod(year, type);
return values && {
revenue: values.revenue,
gross_profit: values.revenue - values.cost,
sales_expense: values.sales_expense,
admin_expense: values.admin_expense,
non_gaap_net_profit: values.non_gaap_net_profit,
};
});
const marginsViews = Object.fromEntries(Object.entries(marginAmountViews).map(([view, rows]) => [
view,
rows.map((values) => {
if (values.revenue === 0) return values;
return {
period: values.period,
gross_margin: values.gross_profit / values.revenue * 100,
sales_expense_rate: values.sales_expense / values.revenue * 100,
admin_expense_rate: values.admin_expense / values.revenue * 100,
non_gaap_net_margin: values.non_gaap_net_profit / values.revenue * 100,
};
}),
]));
writeViewFiles('ppmt_margins', ['period', 'gross_margin', 'sales_expense_rate', 'admin_expense_rate', 'non_gaap_net_margin'], marginsViews, {
gross_margin: 2, sales_expense_rate: 2, admin_expense_rate: 2, non_gaap_net_margin: 2,
});
const cashConversionViews = buildViews((year, type) => {
const flow = cashflowPeriod(year, type);
const incomeValues = incomePeriod(year, type);
if (!flow || !incomeValues) return null;
return inBillion({
operating_cash_flow: flow.operating_cash_flow,
net_profit: incomeValues.net_profit,
});
});
Object.values(cashConversionViews).forEach((rows) => rows.forEach((row) => {
row.cash_conversion = row.net_profit === 0 ? null : row.operating_cash_flow / row.net_profit * 100;
}));
writeViewFiles('ppmt_cash_conversion', ['period', 'operating_cash_flow', 'net_profit', 'cash_conversion'], cashConversionViews, {
operating_cash_flow: 2, net_profit: 2, cash_conversion: 1,
});
const cashflowCompositionViews = buildViews((year, type) => {
const values = cashflowPeriod(year, type);
return values && inBillion(values);
});
writeViewFiles('ppmt_cashflow_composition', ['period', 'operating_cash_flow', 'investing_cash_flow', 'financing_cash_flow', 'net_cash_increase'], cashflowCompositionViews, {
operating_cash_flow: 2, investing_cash_flow: 2, financing_cash_flow: 2, net_cash_increase: 2,
});
const channelKeysForViews = [
['零售店銷售收益', 'retail'],
['線上銷售收益', 'online'],
['機器人商店銷售收益', 'robot_store'],
['批發收益', 'wholesale'],
];
const revenueDateIndex = new Map(revenueComposition.dates.map((date, index) => [date, index]));
function channelPeriod(year, type) {
const index = revenueDateIndex.get(`${year}-Q${type === 'H1' ? 2 : 4}`);
if (index === undefined) return null;
const values = Object.fromEntries(channelKeysForViews.map(([name, key]) => [
key, revenueComposition.channels.get(`${name}:收入`)?.[index] ?? null,
]));
const total = revenueComposition.channels.get('totalRevenue')?.[index] ?? null;
return isComplete({ ...values, total }) ? inBillion({ ...values, total_revenue: total }) : null;
}
const channelRevenueViews = buildViews(channelPeriod);
Object.keys(channelRevenueViews).forEach((view) => {
channelRevenueViews[view] = yoyFor(channelRevenueViews[view], 'total_revenue', 'revenue_yoy');
});
writeViewFiles('ppmt_channel_revenue', ['period', 'retail', 'online', 'robot_store', 'wholesale', 'total_revenue', 'revenue_yoy'], channelRevenueViews, {
retail: 2, online: 2, robot_store: 2, wholesale: 2, total_revenue: 2, revenue_yoy: 1,
});
console.log('已生成首批六图的全部、年度、半年 CSV。');
const profitViews = buildViews((year, type) => {
const values = incomePeriod(year, type);
return values && inBillion({
revenue: values.revenue,
gross_profit: values.revenue - values.cost,
net_profit: values.net_profit,
});
});
Object.values(profitViews).forEach((rows) => rows.forEach((item) => {
item.gross_margin = item.revenue === 0 ? null : item.gross_profit / item.revenue * 100;
}));
writeViewFiles('ppmt_profit', ['period', 'revenue', 'gross_profit', 'gross_margin', 'net_profit'], profitViews, {
revenue: 2, gross_profit: 2, gross_margin: 2, net_profit: 2,
});
const coreMarginViews = buildViews((year, type) => {
const values = incomePeriod(year, type);
return values && {
revenue: values.revenue,
core_profit: values.revenue - values.cost - values.sales_expense - values.admin_expense,
};
});
Object.values(coreMarginViews).forEach((rows) => rows.forEach((item) => {
item.core_margin = item.revenue === 0 ? null : item.core_profit / item.revenue * 100;
}));
writeViewFiles('ppmt_core_margin', ['period', 'core_margin'], coreMarginViews, { core_margin: 1 });
const expenseAmountViews = buildViews((year, type) => {
const values = incomePeriod(year, type);
if (!values) return null;
const financialExpense = row(income, '财务费用')[incomeDateIndex.get(`${year}-${type === 'H1' ? '06-30' : '12-31'}`)];
return {
revenue: values.revenue,
sales_expense: values.sales_expense,
admin_expense: values.admin_expense,
financial_expense: financialExpense,
};
});
const expenseViews = Object.fromEntries(Object.entries(expenseAmountViews).map(([view, rows]) => [
view,
rows.map((item) => ({
...inBillion(item),
period: item.period,
four_expense_rate: (item.sales_expense + item.admin_expense + item.financial_expense) / item.revenue * 100,
})),
]));
writeViewFiles('ppmt_expense_structure', ['period', 'sales_expense', 'admin_expense', 'financial_expense', 'four_expense_rate'], expenseViews, {
sales_expense: 2, admin_expense: 2, financial_expense: 2, four_expense_rate: 1,
});
function readRuntimeRows(filename) {
const [header, ...lines] = fs.readFileSync(path.join(OUTPUT_DIR, filename), 'utf8').trim().split(/\r?\n/);
const headers = header.split(',');
return lines.map((line) => Object.fromEntries(line.split(',').map((cell, index) => {
const value = Number(cell);
return [headers[index], cell !== '' && Number.isFinite(value) ? value : cell];
})));
}
function writeRuntimeViews(base, headers, views, digits = {}) {
writeViewFiles(base, headers, views, digits);
}
function buildWideIpViews(filename) {
const rows = readRuntimeRows(filename);
const id = Object.keys(rows[0])[0];
const sourcePeriods = Object.keys(rows[0]).slice(1).filter((period) => /H[12]$/.test(period));
const years = [...new Set(sourcePeriods.map((period) => period.slice(0, 4)))];
const halfyear = sourcePeriods;
const annual = years.filter((year) => sourcePeriods.includes(`${year}H1`) && sourcePeriods.includes(`${year}H2`)).map((year) => `${year}FY`);
const all = years.flatMap((year) => [
...(sourcePeriods.includes(`${year}H1`) ? [`${year}H1`] : []),
...(sourcePeriods.includes(`${year}H2`) ? [`${year}H2`, `${year}FY`] : []),
]);
const valuesFor = (periods) => rows.map((row) => [row[id], ...periods.map((period) => {
if (!period.endsWith('FY')) return row[period];
return row[`${period.slice(0, 4)}H1`] + row[`${period.slice(0, 4)}H2`];
})]);
writeCSV(filename, [id, ...all], valuesFor(all));
writeCSV(filename.replace('.csv', '_annual.csv'), [id, ...annual], valuesFor(annual));
writeCSV(filename.replace('.csv', '_halfyear.csv'), [id, ...halfyear], valuesFor(halfyear));
}
buildWideIpViews('ppmt_ip.csv');
buildWideIpViews('ppmt_ip_share_history.csv');
const ipExMonstersRows = readRuntimeRows('ppmt_ip_ex_monsters.csv');
function ipExMonstersPeriod(year, type) {
const row = ipExMonstersRows.find((item) => item.period === `${year}${type}`);
return row ? { revenue: row.revenue } : null;
}
const ipExMonstersViews = buildViewsFromHalfYears(ipExMonstersPeriod);
Object.keys(ipExMonstersViews).forEach((view) => {
ipExMonstersViews[view] = yoyFor(ipExMonstersViews[view], 'revenue', 'yoy');
});
writeRuntimeViews('ppmt_ip_ex_monsters', ['period', 'revenue', 'yoy'], ipExMonstersViews, { revenue: 2, yoy: 1 });
const categoryRows = readRuntimeRows('ppmt_category.csv').filter((item) => item.period !== '品类');
function categoryPeriod(year, type) {
const row = categoryRows.find((item) => item.period === `${year}${type}`);
return row && { plush: row.plush, figure: row.figure, mega: row.mega, other: row.other };
}
const categoryViews = buildViewsFromHalfYears(categoryPeriod);
writeRuntimeViews('ppmt_category', ['period', 'plush', 'figure', 'mega', 'other'], categoryViews, {
plush: 2, figure: 2, mega: 2, other: 2,
});
// 资产负债表为时点指标:H2 是年末时点,而非“全年累计”。
function buildSnapshotViews(base, headers, digits) {
const source = readRuntimeRows(`${base}.csv`);
const views = { all: [], annual: [], halfyear: [] };
VIEW_YEARS.forEach((year) => {
const h1 = source.find((row) => row.period === `${year}H1`);
const yearEnd = source.find((row) => row.period === `${year}H2` || row.period === `${year}FY`);
if (h1) {
const row = { ...h1, period: `${year}H1` };
views.all.push(row);
views.halfyear.push(row);
}
if (yearEnd) {
const halfyearRow = { ...yearEnd, period: `${year}H2` };
views.all.push(halfyearRow);
views.halfyear.push(halfyearRow);
views.annual.push({ ...yearEnd, period: `${year}FY` });
}
});
writeRuntimeViews(base, headers, views, digits);
}
buildSnapshotViews('ppmt_assets', ['period', 'total_assets', 'cash_like', 'receivables', 'investment', 'operating_assets'], {
total_assets: 2, cash_like: 2, receivables: 2, investment: 2, operating_assets: 2,
});
buildSnapshotViews('ppmt_liquidity_working_capital', ['period', 'cash', 'total_liabilities', 'net_working_capital'], {
cash: 2, total_liabilities: 2, net_working_capital: 2,
});
console.log('已生成第二批连续图表的全部、年度、半年 CSV。');
+1 -1
View File
@@ -70,7 +70,7 @@ for (const entry of targets) {
if (!csvPath.startsWith(`${ROOT}${path.sep}`)) throw new Error(`CSV 路径越过项目根目录:${entry.csv}`); if (!csvPath.startsWith(`${ROOT}${path.sep}`)) throw new Error(`CSV 路径越过项目根目录:${entry.csv}`);
const rows = parseCSV(fs.readFileSync(csvPath, 'utf8')); const rows = parseCSV(fs.readFileSync(csvPath, 'utf8'));
const chart = echarts.init(null, null, { renderer: 'svg', ssr: true, width: 1100, height: 720 }); const chart = echarts.init(null, null, { renderer: 'svg', ssr: true, width: 1100, height: 720 });
const option = getChartBuilder(entry.key)(rows, { width: 1100, height: 720 }); const option = getChartBuilder(entry.key)(rows, { width: 1100, height: 720, view: entry.view || undefined });
chart.setOption(option); chart.setOption(option);
const svg = chart.renderToSVGString(); const svg = chart.renderToSVGString();
chart.dispose(); chart.dispose();