Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🎨 Code clean-up #139

Merged
merged 18 commits into from
Jan 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion src/components/charts/lume-alluvial-diagram/defaults.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
export const options = {
import { sankeyJustify } from 'd3-sankey';

import { AlluvialDiagramOptions } from '@/composables/options';

export const options: AlluvialDiagramOptions = {
margins: {
top: 0,
right: 0,
Expand All @@ -9,4 +13,10 @@ export const options = {
withTooltip: false,
withHover: false,
withLegend: false,

// Alluvial options
nodePadding: 16,
vivy27 marked this conversation as resolved.
Show resolved Hide resolved
nodeWidth: 16,
nodeAlign: sankeyJustify,
valueFormat: (value: number) => String(value),
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { mount } from '@vue/test-utils';
import { shallowMount } from '@vue/test-utils';

import LumeAlluvialDiagram from './lume-alluvial-diagram.vue';

Expand Down Expand Up @@ -44,13 +44,13 @@ describe('lume-alluvial-diagram.vue', () => {

const wrapper = testSuite.run().wrapper;
const el = wrapper.find('[data-j-alluvial-diagram]');
const props = el.props();

expect(props.data).toBeDefined();
expect(props.color).toBe('skyblue');
expect(props.options).toBeDefined();

expect(el.exists()).toBeTruthy();
expect(el.find('[data-j-alluvial-group]').exists()).toBeTruthy();
expect(
el.find('[data-j-alluvial-group__ghost-path]').exists()
).toBeTruthy();
expect(el.find('[data-j-alluvial-group__path]').exists()).toBeTruthy();
expect(el.find('[data-j-alluvial-group__node-block]').exists()).toBeFalsy();
});

test('mounts component and sets prop values using random data', async () => {
Expand All @@ -59,13 +59,8 @@ describe('lume-alluvial-diagram.vue', () => {

const wrapper = testSuite.run().wrapper;
const el = wrapper.find('[data-j-alluvial-diagram]');

expect(el.exists()).toBeTruthy();
expect(el.find('[data-j-alluvial-group]').exists()).toBeTruthy();
expect(
el.find('[data-j-alluvial-group__ghost-path]').exists()
).toBeTruthy();
expect(el.find('[data-j-alluvial-group__path]').exists()).toBeTruthy();
expect(el.find('[data-j-alluvial-group__node-block]').exists()).toBeFalsy();
});

test('should throw error in case of a dataset with circular links', async () => {
Expand All @@ -84,14 +79,9 @@ describe('lume-alluvial-diagram.vue', () => {
},
];

const data = [
{
...baseData,
values,
},
];
const data = [{ values }];

mount(LumeAlluvialDiagram, {
shallowMount(LumeAlluvialDiagram, {
propsData: {
data,
},
Expand All @@ -110,7 +100,7 @@ describe('lume-alluvial-diagram.vue', () => {
},
];

mount(LumeAlluvialDiagram, {
shallowMount(LumeAlluvialDiagram, {
propsData: {
data,
},
Expand Down Expand Up @@ -149,7 +139,7 @@ describe('lume-alluvial-diagram.vue', () => {
},
];

mount(LumeAlluvialDiagram, {
shallowMount(LumeAlluvialDiagram, {
propsData: {
data,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ export default {
},
args: {
...withSizeArgs(),
options: defaultOptions,
options: Object.fromEntries(
Object.entries(defaultOptions).filter(
([key]) => !key.includes('nodeAlign') && !key.includes('valueFormat')
)
),
title: 'Alluvial diagram',
},
parameters: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,17 @@ import LumeChart from '@/components/core/lume-chart';
import LumeAlluvialGroup from '@/components/groups/lume-alluvial-group';

import { withChartProps } from '@/composables/props';
import { ChartOptions, useOptions } from '@/composables/options';
import { AlluvialDiagramOptions, useOptions } from '@/composables/options';

import { excludeGroups, singleDatasetValidator } from '@/utils/helpers';
import { options as defaultOptions } from './defaults';

const props = defineProps({
...withChartProps(singleDatasetValidator, false, false),
...withChartProps<AlluvialDiagramOptions>(
singleDatasetValidator,
false,
false
),
});

const slots = excludeGroups(useSlots());
Expand All @@ -41,7 +45,7 @@ const { options } = toRefs(props);

const { allOptions } = useOptions(options, defaultOptions);

function getAlluvialDiagramOptions(options: ChartOptions) {
function getAlluvialDiagramOptions(options: AlluvialDiagramOptions) {
return {
...options,
noBaseScales: true, // Alluvial chart never uses base scales
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { toRefs } from 'vue';

import DATASETS from '@/docs/storybook-data/base-data';

import LumeChartLegend from './lume-chart-legend.vue';

import { useBase } from '../../../composables/base';

export default {
title: 'Core/Legend',
component: LumeChartLegend,
Expand All @@ -18,10 +22,12 @@ const Template = ({ argTypes }) => ({
components: { LumeChartLegend },
props: Object.keys(argTypes),
setup(props: InstanceType<typeof LumeChartLegend>['$props']) {
return { props };
const { data, labels } = toRefs(props);
const { internalData } = useBase(data, labels);
return { props, internalData };
},
template: `
<lume-chart-legend v-bind="props" />
<lume-chart-legend v-bind="props" :data="internalData" />
`,
});

Expand Down
7 changes: 4 additions & 3 deletions src/components/core/lume-chart/lume-chart.vue
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@
</template>

<script setup lang="ts">
import { computed, onMounted, ref, toRefs, useSlots } from 'vue';
import { computed, onMounted, PropType, ref, toRefs, useSlots } from 'vue';
import {
Portal as VuePortal,
PortalTarget as VuePortalTarget,
Expand All @@ -208,13 +208,14 @@ import {
} from '@/composables/negative-values';
import { useTooltip, useTooltipAnchors } from '@/composables/tooltip';

import { getEmptyArrayFromData } from '@/utils/helpers';
import { ORIENTATIONS, TOOLTIP_ANCHOR_RADIUS } from '@/utils/constants';
import { getEmptyArrayFromData } from '@/utils/helpers';
import { ChartType } from '@/types/dataset';

const props = defineProps({
...withChartProps(),
chartType: {
type: String,
type: String as PropType<ChartType>,
default: null,
},
});
Expand Down
26 changes: 12 additions & 14 deletions src/components/core/lume-line/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Line

Draws a line between two points based on two scales, two specified values for the value scale and an index for the label scale. It will draw from the index - 1 point to the index point, so be sure to also specify the values as `[values[index - 1], values[index]]`.
Draws a line based on a provided SVG path definition. The component also provides properties to customize the line drawn.

## Usage

Expand All @@ -12,26 +12,24 @@ import { LumeLine } from '@adyen/lume';

### Basic use

To show a point, provide `xScale`, `yScale`, `Γ¬ndex`, `values`, `color`, `dashed` and `transition` properties
To show a line, provide a `pathDefinition` property.

```html
<lume-line
:path-definition="pathDefinition"
:x-scale="xScale"
/>
<lume-line :path-definition="pathDefinition" />
```

## API

### Props

| Name | Type | Default | Description |
| ---------------- | ----------------------------------------------- | -------- | -------------------------------------------------------------------------------------------- |
| `pathDefinition` | `Computed<string>` | Required | A string representing a path that can be fed into the `d` attribute of an SVG `path`element. |
| `xScale` | `ScaleGenerator or ScaleLinear<number, number>` | Required | A d3 scale or a scale generator function to override the default Y scale. |
| `color` | `string` | `'01'` | Indicating what color to use, representing an index to one of the available Lume colors. |
| `width` | `number` | `2` | Indicating the stroke width of the line. |
| `dashed` | `boolean` | `false` | Indicating whether or not this line should be displayed as dashed or solid. |
| `transition` | `boolean` | `true` | Indicating whether or not this line should animate. |
| Name | Type | Default | Description |
| ------------------- | ------------------ | -------- | --------------------------------------------------------------------------------------------------- |
| `pathDefinition` | `Computed<string>` | Required | A string representing a path that can be fed into the `d` attribute of an SVG `path`element. |
| `width` | `number` | `2` | Indicating the stroke width of the line. |
| `color` | `string` | `'01'` | Indicating what color to use, representing an index to one of the available Lume colors. |
| `dashed` | `boolean` | `false` | Indicating whether or not this line should be displayed as dashed or solid. |
| `transition` | `boolean` | `true` | Indicating whether or not this line should animate. |
| `animationDelay` | `number` | `0` | A value in seconds for the transition delay. Useful when animating a line composed of many `path`s. |
| `animationDuration` | `number` | `0.2` | A value in seconds for the transition duration. |

NOTE: A composable `useLineValues` exists to convert indices and values along with their scales to path definitions. For an example of how to use this, see `LumeLineGroup`.
52 changes: 52 additions & 0 deletions src/components/core/lume-line/lume-line.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { computed } from 'vue';

import { Colors } from '@/constants';

import LumeLine from './lume-line.vue';

export default {
title: 'Core/Line',
component: LumeLine,
argTypes: {
width: { control: 'number' },
color: {
control: 'select',
options: Object.keys(Colors),
description: 'Line color.',
},
x1: { control: { type: 'number', step: 10 } },
x2: { control: { type: 'number', step: 10 } },
y1: { control: { type: 'number', step: 10 } },
y2: { control: { type: 'number', step: 10 } },
animationDelay: { control: { type: 'number', step: 0.1 } },
animationDuration: { control: 'number' },
},
args: {
width: 2,
color: 'Royalblue',
x1: 50,
x2: 250,
y1: 50,
y2: 250,
},
};

const Template = ({ argTypes }) => ({
components: { LumeLine },
props: Object.keys(argTypes),
setup(props) {
const computedColor = computed(() => Colors[props.color]);
const pathDefinition = computed(
() => `M${props.x1},${props.y1} L${props.x2},${props.y2}`
);

return { props, computedColor, pathDefinition };
},
template: `
<svg width="300" height="300">
<lume-line v-bind="props" :color="computedColor" :path-definition="pathDefinition" />
</svg>
`,
});

export const Basic = Template.bind({});
45 changes: 14 additions & 31 deletions src/components/core/lume-line/lume-line.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,65 +18,48 @@
</template>

<script lang="ts">
const LUME_TRANSITION_TIME_FULL = 1; // 1s
const DEFAULT_LINE_WIDTH = 2; // 2px
</script>

<script setup lang="ts">
import { computed, onMounted, PropType, ref } from 'vue';

import { Scale } from '@/composables/scales';
import { onMounted, ref } from 'vue';

import { Colors } from '@/utils/constants';

import { getDomainLength } from '@/utils/helpers';

import { svgCheck } from '@/utils/svg-check';

const props = defineProps({
defineProps({
pathDefinition: {
type: String,
required: true,
},
color: {
type: String,
default: Colors.Skyblue,
},
index: {
type: Number,
required: true,
},
width: {
type: Number,
default: DEFAULT_LINE_WIDTH,
},
color: {
type: String,
default: Colors.Skyblue,
},
dashed: {
type: Boolean,
default: false,
},
xScale: {
type: Function as PropType<Scale>,
required: true,
},
transition: {
type: Boolean,
default: true,
},
animationDelay: {
type: Number,
default: 0,
},
animationDuration: {
type: Number,
default: 0.2,
},
});

const root = ref<SVGPathElement>(null);

const animationDuration = computed(
() => LUME_TRANSITION_TIME_FULL / (getDomainLength(props.xScale) - 1) // Subtracting the first line (read below)
);

const animationDelay = computed(() => {
// 0 index is the first line point (which isn't really a line), so it shouldn't have delay
// 1 index is the actual first line drawn, so it also shouldn't have delay
if (props.index < 2) return 0;
return props.transition && (props.index - 1) * animationDuration.value;
});

onMounted(() => svgCheck(root.value));
</script>

Expand Down
Loading