Skip to content

Commit

Permalink
feat(series): adding connectNulls to AreaSeries
Browse files Browse the repository at this point in the history
connectNulls property to specifying gaps.

Relates to react-financial#497
  • Loading branch information
markmcdowell committed Apr 26, 2021
1 parent ec15403 commit d800dc5
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 17 deletions.
13 changes: 9 additions & 4 deletions packages/series/src/AlternatingFillAreaSeries.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import { SVGComponent } from "./SVGComponent";

export interface AlternatingFillAreaSeriesProps {
readonly baseAt: number;
readonly className?: string;
/**
* Wether to connect the area between undefined data points.
*/
readonly connectNulls?: boolean;
/**
* Color, gradient, or pattern to use for fill.
*/
Expand Down Expand Up @@ -51,7 +54,7 @@ export interface AlternatingFillAreaSeriesProps {
*/
export class AlternatingFillAreaSeries extends React.Component<AlternatingFillAreaSeriesProps> {
public static defaultProps = {
className: "react-financial-charts-alternating-area",
connectNulls: false,
fillStyle: {
top: "rgba(38, 166, 154, 0.1)",
bottom: "rgba(239, 83, 80, 0.1)",
Expand All @@ -75,7 +78,7 @@ export class AlternatingFillAreaSeries extends React.Component<AlternatingFillAr

public render() {
const {
className,
connectNulls,
yAccessor,
curve,
strokeStyle = AlternatingFillAreaSeries.defaultProps.strokeStyle,
Expand All @@ -85,10 +88,11 @@ export class AlternatingFillAreaSeries extends React.Component<AlternatingFillAr
} = this.props;

return (
<g className={className}>
<g>
<SVGComponent>{this.renderClip}</SVGComponent>
<AreaSeries
canvasClip={this.topClip}
connectNulls={connectNulls}
yAccessor={yAccessor}
curve={curve}
baseAt={this.baseAt}
Expand All @@ -99,6 +103,7 @@ export class AlternatingFillAreaSeries extends React.Component<AlternatingFillAr
/>
<AreaSeries
canvasClip={this.bottomClip}
connectNulls={connectNulls}
yAccessor={yAccessor}
curve={curve}
baseAt={this.baseAt}
Expand Down
29 changes: 20 additions & 9 deletions packages/series/src/AreaOnlySeries.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ export interface AreaOnlySeriesProps {
| number
| ((yScale: ScaleContinuousNumeric<number, number>, d: [number, number], moreProps: any) => number | undefined);
readonly canvasClip?: (context: CanvasRenderingContext2D, moreProps: any) => void;
/**
* Wether to connect the area between undefined data points.
*/
readonly connectNulls?: boolean;
/**
* A factory for a curve generator for the area.
*/
readonly curve?: CurveFactory;
/**
* The default accessor for defined returns not NaN, thus assumes that the input data is always a number.
*/
Expand All @@ -19,18 +27,18 @@ export interface AreaOnlySeriesProps {
* Color, gradient, or pattern to use for fill.
*/
readonly fillStyle?: string;
/**
* A factory for a curve generator for the area.
*/
readonly curve?: CurveFactory;
/**
* Selector for data to plot.
*/
readonly yAccessor: (data: any) => number | undefined;
}

/**
* `AreaOnlySeries` component.
*/
export class AreaOnlySeries extends React.Component<AreaOnlySeriesProps> {
public static defaultProps = {
connectNulls: false,
defined: (d: number | undefined) => d !== undefined && !isNaN(d),
base: (yScale: ScaleContinuousNumeric<number, number>) => first(yScale.range()),
};
Expand All @@ -41,6 +49,7 @@ export class AreaOnlySeries extends React.Component<AreaOnlySeriesProps> {

private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => {
const {
connectNulls,
fillStyle,
curve,
canvasClip,
Expand All @@ -65,21 +74,23 @@ export class AreaOnlySeries extends React.Component<AreaOnlySeriesProps> {
ctx.fillStyle = fillStyle;
}

ctx.beginPath();
const newBase = functor(base);

const areaSeries = area()
.defined((d) => defined(yAccessor(d)))
.x((d) => Math.round(xScale(xAccessor(d))))
.y0((d) => newBase(yScale, d, moreProps))
.y1((d) => Math.round(yScale(yAccessor(d))))
.context(ctx);
.y1((d) => Math.round(yScale(yAccessor(d))));

if (curve !== undefined) {
areaSeries.curve(curve);
}

areaSeries(plotData);
if (!connectNulls) {
areaSeries.defined((d) => defined(yAccessor(d)));
}

ctx.beginPath();
areaSeries.context(ctx)(plotData);
ctx.fill();

if (canvasClip !== undefined) {
Expand Down
12 changes: 8 additions & 4 deletions packages/series/src/AreaSeries.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ export interface AreaSeriesProps {
| number
| ((yScale: ScaleContinuousNumeric<number, number>, d: [number, number], moreProps: any) => number);
readonly canvasClip?: (context: CanvasRenderingContext2D, moreProps: any) => void;
readonly className?: string;
/**
* Wether to connect the area between undefined data points.
*/
readonly connectNulls?: boolean;
/**
* Color, gradient, or pattern to use for fill.
*/
Expand Down Expand Up @@ -45,7 +48,6 @@ export interface AreaSeriesProps {
*/
export class AreaSeries extends Component<AreaSeriesProps> {
public static defaultProps: Partial<AreaSeriesProps> = {
className: "react-financial-charts-area",
fillStyle: "rgba(33, 150, 243, 0.1)",
strokeStyle: "#2196f3",
strokeWidth: 3,
Expand All @@ -55,7 +57,7 @@ export class AreaSeries extends Component<AreaSeriesProps> {
public render() {
const {
baseAt,
className,
connectNulls,
strokeStyle,
strokeWidth,
strokeDasharray,
Expand All @@ -66,15 +68,17 @@ export class AreaSeries extends Component<AreaSeriesProps> {
} = this.props;

return (
<g className={className}>
<g>
<AreaOnlySeries
connectNulls={connectNulls}
yAccessor={yAccessor}
curve={curve}
base={baseAt}
fillStyle={fillStyle}
canvasClip={canvasClip}
/>
<LineSeries
connectNulls={connectNulls}
yAccessor={yAccessor}
strokeStyle={strokeStyle}
strokeWidth={strokeWidth}
Expand Down

0 comments on commit d800dc5

Please sign in to comment.