Skip to content

Commit

Permalink
feat: add legend title alignment option (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
kuzmadom authored Dec 5, 2024
1 parent fe69001 commit 5d47b17
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 15 deletions.
18 changes: 8 additions & 10 deletions src/__stories__/__data__/pie/continuous-legend.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
import {groups} from 'd3';

import {formatNumber} from '../../../libs';
import type {ChartData, PieSeriesData} from '../../../types';
import {getContinuesColorFn} from '../../../utils';
import nintendoGames from '../nintendoGames';

function prepareData(): ChartData {
const colors = ['rgb(255, 61, 100)', 'rgb(255, 198, 54)', 'rgb(84, 165, 32)'];
const stops = [0, 0.5, 1];

const gamesByPlatform = groups(nintendoGames, (item) => item.platform);
const data: PieSeriesData[] = gamesByPlatform.map(([platform, games]) => ({
name: platform,
value: games.length,
label: `${platform}(${games.length})`,
}));
const data: PieSeriesData[] = [
{name: 'A', value: 1200000},
{name: 'B', value: 900000},
{name: 'C', value: 1310000},
];
const getColor = getContinuesColorFn({colors, stops, values: data.map((d) => d.value)});
data.forEach((d) => {
d.color = getColor(d.value);
d.label = formatNumber(d.value, {unit: 'auto'});
});

return {
Expand All @@ -32,7 +30,7 @@ function prepareData(): ChartData {
legend: {
enabled: true,
type: 'continuous',
title: {text: 'Games by platform'},
title: {text: 'Legend for continues color'},
colorScale: {
colors: colors,
stops,
Expand Down
30 changes: 25 additions & 5 deletions src/components/Legend/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type {
SymbolLegendSymbol,
} from '../../hooks';
import {getLineDashArray} from '../../hooks/useShapes/utils';
import {formatNumber} from '../../libs';
import {
block,
createGradientRect,
Expand All @@ -39,9 +40,9 @@ const getLegendPosition = (args: {
align: PreparedLegend['align'];
contentWidth: number;
width: number;
offsetWidth: number;
offsetWidth?: number;
}) => {
const {align, offsetWidth, width, contentWidth} = args;
const {align, offsetWidth = 0, width, contentWidth} = args;
const top = 0;

if (align === 'left') {
Expand Down Expand Up @@ -311,14 +312,16 @@ export const Legend = (props: Props) => {
});

// ticks
const scale = scaleLinear(domain, [0, legend.width]) as AxisScale<AxisDomain>;
const xAxisGenerator = axisBottom({
scale: scaleLinear(domain, [0, legend.width]) as AxisScale<AxisDomain>,
scale,
ticks: {
items: [[0, -rectHeight]],
labelsMargin: legend.ticks.labelsMargin,
labelsLineHeight: legend.ticks.labelsLineHeight,
maxTickCount: 4,
tickColor: '#fff',
labelFormat: (value: number) => formatNumber(value, {unit: 'auto'}),
},
domain: {
size: legend.width,
Expand All @@ -334,15 +337,32 @@ export const Legend = (props: Props) => {
}

if (legend.title.enable) {
const {maxWidth: labelWidth} = getLabelsSize({
const {maxWidth: titleWidth} = getLabelsSize({
labels: [legend.title.text],
style: legend.title.style,
});
let dx = 0;
switch (legend.title.align) {
case 'center': {
dx = legend.width / 2 - titleWidth / 2;
break;
}
case 'right': {
dx = legend.width - titleWidth;
break;
}
case 'left':
default: {
dx = 0;
break;
}
}

svgElement
.append('g')
.attr('class', b('title'))
.append('text')
.attr('dx', legend.width / 2 - labelWidth / 2)
.attr('dx', dx)
.attr('font-weight', legend.title.style.fontWeight ?? null)
.attr('font-size', legend.title.style.fontSize ?? null)
.attr('fill', legend.title.style.fontColor ?? null)
Expand Down
1 change: 1 addition & 0 deletions src/hooks/useSeries/prepare-legend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export const getPreparedLegend = (args: {
margin: titleMargin,
style: titleStyle,
height: titleHeight,
align: get(legend, 'title.align', 'left'),
},
width: legendWidth,
ticks,
Expand Down
1 change: 1 addition & 0 deletions src/hooks/useSeries/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export type PreparedLegend = Required<Omit<ChartLegend, 'title' | 'colorScale'>>
margin: number;
style: BaseTextStyle;
height: number;
align: Required<Required<ChartLegend>['title']>['align'];
};
ticks: {
labelsMargin: number;
Expand Down
2 changes: 2 additions & 0 deletions src/types/chart/legend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ export type ChartLegend = {
* Defaults to 4 for horizontal axes, 8 for vertical.
* */
margin?: number;
/** The horizontal alignment of the title. */
align?: 'left' | 'center' | 'right';
};
/* Gradient color settings for continuous legend type */
colorScale?: {
Expand Down

0 comments on commit 5d47b17

Please sign in to comment.