11"use client" ;
22
33import { useEvaluation } from "@/context/EvaluationContext" ;
4- import React , { useMemo } from "react" ;
4+ import React , { useMemo , useState , useEffect } from "react" ;
55import ReactECharts from "echarts-for-react" ;
66import { Card , CardContent , CardDescription , CardHeader , CardTitle } from "@/components/ui/card" ;
77import type { EChartsOption , PieSeriesOption } from "echarts" ;
@@ -15,6 +15,19 @@ export function TaskDistributionChart({ chartType = "organ" }: TaskDistributionC
1515 getFilteredTasks,
1616 } = useEvaluation ( ) ;
1717
18+ // Use React state for responsive design instead of window object
19+ const [ isMobile , setIsMobile ] = useState ( false ) ;
20+
21+ useEffect ( ( ) => {
22+ const checkIsMobile = ( ) => {
23+ setIsMobile ( window . innerWidth < 768 ) ;
24+ } ;
25+
26+ checkIsMobile ( ) ;
27+ window . addEventListener ( 'resize' , checkIsMobile ) ;
28+ return ( ) => window . removeEventListener ( 'resize' , checkIsMobile ) ;
29+ } , [ ] ) ;
30+
1831 const chartOptions = useMemo ( ( ) : EChartsOption => {
1932 const filteredTasks = getFilteredTasks ( ) ;
2033
@@ -50,8 +63,8 @@ export function TaskDistributionChart({ chartType = "organ" }: TaskDistributionC
5063 const pieSeries : PieSeriesOption = {
5164 name : "Organ Distribution" ,
5265 type : "pie" ,
53- radius : [ " 45%", "75%" ] , // Donut chart
54- center : [ "65%" , "60%" ] ,
66+ radius : isMobile ? [ "35%" , "65%" ] : [ " 45%", "75%" ] , // Donut chart - moderate size
67+ center : isMobile ? [ "65%" , "55%" ] : [ " 60%", "55%" ] , // Move down for more space from title
5568 avoidLabelOverlap : true ,
5669 itemStyle : {
5770 borderRadius : 10 ,
@@ -65,7 +78,7 @@ export function TaskDistributionChart({ chartType = "organ" }: TaskDistributionC
6578 emphasis : {
6679 label : {
6780 show : true ,
68- fontSize : 16 ,
81+ fontSize : isMobile ? 14 : 16 ,
6982 fontWeight : "bold" ,
7083 } ,
7184 } ,
@@ -88,27 +101,31 @@ export function TaskDistributionChart({ chartType = "organ" }: TaskDistributionC
88101
89102 title : {
90103 text : "Task Distribution by Organ" ,
91- top : '4.5%' ,
104+ top : isMobile ? '2%' : '1%' , // Higher on mobile too
92105 left : "center" ,
93106 textStyle : {
94- fontSize : ( typeof window !== 'undefined' && window . innerWidth < 768 ) ? 14 : 16 ,
107+ fontSize : isMobile ? 14 : 18 , // Larger font on desktop
108+ fontWeight : 'bold' ,
95109 }
96110 } ,
97111 tooltip : {
98112 trigger : "item" ,
99113 formatter : "{a} <br/>{b}: {c} ({d}%)" ,
100114 } ,
101115 legend : {
102- orient : ( typeof window !== 'undefined' && window . innerWidth < 768 ) ? "horizontal" : "vertical" ,
103- left : ( typeof window !== 'undefined' && window . innerWidth < 768 ) ? "center" : 5 ,
104- top : ( typeof window !== 'undefined' && window . innerWidth < 768 ) ? 'bottom' : '42.5%' ,
105- bottom : ( typeof window !== 'undefined' && window . innerWidth < 768 ) ? 10 : undefined ,
116+ orient : "vertical" ,
117+ left : isMobile ? 5 : 10 ,
118+ top : isMobile ? '30%' : '30%' , // Move down to match pie chart center
119+ bottom : undefined ,
106120 type : "scroll" ,
107121 z : 0 ,
108122 textStyle : {
109- fontSize : ( typeof window !== 'undefined' && window . innerWidth < 768 ) ? 12 : 14 ,
123+ fontSize : isMobile ? 13 : 16 , // Larger font for mobile too
110124 color : '#333' ,
111125 } ,
126+ itemWidth : isMobile ? 12 : 16 , // Slightly larger icons for mobile
127+ itemHeight : isMobile ? 12 : 16 ,
128+ itemGap : isMobile ? 8 : 15 , // More spacing for mobile
112129 } ,
113130 series : [ pieSeries ] ,
114131 } ;
@@ -120,20 +137,21 @@ export function TaskDistributionChart({ chartType = "organ" }: TaskDistributionC
120137 taskTypeCounts [ taskType ] = ( taskTypeCounts [ taskType ] || 0 ) + 1 ;
121138 } ) ;
122139
123- // Format data for pie chart
124- const data = Object . entries ( taskTypeCounts ) . map ( ( [ taskType , count ] ) => {
125- return {
126- name : taskType . replace ( '_' , ' ' ) ,
127- value : count ,
128- } ;
129- } ) ;
140+ // Format data for pie chart with custom order
141+ const taskTypeOrder = [ 'Classification' , 'DFS Prediction' , 'DSS Prediction' , 'OS Prediction' ] ;
142+ const data = taskTypeOrder
143+ . filter ( taskType => taskTypeCounts [ taskType ] > 0 ) // Only include types that exist
144+ . map ( taskType => ( {
145+ name : taskType ,
146+ value : taskTypeCounts [ taskType ] ,
147+ } ) ) ;
130148
131149 // Create pie series
132150 const pieSeries : PieSeriesOption = {
133151 name : "Task Type Distribution" ,
134152 type : "pie" ,
135- radius : [ " 45%", "75%" ] ,
136- center : [ " 70%", "60 %" ] ,
153+ radius : isMobile ? [ "35%" , "65%" ] : [ " 45%", "75%" ] , // Moderate size for better balance
154+ center : isMobile ? [ "65%" , "55%" ] : [ " 70%", "55 %" ] , // Move down and right for better spacing
137155 avoidLabelOverlap : true ,
138156 itemStyle : {
139157 borderRadius : 10 ,
@@ -147,7 +165,7 @@ export function TaskDistributionChart({ chartType = "organ" }: TaskDistributionC
147165 emphasis : {
148166 label : {
149167 show : true ,
150- fontSize : 16 ,
168+ fontSize : isMobile ? 14 : 16 ,
151169 fontWeight : "bold" ,
152170 } ,
153171 } ,
@@ -170,42 +188,46 @@ export function TaskDistributionChart({ chartType = "organ" }: TaskDistributionC
170188
171189 title : {
172190 text : "Task Distribution by Type" ,
173- top : '4.5%' ,
191+ top : isMobile ? '2%' : '1%' , // Higher on mobile too
174192 left : "center" ,
175193 textStyle : {
176- fontSize : ( typeof window !== 'undefined' && window . innerWidth < 768 ) ? 14 : 16 ,
194+ fontSize : isMobile ? 14 : 18 , // Larger font on desktop
195+ fontWeight : 'bold' ,
177196 }
178197 } ,
179198 tooltip : {
180199 trigger : "item" ,
181200 formatter : "{a} <br/>{b}: {c} ({d}%)" ,
182201 } ,
183202 legend : {
184- orient : ( typeof window !== 'undefined' && window . innerWidth < 768 ) ? "horizontal" : "vertical" ,
185- left : ( typeof window !== 'undefined' && window . innerWidth < 768 ) ? "center" : 0 ,
186- top : ( typeof window !== 'undefined' && window . innerWidth < 768 ) ? 'bottom' : '42 .5%' ,
187- bottom : ( typeof window !== 'undefined' && window . innerWidth < 768 ) ? 10 : undefined ,
203+ orient : "vertical" ,
204+ left : isMobile ? 5 : 2.5 ,
205+ top : isMobile ? '37.5%' : '37 .5%' , // Move down to match pie chart center
206+ bottom : undefined ,
188207 type : "scroll" ,
189208 z : 0 ,
190209 textStyle : {
191- fontSize : ( typeof window !== 'undefined' && window . innerWidth < 768 ) ? 12 : 14 ,
210+ fontSize : isMobile ? 13 : 16 , // Larger font for mobile too
192211 color : '#333' ,
193212 } ,
213+ itemWidth : isMobile ? 12 : 16 , // Slightly larger icons for mobile
214+ itemHeight : isMobile ? 12 : 16 ,
215+ itemGap : isMobile ? 8 : 15 , // More spacing for mobile
194216 } ,
195217 series : [ pieSeries ] ,
196218 } ;
197219 }
198- } , [ getFilteredTasks , chartType ] ) ;
220+ } , [ getFilteredTasks , chartType , isMobile ] ) ;
199221
200222 return (
201- < Card className = "w-full h-[250px] sm:h-[300px ]" >
202- < CardContent className = "h-[250px] sm:h-[300px ] p-2 sm:p-6" >
223+ < Card className = "w-full h-[250px] sm:h-[350px ]" >
224+ < CardContent className = "h-[250px] sm:h-[350px ] p-2 sm:p-6" >
203225 < ReactECharts
204226 option = { chartOptions }
205227 style = { { height : "100%" , width : "100%" } }
206228 opts = { {
207229 renderer : "svg" ,
208- devicePixelRatio : ( typeof window !== 'undefined' && window . innerWidth < 768 ) ? 1 : 2
230+ devicePixelRatio : isMobile ? 1 : 2
209231 } }
210232 />
211233 </ CardContent >
0 commit comments