Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 3 additions & 15 deletions packages/x-charts/src/ChartsRadialGrid/ChartsRadialGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { GridRoot } from './styledComponents';
import { ChartsRotationGrid } from './ChartsRotationGrid';
import { ChartsRadiusGrid } from './ChartsRadiusGrid';
import { useRotationAxes, useRadiusAxes } from '../hooks/useAxis';
import { EPSILON } from '../utils/epsilon';

const useUtilityClasses = ({ classes }: ChartsRadialGridProps) => {
const slots = {
Expand Down Expand Up @@ -67,20 +66,8 @@ function ChartsRadialGrid(inProps: ChartsRadialGridProps) {
const outerRadius = radiusAxisConfig?.scale.range()[1] ?? 0;

const startAngle = rotationAxisConfig?.scale.range()[0] ?? 0;
let endAngle = rotationAxisConfig?.scale.range()[1] ?? 0;

if (rotationAxisConfig.scaleType === 'point') {
// The rotation gap we add between the first and last point.
const dataRotationGap = (2 * Math.PI) / rotationAxisConfig.data!.length;

// The missing angle between the last and first point.
const angleGap = 2 * Math.PI - Math.abs(endAngle - startAngle);
if (Math.abs(angleGap - dataRotationGap) < EPSILON) {
// If they are close enough we close the circle.
// Otherwise it means user deliberately modified the angles and so keep it as it is.
endAngle = startAngle + 2 * Math.PI;
}
}
const endAngle = rotationAxisConfig?.scale.range()[1] ?? 0;
const isFullCircle = rotationAxisConfig?.isFullCircle ?? false;

return (
<GridRoot {...other} className={clsx(classes.root, className)}>
Expand All @@ -98,6 +85,7 @@ function ChartsRadialGrid(inProps: ChartsRadialGridProps) {
axis={radiusAxisConfig}
startAngle={startAngle}
endAngle={endAngle}
isFullCircle={isFullCircle}
classes={classes}
/>
)}
Expand Down
6 changes: 2 additions & 4 deletions packages/x-charts/src/ChartsRadialGrid/ChartsRadiusGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ import {
type UseChartPolarAxisSignature,
} from '../internals/plugins/featurePlugins/useChartPolarAxis';
import { type PolarAxisDefaultized } from '../models/axis';
import { EPSILON } from '../utils/epsilon';

interface ChartsRadiusGridProps {
axis: PolarAxisDefaultized<any, any, any>;
startAngle: number;
endAngle: number;
isFullCircle: boolean;
classes: Partial<ChartsRadialGridClasses>;
}

Expand All @@ -22,7 +22,7 @@ interface ChartsRadiusGridProps {
*/
export function ChartsRadiusGrid(props: ChartsRadiusGridProps) {
const { store } = useChartsContext<[UseChartPolarAxisSignature]>();
const { axis, startAngle, endAngle, classes } = props;
const { axis, startAngle, endAngle, isFullCircle, classes } = props;
const { cx, cy } = store.use(selectorChartPolarCenter);

const { scale, tickNumber, tickInterval, tickSpacing } = axis;
Expand All @@ -35,8 +35,6 @@ export function ChartsRadiusGrid(props: ChartsRadiusGridProps) {
direction: 'radius',
});

const isFullCircle = Math.abs(endAngle - startAngle) >= 2 * Math.PI - EPSILON;

if (isFullCircle) {
return (
<React.Fragment>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { type AxisConfig, type ScaleName } from '../../../../models';
import type { ContinuousScaleName, AxisConfig, ScaleName } from '../../../../models';
import {
type ChartsAxisProps,
isBandScaleConfig,
isPointScaleConfig,
isContinuousScaleConfig,
type ChartsRotationAxisProps,
type ChartsRadiusAxisProps,
type PolarAxisDefaultized,
type AxisId,
type PolarAxisConfig,
isContinuousScaleConfig,
type ComputedAxis,
} from '../../../../models/axis';
import {
type ChartSeriesType,
Expand All @@ -26,6 +27,7 @@ import { deg2rad } from '../../../angleConversion';
import { getAxisTriggerTooltip } from './getAxisTriggerTooltip';
import { scaleBand, scalePoint } from '../../../scales';
import { type ComputedAxisConfig } from '../useChartCartesianAxis';
import { EPSILON } from '../../../../utils/epsilon';

export type DefaultizedAxisConfig<
AxisProps extends ChartsRotationAxisProps | ChartsRadiusAxisProps,
Expand All @@ -40,30 +42,28 @@ function getRange(
drawingArea: ChartDrawingArea,
axisDirection: 'rotation' | 'radius',
axis: PolarAxisConfig<ScaleName, any>,
) {
): { range: number[]; isFullCircle: boolean } {
if (axisDirection === 'rotation') {
if (axis.scaleType === 'point') {
const angles = [
deg2rad((axis as RotationConfig).startAngle, 0),
deg2rad((axis as RotationConfig).endAngle, 2 * Math.PI),
];
const diff = angles[1] - angles[0];
if (diff > Math.PI * 2 - 0.1) {
// If we cover a full circle, we remove a slice to avoid having data point at the same place.
angles[1] -= diff / axis.data!.length;
}
return angles;
}
return [
const angles = [
deg2rad((axis as RotationConfig).startAngle, 0),
deg2rad((axis as RotationConfig).endAngle, 2 * Math.PI),
];
const diff = angles[1] - angles[0];
const isFullCircle = diff >= Math.PI * 2 - EPSILON;
if (axis.scaleType === 'point' && isFullCircle) {
// For point scale, remove a slice to avoid overlapping first and last points.
angles[1] -= diff / axis.data!.length;
}
return { range: angles, isFullCircle };
}
const availableRadius = Math.min(drawingArea.height, drawingArea.width) / 2;
return [
(axis as RadiusConfig).minRadius ?? 0,
(axis as RadiusConfig).maxRadius ?? availableRadius,
];
return {
range: [
(axis as RadiusConfig).minRadius ?? 0,
(axis as RadiusConfig).maxRadius ?? availableRadius,
],
isFullCircle: false,
};
}

const DEFAULT_CATEGORY_GAP_RATIO = 0.2;
Expand Down Expand Up @@ -116,10 +116,10 @@ export function computeAxisValue<SeriesType extends ChartSeriesType>({
allAxis[0].id,
);

const completeAxis: DefaultizedAxisConfig<ChartsAxisProps> = {};
const completeAxis: ComputedAxisConfig<ChartsAxisProps> = {};
allAxis.forEach((eachAxis, axisIndex) => {
const axis = eachAxis as Readonly<AxisConfig<ScaleName, any, Readonly<ChartsAxisProps>>>;
const range = getRange(drawingArea, axisDirection, axis);
const { range, isFullCircle } = getRange(drawingArea, axisDirection, axis);

const [minData, maxData] = getAxisExtremum(
axis,
Expand Down Expand Up @@ -153,7 +153,8 @@ export function computeAxisValue<SeriesType extends ChartSeriesType>({
(axis.colorMap.type === 'ordinal'
? getOrdinalColorScale({ values: axis.data, ...axis.colorMap })
: getColorScale(axis.colorMap)),
};
isFullCircle,
} as ComputedAxis<'band', any, ChartsAxisProps>;

if (isDateData(axis.data)) {
const dateFormatter = createDateFormatter(axis.data, range, axis.tickNumber);
Expand All @@ -173,7 +174,8 @@ export function computeAxisValue<SeriesType extends ChartSeriesType>({
(axis.colorMap.type === 'ordinal'
? getOrdinalColorScale({ values: axis.data, ...axis.colorMap })
: getColorScale(axis.colorMap)),
};
isFullCircle,
} as ComputedAxis<'point', any, ChartsAxisProps>;

if (isDateData(axis.data)) {
const dateFormatter = createDateFormatter(axis.data, range, axis.tickNumber);
Expand Down Expand Up @@ -223,7 +225,7 @@ export function computeAxisValue<SeriesType extends ChartSeriesType>({
scale: finalScale.domain(domain) as any,
tickNumber,
colorScale: axis.colorMap && getColorScale(axis.colorMap),
};
} as ComputedAxis<ContinuousScaleName, any, ChartsAxisProps>;
});
return {
axis: completeAxis,
Expand Down
2 changes: 2 additions & 0 deletions packages/x-charts/src/models/axis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,8 @@ export type ComputedAxis<
* Indicate if the axis should be consider by a tooltip with `trigger='axis'`.
*/
triggerTooltip?: boolean;
/** @ignore - internal. True when a rotation axis covers a full circle. */
isFullCircle?: boolean;
} & (AxisProps extends ChartsXAxisProps
? AxisSideConfig<AxisProps> & { height: number }
: AxisProps extends ChartsYAxisProps
Expand Down
Loading