Skip to content

Commit 94ed00b

Browse files
committed
multi line label "most biased cluster" and fixed y-axis on categorical chart
1 parent 62e868e commit 94ed00b

File tree

3 files changed

+91
-9
lines changed

3 files changed

+91
-9
lines changed

src/components/graphs/GroupBarChart.tsx

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ interface GroupBarChartProps {
1111
data: Data[];
1212
}
1313

14-
const margin = { top: 10, right: 10, bottom: 40, left: 10 };
14+
const margin = { top: 10, right: 10, bottom: 40, left: 50 };
1515
const height = 300 - margin.top - margin.bottom;
1616
const barWidth = 0.05 * window.innerWidth < 40 ? 40 : 0.05 * window.innerWidth;
17+
const barGap = 5;
1718

1819
const GroupBarChart = ({ title, data }: GroupBarChartProps) => {
1920
const svgRef = useRef<SVGSVGElement>(null);
@@ -26,8 +27,12 @@ const GroupBarChart = ({ title, data }: GroupBarChartProps) => {
2627
.domain(new Set(data.map(d => d.name)))
2728
.range([
2829
0,
29-
Math.max(containerWidth, data.length * barWidth) -
30-
margin.right,
30+
Math.max(
31+
containerWidth - margin.right - margin.left,
32+
data.length * (barWidth + barGap) -
33+
margin.right -
34+
margin.left
35+
),
3136
])
3237
.padding(0.2),
3338
[data, containerWidth]
@@ -40,9 +45,7 @@ const GroupBarChart = ({ title, data }: GroupBarChartProps) => {
4045
.domain(groupbarNames)
4146
.rangeRound([0, fx.bandwidth()])
4247
.padding(0.05);
43-
groupbarNames.forEach((name, i) => {
44-
console.log('groupbarNames', name, i);
45-
});
48+
4649
const color = d3
4750
.scaleOrdinal()
4851
.domain(groupbarNames)
@@ -65,7 +68,10 @@ const GroupBarChart = ({ title, data }: GroupBarChartProps) => {
6568
const svg = d3
6669
.select(svgRef.current)
6770
.attr('class', `min-h-[${height}px]`)
68-
.attr('width', Math.max(containerWidth, data.length * barWidth))
71+
.attr(
72+
'width',
73+
Math.max(containerWidth, margin.left + data.length * barWidth)
74+
)
6975
.attr('height', height + margin.top + margin.bottom)
7076
.append('g')
7177
.attr('transform', `translate(${margin.left},${margin.top})`);
@@ -122,7 +128,7 @@ const GroupBarChart = ({ title, data }: GroupBarChartProps) => {
122128

123129
// Add a label for the mean line
124130
svg.append('text')
125-
.attr('x', margin.left + 30)
131+
.attr('x', margin.left + 30 + 50)
126132
.attr('y', y(meanValue) - 5)
127133
.attr('text-anchor', 'end')
128134
.attr('fill', 'black')
@@ -164,6 +170,7 @@ const GroupBarChart = ({ title, data }: GroupBarChartProps) => {
164170
.attr('x', 20)
165171
.attr('y', 12)
166172
.text(d => d);
173+
167174
if (legend) {
168175
const legendBBox = legend.node()?.getBBox();
169176
if (legendBBox) {
@@ -173,6 +180,44 @@ const GroupBarChart = ({ title, data }: GroupBarChartProps) => {
173180
);
174181
}
175182
}
183+
184+
xAxis.selectAll('.tick text').call((text, width) => {
185+
text.each(function () {
186+
let word: string | undefined = '';
187+
const text = d3.select(this),
188+
words = text.text().split(/\n+/).reverse(),
189+
lineHeight = 1.1, // ems
190+
y = text.attr('y'),
191+
dy = parseFloat(text.attr('dy'));
192+
let lineNumber = 0;
193+
let line: string[] = [];
194+
let tspan = text
195+
.text(null)
196+
.append('tspan')
197+
.attr('x', 0)
198+
.attr('y', y)
199+
.attr('dy', dy + 'em');
200+
// eslint-disable-next-line no-cond-assign
201+
while ((word = words.pop())) {
202+
line.push(word);
203+
tspan.text(line.join(' '));
204+
if (
205+
tspan?.node?.()?.getComputedTextLength?.() ??
206+
0 > width
207+
) {
208+
line.pop();
209+
tspan.text(line.join(' '));
210+
line = [word];
211+
tspan = text
212+
.append('tspan')
213+
.attr('x', 0)
214+
.attr('y', y)
215+
.attr('dy', ++lineNumber * lineHeight + dy + 'em')
216+
.text(word);
217+
}
218+
}
219+
});
220+
}, barWidth);
176221
}, [data, x0, y, color, title, containerWidth]);
177222

178223
useEffect(() => {

src/components/graphs/SingleBarChart.tsx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,43 @@ const SingleBarChart = ({ title, data }: SingleBarChartProps) => {
137137
// Append y-axis to the SVG container
138138
svg.append('g').call(d3.axisLeft(y).ticks(10, 's')); // Create the y-axis using the y scale
139139

140+
xAxis.selectAll('.tick text').call((text, width) => {
141+
text.each(function () {
142+
let word: string | undefined = '';
143+
const text = d3.select(this),
144+
words = text.text().split(/\n+/).reverse(),
145+
lineHeight = 1.1, // ems
146+
y = text.attr('y'),
147+
dy = parseFloat(text.attr('dy'));
148+
let lineNumber = 0;
149+
let line: string[] = [];
150+
let tspan = text
151+
.text(null)
152+
.append('tspan')
153+
.attr('x', 0)
154+
.attr('y', y)
155+
.attr('dy', dy + 'em');
156+
// eslint-disable-next-line no-cond-assign
157+
while ((word = words.pop())) {
158+
line.push(word);
159+
tspan.text(line.join(' '));
160+
if (
161+
tspan?.node?.()?.getComputedTextLength?.() ??
162+
0 > width
163+
) {
164+
line.pop();
165+
tspan.text(line.join(' '));
166+
line = [word];
167+
tspan = text
168+
.append('tspan')
169+
.attr('x', 0)
170+
.attr('y', y)
171+
.attr('dy', ++lineNumber * lineHeight + dy + 'em')
172+
.text(word);
173+
}
174+
}
175+
});
176+
}, barWidth);
140177
// Add a legend label for the mean line
141178
}, [data, x0, y, title, containerWidth]);
142179

src/components/graphs/get-label.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export const getLabel = (index: number) => {
22
if (index === 0) {
3-
return 'Most biased';
3+
return 'Most biased\ncluster';
44
}
55

66
return `Cluster ${index}`;

0 commit comments

Comments
 (0)