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
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
"react-native-svg": "> 6.4.1"
},
"dependencies": {
"lodash": "^4.17.13",
"paths-js": "^0.4.10",
"point-in-polygon": "^1.0.1"
},
Expand Down
64 changes: 46 additions & 18 deletions src/AbstractChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ class AbstractChart<
> extends Component<AbstractChartProps & IProps, AbstractChartState & IState> {
private chartId = nextChartId++;

protected getValidData = (data: number[] = []) => {
return data.filter(value => typeof value === "number" && isFinite(value));
};

protected getGradientId = (id: string) => {
return `chart-kit-${this.chartId}-${id}`;
};
Expand All @@ -55,48 +59,70 @@ class AbstractChart<
};

calcScaler = (data: number[]) => {
const values = this.getValidData(data);

if (values.length === 0) {
return 1;
}

if (this.props.fromZero && this.props.fromNumber) {
return (
Math.max(...data, this.props.fromNumber) - Math.min(...data, 0) || 1
Math.max(...values, this.props.fromNumber) - Math.min(...values, 0) || 1
);
} else if (this.props.fromZero) {
return Math.max(...data, 0) - Math.min(...data, 0) || 1;
return Math.max(...values, 0) - Math.min(...values, 0) || 1;
} else if (this.props.fromNumber) {
return (
Math.max(...data, this.props.fromNumber) -
Math.min(...data, this.props.fromNumber) || 1
Math.max(...values, this.props.fromNumber) -
Math.min(...values, this.props.fromNumber) || 1
);
} else {
return Math.max(...data) - Math.min(...data) || 1;
return Math.max(...values) - Math.min(...values) || 1;
}
};

calcBaseHeight = (data: number[], height: number) => {
const min = Math.min(...data);
const max = Math.max(...data);
const values = this.getValidData(data);

if (values.length === 0) {
return height;
}

const min = Math.min(...values);
const max = Math.max(...values);
if (min >= 0 && max >= 0) {
return height;
} else if (min < 0 && max <= 0) {
return 0;
} else if (min < 0 && max > 0) {
return (height * max) / this.calcScaler(data);
return (height * max) / this.calcScaler(values);
}
};

calcHeight = (val: number, data: number[], height: number) => {
const max = Math.max(...data);
const min = Math.min(...data);
if (typeof val !== "number" || !isFinite(val)) {
return 0;
}

const values = this.getValidData(data);

if (values.length === 0) {
return 0;
}

const max = Math.max(...values);
const min = Math.min(...values);

if (min < 0 && max > 0) {
return height * (val / this.calcScaler(data));
return height * (val / this.calcScaler(values));
} else if (min >= 0 && max >= 0) {
return this.props.fromZero
? height * (val / this.calcScaler(data))
: height * ((val - min) / this.calcScaler(data));
? height * (val / this.calcScaler(values))
: height * ((val - min) / this.calcScaler(values));
} else if (min < 0 && max <= 0) {
return this.props.fromZero
? height * (val / this.calcScaler(data))
: height * ((val - max) / this.calcScaler(data));
? height * (val / this.calcScaler(values))
: height * ((val - max) / this.calcScaler(values));
}
};

Expand Down Expand Up @@ -207,6 +233,8 @@ class AbstractChart<
formatYLabel = (yLabel: string) => yLabel,
verticalLabelsHeightPercentage = DEFAULT_X_LABELS_HEIGHT_PERCENTAGE
} = config;
const values = this.getValidData(data);
const labelData = values.length === 0 ? [0] : values;

const {
yAxisLabel = "",
Expand All @@ -218,12 +246,12 @@ class AbstractChart<

if (count === 1) {
yLabel = `${yAxisLabel}${formatYLabel(
data[0].toFixed(decimalPlaces)
labelData[0].toFixed(decimalPlaces)
)}${yAxisSuffix}`;
} else {
const label = this.props.fromZero
? (this.calcScaler(data) / count) * i + Math.min(...data, 0)
: (this.calcScaler(data) / count) * i + Math.min(...data);
? (this.calcScaler(labelData) / count) * i + Math.min(...labelData, 0)
: (this.calcScaler(labelData) / count) * i + Math.min(...labelData);
yLabel = `${yAxisLabel}${formatYLabel(
label.toFixed(decimalPlaces)
)}${yAxisSuffix}`;
Expand Down
2 changes: 1 addition & 1 deletion src/HelperTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export interface Dataset {
key?: string | number;

/** Stroke Dash Array */
strokeDashArray?: number[];
strokeDashArray?: number[] | string;

/** Stroke Dash Offset */
strokeDashOffset?: number;
Expand Down
3 changes: 2 additions & 1 deletion src/StackedBarChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,10 @@ class StackedBarChart extends AbstractChart<
fac = 0.7;
}
const sum = this.props.percentile ? x.reduce((a, b) => a + b, 0) : border;
const safeSum = sum || 1;
const barsAreaHeight = height * verticalLabelsHeightPercentage;
for (let z = 0; z < x.length; z++) {
h = barsAreaHeight * (x[z] / sum);
h = barsAreaHeight * (x[z] / safeSum);
const y = barsAreaHeight - h + st;
const xC =
(paddingRight +
Expand Down
8 changes: 4 additions & 4 deletions src/contribution-graph/ContributionGraph.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import _ from "lodash";
import React from "react";
import { View } from "react-native";
import { G, Rect, RectProps, Svg, Text } from "react-native-svg";
Expand All @@ -20,6 +19,7 @@ import { ContributionGraphProps, ContributionGraphState } from ".";
const SQUARE_SIZE = 20;
const MONTH_LABEL_GUTTER_SIZE = 8;
const paddingLeft = 32;
const range = (count: number) => Array.from({ length: count }, (_, i) => i);

export type ContributionChartValue = {
value: number;
Expand Down Expand Up @@ -322,15 +322,15 @@ class ContributionGraph extends AbstractChart<
const [x, y] = this.getTransformForWeek(weekIndex);
return (
<G key={weekIndex} x={x} y={y}>
{_.range(DAYS_IN_WEEK).map(dayIndex =>
{range(DAYS_IN_WEEK).map(dayIndex =>
this.renderSquare(dayIndex, weekIndex * DAYS_IN_WEEK + dayIndex)
)}
</G>
);
}

renderAllWeeks() {
return _.range(this.getWeekCount()).map(weekIndex =>
return range(this.getWeekCount()).map(weekIndex =>
this.renderWeek(weekIndex)
);
}
Expand All @@ -340,7 +340,7 @@ class ContributionGraph extends AbstractChart<
return null;
}

const weekRange = _.range(this.getWeekCount() - 1); // don't render for last week, because label will be cut off
const weekRange = range(this.getWeekCount() - 1); // don't render for last week, because label will be cut off

return weekRange.map(weekIndex => {
const endOfWeek = shiftDate(
Expand Down
31 changes: 22 additions & 9 deletions src/line-chart/LineChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -237,11 +237,20 @@ class LineChart extends AbstractChart<LineChartProps, LineChartState> {

getDatas = (data: Dataset[]): number[] => {
return data.reduce(
(acc, item) => (item.data ? [...acc, ...item.data] : acc),
(acc, item) =>
item.data ? [...acc, ...this.getValidData(item.data)] : acc,
[]
);
};

getStrokeDashArray = (dataset: Dataset) => {
const { strokeDashArray } = dataset;

return Array.isArray(strokeDashArray)
? strokeDashArray.join(",")
: strokeDashArray;
};

getPropsForDots = (x: any, i: number) => {
const { getDotProps, chartConfig } = this.props;

Expand Down Expand Up @@ -307,6 +316,7 @@ class LineChart extends AbstractChart<LineChartProps, LineChartState> {
getColor: opacity => this.getColor(dataset, opacity)
});
};
const pressProps = { onPressIn, onClick: onPressIn } as any;

output.push(
<Circle
Expand All @@ -318,7 +328,7 @@ class LineChart extends AbstractChart<LineChartProps, LineChartState> {
? getDotColor(x, i)
: this.getColor(dataset, 0.9)
}
onPressIn={onPressIn}
{...pressProps}
{...this.getPropsForDots(x, i)}
/>,
<Circle
Expand All @@ -328,7 +338,7 @@ class LineChart extends AbstractChart<LineChartProps, LineChartState> {
r="14"
fill="#fff"
fillOpacity={0}
onPressIn={onPressIn}
{...pressProps}
/>,
<React.Fragment key={`dot-content-${datasetIndex}-${i}`}>
{renderDotContent({ x: cx, y: cy, index: i, indexData: x })}
Expand Down Expand Up @@ -620,9 +630,8 @@ class LineChart extends AbstractChart<LineChartProps, LineChartState> {
const baseHeight = this.calcBaseHeight(datas, height);
const xMax = this.getXMaxValues(data);

let lastPoint: string;

data.forEach((dataset, index) => {
let lastPoint: string;
const points = dataset.data.map((d, i) => {
if (d === null) return lastPoint;
const x = (i * (width - paddingRight)) / xMax + paddingRight;
Expand All @@ -641,7 +650,7 @@ class LineChart extends AbstractChart<LineChartProps, LineChartState> {
fill="none"
stroke={this.getColor(dataset, 0.2)}
strokeWidth={this.getStrokeWidth(dataset)}
strokeDasharray={dataset.strokeDashArray}
strokeDasharray={this.getStrokeDashArray(dataset)}
strokeDashoffset={dataset.strokeDashOffset}
/>
);
Expand Down Expand Up @@ -729,7 +738,7 @@ class LineChart extends AbstractChart<LineChartProps, LineChartState> {
fill="none"
stroke={this.getColor(dataset, 0.2)}
strokeWidth={this.getStrokeWidth(dataset)}
strokeDasharray={dataset.strokeDashArray}
strokeDasharray={this.getStrokeDashArray(dataset)}
strokeDashoffset={dataset.strokeDashOffset}
/>
);
Expand Down Expand Up @@ -839,6 +848,10 @@ class LineChart extends AbstractChart<LineChartProps, LineChartState> {
};

const datas = this.getDatas(data.datasets);
const firstDataset = data.datasets[0] || { data: [] };
const hasScrollableData =
withScrollableDot &&
data.datasets.some(dataset => dataset.data && dataset.data.length > 0);

let count = Math.min(...datas) === Math.max(...datas) ? 1 : 4;
if (segments) {
Expand Down Expand Up @@ -903,7 +916,7 @@ class LineChart extends AbstractChart<LineChartProps, LineChartState> {
(withInnerLines
? this.renderVerticalLines({
...config,
data: data.datasets[0].data,
data: firstDataset.data,
paddingTop: paddingTop as number,
paddingRight: paddingRight as number
})
Expand Down Expand Up @@ -955,7 +968,7 @@ class LineChart extends AbstractChart<LineChartProps, LineChartState> {
})}
</G>
<G>
{withScrollableDot &&
{hasScrollableData &&
this.renderScrollableDot({
...config,
...chartConfig,
Expand Down
Loading