Skip to content

Commit

Permalink
fix: resolve init animation with responsive (#600)
Browse files Browse the repository at this point in the history
* fix: resolve init animation with responsive

* fix: modify using offsetSize

* refactor: remove animation duration

* refactor: apply PR feedbacks

* refactor: change responsive animation duration

* test: resolve boxSeriesData types
  • Loading branch information
jungeun-cho authored Feb 25, 2021
1 parent fafb67e commit a25e85b
Show file tree
Hide file tree
Showing 29 changed files with 380 additions and 226 deletions.
10 changes: 8 additions & 2 deletions apps/chart/src/charts/barChart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,13 @@ import * as labelBrush from '@src/brushes/label';
import * as dataLabelBrush from '@src/brushes/dataLabel';
import * as exportMenuBrush from '@src/brushes/exportMenu';

import { BoxSeriesDataType, BarChartOptions, BoxSeriesInput, BoxSeriesData } from '@t/options';
import {
BoxSeriesDataType,
BarChartOptions,
BoxSeriesInput,
BoxSeriesData,
BoxSeriesType,
} from '@t/options';

export interface BarChartProps {
el: HTMLElement;
Expand Down Expand Up @@ -119,7 +125,7 @@ export default class BarChart extends Chart<BarChartOptions> {
el,
options,
series: {
bar: data.series,
bar: data.series as BoxSeriesType<BoxSeriesDataType>[],
},
categories: data.categories,
modules: [stackSeriesData, dataRange, scale, axes, plot],
Expand Down
15 changes: 5 additions & 10 deletions apps/chart/src/charts/chart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,11 +235,7 @@ export default abstract class Chart<T extends Options> {
this.draw();
}

private debounceResizeEvent = debounce((containerWidth: number, containerHeight: number) => {
this.resizeChartSize(containerWidth, containerHeight);
}, 100);

private debounceWindowResizeEvent = debounce(() => {
private debounceResizeEvent = debounce(() => {
const { offsetWidth, offsetHeight } = this.containerEl;
this.resizeChartSize(offsetWidth, offsetHeight);
}, 100);
Expand All @@ -257,12 +253,11 @@ export default abstract class Chart<T extends Options> {
const isResizeObserverAPIExist = typeof ResizeObserver === 'undefined';

if (isResizeObserverAPIExist) {
window.addEventListener('resize', this.debounceWindowResizeEvent);
window.addEventListener('resize', this.debounceResizeEvent);
} else {
this.resizeObserver = new ResizeObserver((entries) => {
entries.forEach((entry) => {
const { width, height } = entry.contentRect;
this.debounceResizeEvent(width, height);
entries.forEach(() => {
this.debounceResizeEvent();
});
});
this.resizeObserver.observe(this.containerEl);
Expand All @@ -275,7 +270,7 @@ export default abstract class Chart<T extends Options> {
this.resizeObserver.disconnect();
this.resizeObserver = null;
} else {
window.removeEventListener('resize', this.debounceWindowResizeEvent);
window.removeEventListener('resize', this.debounceResizeEvent);
}
}

Expand Down
10 changes: 8 additions & 2 deletions apps/chart/src/charts/columnChart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,13 @@ import * as labelBrush from '@src/brushes/label';
import * as exportMenuBrush from '@src/brushes/exportMenu';
import * as dataLabelBrush from '@src/brushes/dataLabel';

import { ColumnChartOptions, BoxSeriesData, BoxSeriesDataType, BoxSeriesInput } from '@t/options';
import {
ColumnChartOptions,
BoxSeriesData,
BoxSeriesDataType,
BoxSeriesInput,
BoxSeriesType,
} from '@t/options';

export interface ColumnChartProps {
el: HTMLElement;
Expand Down Expand Up @@ -119,7 +125,7 @@ export default class ColumnChart extends Chart<ColumnChartOptions> {
el,
options,
series: {
column: data.series,
column: data.series as BoxSeriesType<BoxSeriesDataType>[],
},
categories: data.categories,
modules: [stackSeriesData, dataRange, scale, axes, plot],
Expand Down
26 changes: 14 additions & 12 deletions apps/chart/src/component/boxSeries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export function isLeftBottomSide(seriesIndex: number) {
return !!(seriesIndex % 2);
}

function calculateBarLength(value: BoxSeriesDataType, min: number, max: number) {
function calculateBarLength(value: Exclude<BoxSeriesDataType, null>, min: number, max: number) {
if (isRangeValue(value)) {
let [start, end] = value;

Expand Down Expand Up @@ -540,23 +540,25 @@ export default class BoxSeries extends Component {

seriesData.forEach(({ data, name, color }) => {
data.forEach((value, dataIndex) => {
const barLength = this.makeBarLength(value, renderOptions);

if (isNumber(barLength)) {
tooltipData.push({
label: name,
color,
value: this.getTooltipValue(value),
category: categories.length ? categories[dataIndex] : '',
});
if (!isNull(value)) {
const barLength = this.makeBarLength(value, renderOptions);

if (isNumber(barLength)) {
tooltipData.push({
label: name,
color,
value: this.getTooltipValue(value),
category: categories.length ? categories[dataIndex] : '',
});
}
}
});
});

return tooltipData;
}

private getTooltipValue(value: BoxSeriesDataType): string | number {
private getTooltipValue(value: Exclude<BoxSeriesDataType, null>): string | number {
return isRangeValue(value) ? `${value[0]} ~ ${value[1]}` : value;
}

Expand Down Expand Up @@ -628,7 +630,7 @@ export default class BoxSeries extends Component {

getStartPosition(
barLength: number,
value: BoxSeriesDataType,
value: Exclude<BoxSeriesDataType, null>,
renderOptions: RenderOptions,
isLBSideWithDiverging: boolean
): number {
Expand Down
5 changes: 1 addition & 4 deletions apps/chart/src/store/layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,10 +320,7 @@ function getPlotRect(xAxis: Rect, yAxis: Rect, size: OptionalSize) {
return {
x: xAxis.x,
y: yAxis.y,
...getValidRectSize(size, Math.max(xAxis.width, 1), Math.max(yAxis.height, 1)),
// @TODO: Math.max(xAxis.width, 1), Math.max(yAxis.height, 1) 리팩토링 필요
// 차트 사이즈를 지정하지 않는 상태에서 plot의 너비와 높이가 잘못 계산되고,
// scale의 stepSize에 영향을 줌. xAxis.width, yAxis.height 값을 보정하도록 해야함.
...getValidRectSize(size, xAxis.width, yAxis.height),
};
}

Expand Down
8 changes: 5 additions & 3 deletions apps/chart/src/store/scale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ type ScaleOptions = {
verticalAxis?: ScaleOption;
};

const MIN_OFFSET_SIZE = 1;

function getLabelScaleData(
state: ChartState<Options>,
labelAxisOnYAxis: boolean,
Expand All @@ -39,7 +41,7 @@ function getLabelScaleData(
const dateTypeLabel = isExist(options.xAxis?.date);
const labelOptions = {
dataRange: dataRange[labelAxisName],
offsetSize: layout.plot[labelSizeKey],
offsetSize: Math.max(layout.plot[labelSizeKey], MIN_OFFSET_SIZE),
scaleOption: scaleOptions[labelAxisName],
rawCategoriesSize: rawCategories.length,
};
Expand Down Expand Up @@ -77,15 +79,15 @@ function getValueScaleData(
} else if (isCoordinateTypeChart) {
const valueOptions = {
dataRange: dataRange[valueAxisName],
offsetSize: layout.plot[valueSizeKey],
offsetSize: Math.max(layout.plot[valueSizeKey], MIN_OFFSET_SIZE),
scaleOption: scaleOptions[valueAxisName],
};

result = calculateCoordinateScale(valueOptions);
} else {
result = calculateCoordinateScale({
dataRange: dataRange[valueAxisName],
offsetSize: layout.plot[valueSizeKey],
offsetSize: Math.max(layout.plot[valueSizeKey], MIN_OFFSET_SIZE),
scaleOption: scaleOptions[valueAxisName],
});
}
Expand Down
15 changes: 9 additions & 6 deletions apps/chart/stories/area.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from './data';
import { withKnobs, boolean, radios } from '@storybook/addon-knobs';
import '@src/css/chart.css';
import { createResponsiveChart } from './util';

export default {
title: 'chart|Area',
Expand All @@ -34,8 +35,8 @@ function createChart(data: AreaSeriesData, customOptions: AreaChartOptions = {})
const el = document.createElement('div');
const options = deepMergedCopy(defaultOptions, customOptions);

el.style.width = options.chart?.width === 'auto' ? '90vw' : `${options.chart?.width}px`;
el.style.height = options.chart?.height === 'auto' ? '90vh' : `${options.chart?.height}px`;
el.style.width = `${options.chart?.width}px`;
el.style.height = `${options.chart?.height}px`;

const chart = new AreaChart({ el, data, options });

Expand Down Expand Up @@ -297,14 +298,16 @@ export const secondaryYAxis = () => {
};

export const responsive = () => {
const { el } = createChart(avgTemperatureData, {
chart: { title: 'Average Temperature', width: 'auto', height: 'auto' },
return createResponsiveChart<AreaSeriesData, AreaChartOptions>(AreaChart, avgTemperatureData, {
chart: {
title: 'Average Temperature',
width: 'auto',
height: 'auto',
},
responsive: {
animation: { duration: 300 },
},
});

return el;
};

export const theme = () => {
Expand Down
18 changes: 16 additions & 2 deletions apps/chart/stories/bar.groupstack.stories.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import BarChart from '@src/charts/barChart';
import { lossDataForGroupStack, genderAgeGroupData } from './data';
import { BarChartOptions } from '@t/options';
import { BarChartOptions, BoxSeriesData } from '@t/options';
import { deepMergedCopy } from '@src/helpers/utils';
import { withKnobs, radios } from '@storybook/addon-knobs';

import '@src/css/chart.css';
import { createResponsiveChart } from './util';

export default {
title: 'chart.Bar.Group Stack',
Expand All @@ -21,7 +22,7 @@ const defaultOptions: BarChartOptions = {
},
};

function createChart(data, customOptions?: BarChartOptions) {
function createChart(data: BoxSeriesData, customOptions?: BarChartOptions) {
const el = document.createElement('div');
const options = deepMergedCopy(defaultOptions, customOptions || {});

Expand Down Expand Up @@ -171,3 +172,16 @@ export const theme = () => {

return el;
};

export const responsive = () => {
return createResponsiveChart<BoxSeriesData, BarChartOptions>(BarChart, genderAgeGroupData, {
chart: {
title: 'Population Distribution',
width: 'auto',
height: 'auto',
},
series: {
stack: true,
},
});
};
18 changes: 16 additions & 2 deletions apps/chart/stories/bar.stack.stories.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import BarChart from '@src/charts/barChart';
import { budgetDataForStack, negativeBudgetData, budgetData, lossData } from './data';
import { BarChartOptions } from '@t/options';
import { BarChartOptions, BoxSeriesData } from '@t/options';
import { deepMergedCopy } from '@src/helpers/utils';
import { withKnobs, radios } from '@storybook/addon-knobs';
import '@src/css/chart.css';
import { createResponsiveChart } from './util';

export default {
title: 'chart.Bar.Stack',
Expand All @@ -20,7 +21,7 @@ const defaultOptions: BarChartOptions = {
},
};

function createChart(data, customOptions?: BarChartOptions) {
function createChart(data: BoxSeriesData, customOptions?: BarChartOptions) {
const el = document.createElement('div');
const options = deepMergedCopy(defaultOptions, customOptions || {});

Expand Down Expand Up @@ -315,3 +316,16 @@ export const dataLabelsWithTheme = () => {

return el;
};

export const responsive = () => {
return createResponsiveChart<BoxSeriesData, BarChartOptions>(BarChart, budgetData, {
chart: {
title: 'Monthly Revenue',
width: 'auto',
height: 'auto',
},
series: {
stack: true,
},
});
};
25 changes: 14 additions & 11 deletions apps/chart/stories/bar.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import {
genderAgeData,
simpleBudgetData,
} from './data';
import { BarChartOptions } from '@t/options';
import { BarChartOptions, BoxSeriesData } from '@t/options';
import { deepMergedCopy } from '@src/helpers/utils';
import { withKnobs, radios } from '@storybook/addon-knobs';
import '@src/css/chart.css';
import { createResponsiveChart } from './util';

export default {
title: 'chart.Bar.General',
Expand All @@ -27,12 +28,12 @@ const defaultOptions: BarChartOptions = {
},
};

function createChart(data, customOptions: Record<string, any> = {}) {
function createChart(data: BoxSeriesData, customOptions: BarChartOptions = {}) {
const el = document.createElement('div');
const options = deepMergedCopy(defaultOptions, customOptions);

el.style.width = options.chart?.width === 'auto' ? '90vw' : `${options.chart?.width}px`;
el.style.height = options.chart?.height === 'auto' ? '90vh' : `${options.chart?.height}px`;
el.style.width = `${options.chart?.width}px`;
el.style.height = `${options.chart?.height}px`;

const chart = new BarChart({
el,
Expand Down Expand Up @@ -109,13 +110,13 @@ export const positiveAndNegativeWithMinMax = () => {
};

export const range = () => {
const { el } = createChart(temperatureRangeData);
const { el } = createChart(temperatureRangeData as BoxSeriesData);

return el;
};

export const rangeWithMinMax = () => {
const { el } = createChart(temperatureRangeData, {
const { el } = createChart(temperatureRangeData as BoxSeriesData, {
xAxis: {
scale: {
min: -4,
Expand All @@ -128,7 +129,7 @@ export const rangeWithMinMax = () => {
};

export const rangeWithDataLabels = () => {
const { el } = createChart(temperatureRangeData, {
const { el } = createChart(temperatureRangeData as BoxSeriesData, {
chart: { height: 800 },
series: { dataLabels: { visible: true } },
});
Expand Down Expand Up @@ -213,8 +214,12 @@ export const secondaryYAxis = () => {
};

export const responsive = () => {
const { el } = createChart(budgetData, {
chart: { title: 'Monthly Revenue', width: 700, height: 'auto' },
return createResponsiveChart<BoxSeriesData, BarChartOptions>(BarChart, budgetData, {
chart: {
title: 'Monthly Revenue',
width: 'auto',
height: 'auto',
},
responsive: {
animation: { duration: 300 },
rules: [
Expand Down Expand Up @@ -244,8 +249,6 @@ export const responsive = () => {
],
},
});

return el;
};

export const theme = () => {
Expand Down
Loading

0 comments on commit a25e85b

Please sign in to comment.