Skip to content

Commit

Permalink
✨ Provide options to customize bar paddings (#27)
Browse files Browse the repository at this point in the history
  • Loading branch information
joao-m-santos authored Oct 24, 2022
2 parents 25db4fd + b7444ae commit 693775b
Show file tree
Hide file tree
Showing 13 changed files with 99 additions and 32 deletions.
4 changes: 2 additions & 2 deletions src/components/charts/lume-bar-chart/lume-bar-chart.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { computed, defineAsyncComponent, defineComponent, PropType } from 'vue';
import { singleDatasetValidator } from '@/utils/helpers';
import { withChartProps } from '@/composables/props';
import { Options } from '@/composables/options';
import { BarChartOptions, Options } from '@/composables/options';
import { ORIENTATIONS } from '@/constants';
Expand All @@ -39,7 +39,7 @@ export default defineComponent({
),
},
props: {
...withChartProps(),
...withChartProps<BarChartOptions>(),
type: {
type: String as PropType<TYPES>,
default: null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { computed, defineComponent, toRefs } from 'vue';
import LumeChart from '@/components/core/lume-chart';
import LumeBarGroup from '@/components/groups/lume-bar-group';
import { useOptions } from '@/composables/options';
import { BarChartOptions, useOptions } from '@/composables/options';
import { withChartProps } from '@/composables/props';
import { ORIENTATIONS } from '@/constants';
Expand All @@ -30,7 +30,7 @@ import { options as defaultOptions } from './defaults';
export default defineComponent({
components: { LumeChart, LumeBarGroup },
props: {
...withChartProps(),
...withChartProps<BarChartOptions>(),
},
setup(props) {
// State from mixins
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { computed, defineComponent, toRefs } from 'vue';
import LumeChart from '@/components/core/lume-chart';
import LumeBarGroup from '@/components/groups/lume-bar-group';
import { useOptions } from '@/composables/options';
import { BarChartOptions, useOptions } from '@/composables/options';
import { withChartProps } from '@/composables/props';
import { singleDatasetValidator } from '@/utils/helpers';
Expand All @@ -31,7 +31,7 @@ import { options as defaultOptions } from './defaults';
export default defineComponent({
components: { LumeChart, LumeBarGroup },
props: {
...withChartProps(singleDatasetValidator),
...withChartProps<BarChartOptions>(singleDatasetValidator),
},
setup(props) {
// State from mixins
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import LumeChart from '@/components/core/lume-chart';
import LumeBarGroup from '@/components/groups/lume-bar-group';
import { useBase } from '@/composables/base';
import { useOptions } from '@/composables/options';
import { BarChartOptions, useOptions } from '@/composables/options';
import { withChartProps } from '@/composables/props';
import { useBarMixin } from '@/components/groups/lume-bar-group/composables/bar-mixin';
import { useStackedAxes } from '@/components/groups/lume-bar-group/composables/stacked-mixin';
Expand All @@ -35,7 +35,7 @@ import { options as defaultOptions } from './defaults';
export default defineComponent({
components: { LumeChart, LumeBarGroup },
props: {
...withChartProps(),
...withChartProps<BarChartOptions>(),
},
setup(props) {
// State from mixins
Expand Down
1 change: 1 addition & 0 deletions src/components/core/lume-chart/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ No props.
| -------------- | ---------------------------- | ---------------------------------------- |
| `data` | `Data` | The data to plot. |
| `labels` | `Array<string \| number>` | The group of labels to plot the data to. |
| `options` | `Options` | A set of chart options. |
| `orientation` | `'vertical' \| 'horizontal'` | The chart's orientation. |
| `xScale` | `Scale` | The base X scale. |
| `yScale` | `Scale` | The base Y scale. |
Expand Down
1 change: 1 addition & 0 deletions src/components/core/lume-chart/lume-chart.vue
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
name="groups"
:data="internalData"
:labels="computedLabels"
:options="allOptions"
:orientation="orientation"
:x-scale="computedXScale"
:y-scale="computedYScale"
Expand Down
5 changes: 5 additions & 0 deletions src/components/groups/composables/group-props.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { PropType } from 'vue';

import { Options } from '@/composables/options';
import { Scale } from '@/composables/scales';

import { InternalData } from '@/types/dataset';
Expand All @@ -21,4 +22,8 @@ export const withGroupProps = () => ({
type: Number,
default: -1,
},
options: {
type: Object as PropType<Options>,
default: () => ({}),
},
});
10 changes: 8 additions & 2 deletions src/components/groups/lume-bar-group/composables/bar-mixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { getPaddedScale, Scale } from '@/composables/scales';

import { BAR_TYPES, BarType, Orientation, ORIENTATIONS } from '@/constants';
import { DatasetValueObject, InternalData } from '@/types/dataset';
import { BarChartOptions } from '@/composables/options';

function typeValidator(type: string): boolean {
return Object.values(BAR_TYPES).includes(type as BarType) || type == null;
Expand Down Expand Up @@ -68,6 +69,7 @@ export function getBarChartType(data: Ref<InternalData>, type: Ref<string>) {
export function useBarScales(
xScale: Ref<Scale>,
yScale: Ref<Scale>,
options?: Ref<BarChartOptions>,
orientation?: Ref<Orientation>
) {
const isHorizontal = computed(
Expand All @@ -81,24 +83,28 @@ export function useBarScales(
}

const barXScale = computed(() => {
const { padding, paddingInner, paddingOuter } = options.value;
const scale = isHorizontal.value
? (() => {
checkValidDomain(xScale.value as ScaleLinear<number, number>);
return xScale.value;
})()
: getPaddedScale(
xScale.value as ScaleBand<string | number>,
orientation.value
orientation.value,
{ padding, paddingInner, paddingOuter }
);

return scale;
});

const barYScale = computed(() => {
const { padding, paddingInner, paddingOuter } = options.value;
const scale = isHorizontal.value
? getPaddedScale(
yScale.value as ScaleBand<string | number>,
orientation.value
orientation.value,
{ padding, paddingInner, paddingOuter }
)
: (() => {
checkValidDomain(yScale.value as ScaleLinear<number, number>);
Expand Down
8 changes: 7 additions & 1 deletion src/components/groups/lume-bar-group/lume-bar-group.vue
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export default defineComponent({
const {
data,
hoveredIndex,
options,
orientation,
transition,
type,
Expand All @@ -71,7 +72,12 @@ export default defineComponent({
const { groupedData } = useBarMixin(data);
const { barXScale, barYScale } = useBarScales(xScale, yScale, orientation);
const { barXScale, barYScale } = useBarScales(
xScale,
yScale,
options,
orientation
);
const computedClasses = computed(() => {
if (typeof classList.value === 'string') return [classList.value];
Expand Down
6 changes: 6 additions & 0 deletions src/composables/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ export interface ChartOptions extends Options {
noMinSize?: boolean;
}

export interface BarChartOptions extends ChartOptions {
padding?: number;
paddingInner?: number;
paddingOuter?: number;
}

export type Options = Record<string, unknown>;

export const withOptions = <T = Options>() => ({
Expand Down
32 changes: 17 additions & 15 deletions src/composables/props.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { PropType } from 'vue';

import { DataValidator, withBase } from './base';
import { ChartOptions, withOptions } from './options';
import { ChartOptions, Options, withOptions } from './options';
import { withScales } from './scales';

import { Orientation, ORIENTATIONS } from '@/constants';
Expand All @@ -10,17 +10,19 @@ function orientationValidator(orientation: string): boolean {
return Object.values(ORIENTATIONS).includes(orientation as Orientation);
}

export const withChartProps = (dataValidator?: DataValidator) => ({
...withBase(dataValidator),
...withScales(),
...withOptions<ChartOptions>(),
title: {
type: String,
default: null,
},
orientation: {
type: String as PropType<Orientation>,
default: ORIENTATIONS.VERTICAL,
validator: orientationValidator,
},
});
export const withChartProps = <T extends Options = ChartOptions>(
dataValidator?: DataValidator
) => ({
...withBase(dataValidator),
...withScales(),
...withOptions<T>(),
title: {
type: String,
default: null,
},
orientation: {
type: String as PropType<Orientation>,
default: ORIENTATIONS.VERTICAL,
validator: orientationValidator,
},
});
33 changes: 33 additions & 0 deletions src/composables/scales.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,5 +159,38 @@ describe('scales.ts', () => {
expect(paddedScale.paddingInner()).toEqual(PADDING_VERTICAL);
expect(paddedScale.paddingOuter()).toEqual(PADDING_VERTICAL / 2);
});

test('should return scale with custom padding', () => {
const { yScale } = await getMixin(data);

const paddedScale = getPaddedScale(yScale.value, 'horizontal', {
padding: 1,
});

expect(paddedScale.paddingInner()).toEqual(1);
expect(paddedScale.paddingOuter()).toEqual(0.5);
});

test('should return scale with custom paddingInner', () => {
const { yScale } = await getMixin(data);

const paddedScale = getPaddedScale(yScale.value, 'horizontal', {
paddingInner: 1,
});

expect(paddedScale.paddingInner()).toEqual(1);
expect(paddedScale.paddingOuter()).toEqual(PADDING_VERTICAL / 2);
});

test('should return scale with custom paddingOuter', () => {
const { yScale } = await getMixin(data);

const paddedScale = getPaddedScale(yScale.value, 'horizontal', {
paddingOuter: 1,
});

expect(paddedScale.paddingInner()).toEqual(PADDING_VERTICAL);
expect(paddedScale.paddingOuter()).toEqual(1);
});
});
});
19 changes: 13 additions & 6 deletions src/composables/scales.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,14 +146,21 @@ export function getXByIndex(scale: Scale, index: number): number {

export function getPaddedScale(
scale: ScaleBand<string | number>,
orientation?: Orientation
orientation?: Orientation,
{
padding,
paddingInner,
paddingOuter,
}: { padding?: number; paddingInner?: number; paddingOuter?: number } = {}
) {
const padding =
orientation === ORIENTATIONS.HORIZONTAL
const defaultPadding =
padding ??
(orientation === ORIENTATIONS.HORIZONTAL
? PADDING_HORIZONTAL
: PADDING_VERTICAL;
: PADDING_VERTICAL);

return scale
.copy()
.paddingInner(padding)
.paddingOuter(padding / 2);
.paddingInner(paddingInner ?? defaultPadding)
.paddingOuter(paddingOuter ?? defaultPadding / 2);
}

0 comments on commit 693775b

Please sign in to comment.