11import { useEffect , useRef , useState } from 'react' ;
22import * as d3 from 'd3' ;
3+ import { useTranslation } from 'react-i18next' ;
34
45interface DistributionBarChartProps {
56 column : string ;
@@ -8,7 +9,7 @@ interface DistributionBarChartProps {
89}
910
1011// Define margins for the chart
11- const margin = { top : 10 , right : 50 , bottom : 40 , left : 50 } ;
12+ const margin = { top : 30 , right : 50 , bottom : 40 , left : 50 } ;
1213// Define height for the chart, adjusting for margins
1314const height = 300 - margin . top - margin . bottom ;
1415
@@ -24,38 +25,7 @@ const DistributionBarChart = ({
2425 const svgRef = useRef < SVGSVGElement > ( null ) ; // Reference to the SVG element
2526 const containerRef = useRef < HTMLDivElement > ( null ) ; // Reference to the container div
2627 const [ containerWidth , setContainerWidth ] = useState ( 800 ) ; // Default container width
27-
28- // Create x-axis scale using d3.scaleBand, with padding for spacing between bars
29- // const x0 = useMemo(
30- // () =>
31- // d3
32- // .scaleBand()
33- // .domain(data.map(d => d.name))
34- // .range([
35- // 0,
36- // Math.max(
37- // containerWidth - margin.right,
38- // data.length * (barWidth + barGap)
39- // ),
40- // ])
41- // .padding(0.2),
42- // [data, containerWidth]
43- // );
44-
45- // // Create y-axis scale using d3.scaleLinear, with a range from the height to 0
46- // const y = useMemo(
47- // () =>
48- // d3
49- // .scaleLinear()
50- // .domain([
51- // d3.min(data, d => d.values) ?? 0, // Minimum value in the dataset (or 0 if undefined)
52- // d3.max(data, d => d.values) ?? 0, // Maximum value in the dataset (or 0 if undefined)
53- // ])
54- // .nice() // Rounds the domain to nice round values
55- // .range([height, 0]),
56- // [data]
57- // );
58-
28+ const { t } = useTranslation ( ) ;
5929 useEffect ( ( ) => {
6030 const plotWidth = containerWidth - margin . left - margin . right ;
6131 const plotHeight = height - margin . top - margin . bottom ;
@@ -160,9 +130,67 @@ const DistributionBarChart = ({
160130 . attr ( 'text-anchor' , 'middle' )
161131 . style ( 'font-size' , '12px' )
162132 . style ( 'font-weight' , 'bold' )
163- . text ( `Distribution for ${ column } ` ) ;
133+ . text ( `${ t ( 'distribution.distributionFor' ) } ${ column } ` ) ;
164134
165- // Add a legend label for the mean line
135+ // Add legend
136+ const legend = svg
137+ . append ( 'g' )
138+ . attr ( 'class' , 'legend' )
139+ . attr ( 'transform' , `translate(${ plotWidth - 120 } , -20)` ) ;
140+
141+ // Add the text elements first so we can measure them
142+ const realDataText = legend
143+ . append ( 'text' )
144+ . attr ( 'x' , 20 )
145+ . attr ( 'y' , 12 )
146+ . style ( 'font-size' , '12px' )
147+ . text ( t ( 'distribution.realData' ) ) ;
148+
149+ const syntheticDataText = legend
150+ . append ( 'text' )
151+ . attr ( 'x' , 20 )
152+ . attr ( 'y' , 32 )
153+ . style ( 'font-size' , '12px' )
154+ . text ( t ( 'distribution.syntheticData' ) ) ;
155+
156+ // Calculate the width needed based on the longest text
157+ const realTextWidth = realDataText . node ( ) ?. getBBox ( ) . width || 0 ;
158+ const syntheticTextWidth =
159+ syntheticDataText . node ( ) ?. getBBox ( ) . width || 0 ;
160+ const maxTextWidth = Math . max ( realTextWidth , syntheticTextWidth ) ;
161+ const legendWidth = maxTextWidth + 40 ; // 40 = 20px text offset + 15px rect width + 5px padding
162+
163+ // Add background rectangle for legend with calculated width
164+ legend
165+ . insert ( 'rect' , 'text' ) // Insert before the text elements
166+ . attr ( 'x' , - 10 )
167+ . attr ( 'y' , - 10 )
168+ . attr ( 'width' , legendWidth )
169+ . attr ( 'height' , 55 )
170+ . attr ( 'rx' , 5 )
171+ . style ( 'fill' , 'white' )
172+ . style ( 'opacity' , 0.7 )
173+ . style ( 'stroke' , '#e2e8f0' )
174+ . style ( 'stroke-width' , 1 ) ;
175+
176+ // Add the colored rectangles
177+ legend
178+ . append ( 'rect' )
179+ . attr ( 'x' , 0 )
180+ . attr ( 'y' , 0 )
181+ . attr ( 'width' , 15 )
182+ . attr ( 'height' , 15 )
183+ . style ( 'fill' , 'steelblue' )
184+ . style ( 'opacity' , 0.5 ) ;
185+
186+ legend
187+ . append ( 'rect' )
188+ . attr ( 'x' , 0 )
189+ . attr ( 'y' , 20 )
190+ . attr ( 'width' , 15 )
191+ . attr ( 'height' , 15 )
192+ . style ( 'fill' , 'orange' )
193+ . style ( 'opacity' , 0.5 ) ;
166194 } , [ containerWidth , column , realData , syntheticData ] ) ;
167195
168196 useEffect ( ( ) => {
0 commit comments