diff --git a/src/plugins/d3/__stories__/line/Line.stories.tsx b/src/plugins/d3/__stories__/line/Line.stories.tsx
new file mode 100644
index 00000000..12ddf2ee
--- /dev/null
+++ b/src/plugins/d3/__stories__/line/Line.stories.tsx
@@ -0,0 +1,44 @@
+import React from 'react';
+
+import {StoryObj} from '@storybook/react';
+
+import {D3Plugin} from '../..';
+import {Loader} from '../../../../components/Loader/Loader';
+import {settings} from '../../../../libs';
+import {LineWithLogarithmicAxis} from '../../examples/line/LogarithmicAxis';
+
+const ChartStory = ({Chart}: {Chart: React.FC}) => {
+ const [loading, setLoading] = React.useState(true);
+
+ React.useEffect(() => {
+ settings.set({plugins: [D3Plugin]});
+ setLoading(false);
+ }, []);
+
+ if (loading) {
+ return ;
+ }
+
+ return (
+
+
+
+ );
+};
+
+export const LogarithmicAxis: StoryObj = {
+ name: 'Logarithmic axis',
+ args: {
+ Chart: LineWithLogarithmicAxis,
+ },
+};
+
+export default {
+ title: 'Plugins/D3/Line',
+ component: ChartStory,
+};
diff --git a/src/plugins/d3/examples/line/LogarithmicAxis.tsx b/src/plugins/d3/examples/line/LogarithmicAxis.tsx
new file mode 100644
index 00000000..93e3303b
--- /dev/null
+++ b/src/plugins/d3/examples/line/LogarithmicAxis.tsx
@@ -0,0 +1,56 @@
+import React from 'react';
+
+import {Col, Container, Row, Text} from '@gravity-ui/uikit';
+import {randomNormal} from 'd3';
+
+import {ChartKit} from '../../../../components/ChartKit';
+import {ChartKitWidgetData} from '../../../../types';
+import {ExampleWrapper} from '../ExampleWrapper';
+
+export const LineWithLogarithmicAxis = () => {
+ const randomY = randomNormal(0, 100);
+ const widgetData: ChartKitWidgetData = {
+ series: {
+ data: [
+ {
+ type: 'line',
+ name: 'Line series',
+ data: new Array(25).fill(null).map((_, index) => ({
+ x: index,
+ y: Math.abs(randomY()),
+ })),
+ },
+ ],
+ },
+ };
+ const lineWidgetData: ChartKitWidgetData = {...widgetData, title: {text: 'line'}};
+ const logarithmicWidgetData: ChartKitWidgetData = {
+ ...widgetData,
+ title: {text: 'logarithmic'},
+ yAxis: [
+ {
+ type: 'logarithmic',
+ },
+ ],
+ };
+
+ return (
+
+
+ logarithmic VS line
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/src/plugins/d3/renderer/hooks/useAxisScales/index.ts b/src/plugins/d3/renderer/hooks/useAxisScales/index.ts
index c55822ea..2fcab444 100644
--- a/src/plugins/d3/renderer/hooks/useAxisScales/index.ts
+++ b/src/plugins/d3/renderer/hooks/useAxisScales/index.ts
@@ -1,10 +1,14 @@
import React from 'react';
-import {extent, scaleBand, scaleLinear, scaleUtc} from 'd3';
+import {extent, scaleBand, scaleLinear, scaleLog, scaleUtc} from 'd3';
import type {ScaleBand, ScaleLinear, ScaleTime} from 'd3';
import get from 'lodash/get';
-import {ChartKitWidgetAxis, ChartKitWidgetSeries} from '../../../../../types';
+import {
+ ChartKitWidgetAxis,
+ ChartKitWidgetAxisType,
+ ChartKitWidgetSeries,
+} from '../../../../../types';
import {DEFAULT_AXIS_TYPE} from '../../constants';
import {
CHART_SERIES_WITH_VOLUME_ON_Y_AXIS,
@@ -65,13 +69,14 @@ const filterCategoriesByVisibleSeries = (args: {
};
export function createYScale(axis: PreparedAxis, series: PreparedSeries[], boundsHeight: number) {
- const yType = get(axis, 'type', DEFAULT_AXIS_TYPE);
+ const yType: ChartKitWidgetAxisType = get(axis, 'type', DEFAULT_AXIS_TYPE);
const yMin = get(axis, 'min');
const yCategories = get(axis, 'categories');
const yTimestamps = get(axis, 'timestamps');
switch (yType) {
- case 'linear': {
+ case 'linear':
+ case 'logarithmic': {
const domain = getDomainDataYBySeries(series);
const range = [boundsHeight, boundsHeight * axis.maxPadding];
@@ -83,7 +88,8 @@ export function createYScale(axis: PreparedAxis, series: PreparedSeries[], bound
yMaxValue = Math.max(yMaxValue, 0);
}
- return scaleLinear().domain([yMinValue, yMaxValue]).range(range).nice();
+ const scaleFn = yType === 'logarithmic' ? scaleLog : scaleLinear;
+ return scaleFn().domain([yMinValue, yMaxValue]).range(range).nice();
}
break;
@@ -150,7 +156,7 @@ export function createXScale(
) {
const xMin = get(axis, 'min');
const xMax = getDefaultMaxXAxisValue(series);
- const xType = get(axis, 'type', DEFAULT_AXIS_TYPE);
+ const xType: ChartKitWidgetAxisType = get(axis, 'type', DEFAULT_AXIS_TYPE);
const xCategories = get(axis, 'categories');
const xTimestamps = get(axis, 'timestamps');
const maxPadding = get(axis, 'maxPadding', 0);
@@ -159,7 +165,8 @@ export function createXScale(
const xRange = [0, boundsWidth - xAxisMinPadding];
switch (xType) {
- case 'linear': {
+ case 'linear':
+ case 'logarithmic': {
const domain = getDomainDataXBySeries(series);
if (isNumericalArrayData(domain)) {
@@ -167,7 +174,9 @@ export function createXScale(
const xMinValue = typeof xMin === 'number' ? xMin : domainXMin;
const xMaxValue =
typeof xMax === 'number' ? Math.max(xMax, domainXMax) : domainXMax;
- return scaleLinear().domain([xMinValue, xMaxValue]).range(xRange).nice();
+
+ const scaleFn = xType === 'logarithmic' ? scaleLog : scaleLinear;
+ return scaleFn().domain([xMinValue, xMaxValue]).range(xRange).nice();
}
break;
diff --git a/src/plugins/d3/renderer/hooks/useChartOptions/y-axis.ts b/src/plugins/d3/renderer/hooks/useChartOptions/y-axis.ts
index bdbcbe47..fb08c685 100644
--- a/src/plugins/d3/renderer/hooks/useChartOptions/y-axis.ts
+++ b/src/plugins/d3/renderer/hooks/useChartOptions/y-axis.ts
@@ -4,6 +4,7 @@ import get from 'lodash/get';
import type {BaseTextStyle, ChartKitWidgetSeries, ChartKitWidgetYAxis} from '../../../../../types';
import {
DEFAULT_AXIS_LABEL_FONT_SIZE,
+ DEFAULT_AXIS_TYPE,
axisLabelsDefaults,
yAxisTitleDefaults,
} from '../../constants';
@@ -107,7 +108,7 @@ export const getPreparedYAxis = ({
const titleStyle: BaseTextStyle = {
fontSize: get(axisItem, 'title.style.fontSize', yAxisTitleDefaults.fontSize),
};
- const axisType = get(axisItem, 'type', 'linear');
+ const axisType = get(axisItem, 'type', DEFAULT_AXIS_TYPE);
const preparedAxis: PreparedAxis = {
type: axisType,
labels: {
diff --git a/src/types/widget-data/axis.ts b/src/types/widget-data/axis.ts
index 78317dc5..32ca24e0 100644
--- a/src/types/widget-data/axis.ts
+++ b/src/types/widget-data/axis.ts
@@ -2,7 +2,7 @@ import type {FormatNumberOptions} from '../../plugins/shared';
import type {BaseTextStyle} from './base';
-export type ChartKitWidgetAxisType = 'category' | 'datetime' | 'linear';
+export type ChartKitWidgetAxisType = 'category' | 'datetime' | 'linear' | 'logarithmic';
export type ChartKitWidgetAxisLabels = {
/** Enable or disable the axis labels. */