Skip to content

Commit fc78144

Browse files
authored
Merge pull request #13 from NGO-Algorithm-Audit/feature/distribution-chart-legend
legend and translated texts for distribution charts
2 parents d7cd623 + 987ba75 commit fc78144

File tree

3 files changed

+73
-35
lines changed

3 files changed

+73
-35
lines changed

src/components/graphs/DistributionBarChart.tsx

Lines changed: 63 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { useEffect, useRef, useState } from 'react';
22
import * as d3 from 'd3';
3+
import { useTranslation } from 'react-i18next';
34

45
interface 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
1314
const 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(() => {

src/locales/en.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,5 +118,10 @@
118118
"heatmap": {
119119
"realdata": "Correlation matrix of real data",
120120
"syntheticdata": "Correlation matrix of synthetic data"
121+
},
122+
"distribution": {
123+
"distributionFor": "Distribution for",
124+
"syntheticData": "Synthetic data",
125+
"realData": "Real data"
121126
}
122127
}

src/locales/nl.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,5 +118,10 @@
118118
"heatmap": {
119119
"realdata": "Correlatie matrix van echte data",
120120
"syntheticdata": "Correlatie matrix van synthetische data"
121+
},
122+
"distribution": {
123+
"distributionFor": "Distributie voor",
124+
"syntheticData": "Synthetische data",
125+
"realData": "Echte data"
121126
}
122127
}

0 commit comments

Comments
 (0)