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

feat(declarative-chart): Create Scatter plot #33843

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Prev Previous commit
Next Next commit
move markers logic in linechart.base file
  • Loading branch information
Anush2303 committed Feb 24, 2025
commit b605636a450ccf16357fa437eda2d0c751ba6a21
2 changes: 1 addition & 1 deletion packages/charts/react-charting/etc/react-charting.api.md
Original file line number Diff line number Diff line change
@@ -1096,7 +1096,7 @@ export interface IModifiedCartesianChartProps extends ICartesianChartProps {
getDomainNRangeValues: (points: ILineChartPoints[] | IVerticalBarChartDataPoint[] | IVerticalStackedBarDataPoint[] | IHorizontalBarChartWithAxisDataPoint[] | IGroupedVerticalBarChartData[] | IHeatMapChartDataPoint[], margins: IMargins, width: number, chartType: ChartTypes, isRTL: boolean, xAxisType: XAxisTypes, barWidth: number, tickValues: Date[] | number[] | undefined, shiftX: number) => IDomainNRange;
getGraphData?: any;
getmargins?: (margins: IMargins) => void;
getMinMaxOfYAxis: (points: ILineChartPoints[] | IHorizontalBarChartWithAxisDataPoint[] | IVerticalBarChartDataPoint[] | IDataPoint[], yAxisType: YAxisType | undefined) => {
getMinMaxOfYAxis: (points: ILineChartPoints[] | IHorizontalBarChartWithAxisDataPoint[] | IVerticalBarChartDataPoint[] | IDataPoint[], yAxisType: YAxisType | undefined, containerHeight?: number, margins?: IMargins) => {
startValue: number;
endValue: number;
};
Original file line number Diff line number Diff line change
@@ -307,7 +307,12 @@ export class CartesianChartBase
yMaxValue: this.props.yMaxValue || 0,
tickPadding: 10,
maxOfYVal: this.props.maxOfYVal,
yMinMaxValues: this.props.getMinMaxOfYAxis(points, this.props.yAxisType),
yMinMaxValues: this.props.getMinMaxOfYAxis(
points,
this.props.yAxisType,
this.state.containerHeight - this.state._removalValueForTextTuncate!,
this.margins,
),
// please note these padding default values must be consistent in here
// and the parent chart(HBWA/Vertical etc..) for more details refer example
// http://using-d3js.com/04_07_ordinal_scales.html
Original file line number Diff line number Diff line change
@@ -659,6 +659,8 @@ export interface IModifiedCartesianChartProps extends ICartesianChartProps {
getMinMaxOfYAxis: (
points: ILineChartPoints[] | IHorizontalBarChartWithAxisDataPoint[] | IVerticalBarChartDataPoint[] | IDataPoint[],
yAxisType: YAxisType | undefined,
containerHeight?: number,
margins?: IMargins,
) => { startValue: number; endValue: number };

/**
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ import { select as d3Select, pointer } from 'd3-selection';
import { bisector } from 'd3-array';
import { ILegend, Legends } from '../Legends/index';
import { line as d3Line, curveLinear as d3curveLinear } from 'd3-shape';
import { max as d3Max, min as d3Min } from 'd3-array';
import {
classNamesFunction,
getId,
@@ -49,6 +50,7 @@ import {
createStringYAxis,
formatDate,
areArraysEqual,
YAxisType,
} from '../../utilities/index';
import { IChart } from '../../types/index';

@@ -67,6 +69,9 @@ const DEFAULT_LINE_STROKE_SIZE = 4;
// The given shape of a icon must be 2.5 times bigger than line width (known as stroke width)
const PATH_MULTIPLY_SIZE = 2.5;

// markersize for scatter plot
let maxMarkerSize = 0;

/**
*
* @param x units from origin
@@ -310,7 +315,7 @@ export class LineChartBase extends React.Component<ILineChartProps, ILineChartSt
legendBars={legendBars}
createYAxis={createNumericYAxis}
getmargins={this._getMargins}
getMinMaxOfYAxis={findNumericMinMaxOfY}
getMinMaxOfYAxis={this._getNumericMinMaxOfYForLineChart}
getGraphData={this._initializeLineChartData}
xAxisType={isXAxisDateType ? XAxisTypes.DateAxis : XAxisTypes.NumericAxis}
customizedCallout={this._getCustomizedCallout()}
@@ -391,7 +396,9 @@ export class LineChartBase extends React.Component<ILineChartProps, ILineChartSt
shiftX: number,
) => {
let domainNRangeValue: IDomainNRange;
if (xAxisType === XAxisTypes.NumericAxis) {
if (this.props.lineMode === 'scatter' && xAxisType === XAxisTypes.NumericAxis) {
domainNRangeValue = this._getDomainNRangeValuesWithPadding(points, margins, width, isRTL);
} else if (xAxisType === XAxisTypes.NumericAxis) {
domainNRangeValue = domainRangeOfNumericForAreaChart(points, margins, width, isRTL);
} else if (xAxisType === XAxisTypes.DateAxis) {
domainNRangeValue = domainRangeOfDateForAreaLineVerticalBarChart(
@@ -449,6 +456,37 @@ export class LineChartBase extends React.Component<ILineChartProps, ILineChartSt
: null;
};

private _getNumericMinMaxOfYForLineChart = (
points: ILineChartPoints[],
yAxisType: YAxisType,
containerHeight: number,
margins: IMargins,
): { startValue: number; endValue: number } => {
const { startValue, endValue } = findNumericMinMaxOfY(points);
let maxMarkerSizeForYAxis = 0;
if (this.props.lineMode === 'scatter') {
maxMarkerSize = d3Max(points, (point: ILineChartPoints) => {
return d3Max(point.data, (item: ILineChartDataPoint) => {
return item.markerSize as number;
});
})!;
maxMarkerSizeForYAxis = this._getExtendedDomainValue(
startValue,
endValue,
margins.bottom!,
containerHeight - margins.top!,
);
}
return {
startValue: startValue - maxMarkerSizeForYAxis,
endValue: endValue + maxMarkerSizeForYAxis,
};
};

private _getExtendedDomainValue = (x1: number, x2: number, y1: number, y2: number): number => {
return maxMarkerSize ? Math.abs((maxMarkerSize * (x2 - x1)) / (y2 - y1 - 2 * maxMarkerSize)) : 0;
};

private _getMargins = (margins: IMargins) => {
this.margins = margins;
};
@@ -1035,7 +1073,6 @@ export class LineChartBase extends React.Component<ILineChartProps, ILineChartSt
onBlur={this._handleMouseOut}
/>
</React.Fragment>,
/* eslint-enable react/jsx-no-bind */
);
}

@@ -1604,6 +1641,41 @@ export class LineChartBase extends React.Component<ILineChartProps, ILineChartSt
return point.callOutAccessibilityData?.ariaLabel || `${xValue}. ${legend}, ${yValue}.`;
};

private _getDomainNRangeValuesWithPadding = (
points: ILineChartPoints[],
margins: IMargins,
width: number,
isRTL: boolean,
): IDomainNRange => {
const xMin = d3Min(points, (point: ILineChartPoints) => {
return d3Min(point.data, (item: ILineChartDataPoint) => item.x as number)!;
})!;

const xMax = d3Max(points, (point: ILineChartPoints) => {
return d3Max(point.data, (item: ILineChartDataPoint) => {
return item.x as number;
});
})!;

const maxMarkerSizeForXAxis = this._getExtendedDomainValue(xMax, xMin, width - margins.right!, margins.left!);
const rStartValue = margins.left!;
const rEndValue = width - margins.right!;

return isRTL
? {
dStartValue: xMax + maxMarkerSizeForXAxis,
dEndValue: xMin - maxMarkerSizeForXAxis,
rStartValue,
rEndValue,
}
: {
dStartValue: xMin - maxMarkerSizeForXAxis,
dEndValue: xMax + maxMarkerSizeForXAxis,
rStartValue,
rEndValue,
};
};

private _isChartEmpty(): boolean {
return !(
this.props.data &&
32 changes: 5 additions & 27 deletions packages/charts/react-charting/src/utilities/utilities.ts
Original file line number Diff line number Diff line change
@@ -43,7 +43,6 @@ import {
} from '../index';
import { formatPrefix as d3FormatPrefix } from 'd3-format';

let maxMarkerSize = 0;
export type NumericAxis = D3Axis<number | { valueOf(): number }>;
export type StringAxis = D3Axis<string>;

@@ -446,19 +445,7 @@ export function createNumericYAxis(
: yMinMaxValues.startValue < yMinValue
? 0
: yMinValue!;
const maxMarkerSizeForYAxis = maxMarkerSize
? Math.abs(
(maxMarkerSize * (finalYmin - finalYmax)) /
(margins.top! - containerHeight + margins.bottom! + 2 * maxMarkerSize),
)
: 0;
const domainValues = prepareDatapoints(
finalYmax + maxMarkerSizeForYAxis,
finalYmin - maxMarkerSizeForYAxis,
yAxisTickCount,
isIntegralDataset,
roundedTicks,
);
const domainValues = prepareDatapoints(finalYmax, finalYmin, yAxisTickCount, isIntegralDataset, roundedTicks);
const yAxisScale = d3ScaleLinear()
.domain([supportNegativeData ? domainValues[0] : finalYmin, domainValues[domainValues.length - 1]])
.range([containerHeight - margins.bottom!, margins.top! + (eventAnnotationProps! ? eventLabelHeight! : 0)]);
@@ -918,28 +905,19 @@ export function domainRangeOfNumericForAreaChart(
return item.x as number;
});
})!;

maxMarkerSize = d3Max(points, (point: ILineChartPoints) => {
return d3Max(point.data, (item: ILineChartDataPoint) => {
return item.markerSize as number;
});
})!;
const maxMarkerSizeForXAxis = maxMarkerSize
? Math.abs((maxMarkerSize * (xMax - xMin)) / (width - margins.right! - margins.left! - 2 * maxMarkerSize))
: 0;
const rStartValue = margins.left!;
const rEndValue = width - margins.right!;

return isRTL
? {
dStartValue: xMax + maxMarkerSizeForXAxis,
dEndValue: xMin - maxMarkerSizeForXAxis,
dStartValue: xMax,
dEndValue: xMin,
rStartValue,
rEndValue,
}
: {
dStartValue: xMin - maxMarkerSizeForXAxis,
dEndValue: xMax + maxMarkerSizeForXAxis,
dStartValue: xMin,
dEndValue: xMax,
rStartValue,
rEndValue,
};
Loading
Oops, something went wrong.