From 889f1137f4b21489e1e8c3916c4e370af13d80e5 Mon Sep 17 00:00:00 2001 From: Artem Date: Mon, 1 Feb 2021 21:07:18 +0100 Subject: [PATCH] Additional prop to customize vertical labels height --- src/AbstractChart.tsx | 67 +++++++++++++++++++++++++++++++---------- src/StackedBarChart.tsx | 36 ++++++++++++++++------ 2 files changed, 78 insertions(+), 25 deletions(-) diff --git a/src/AbstractChart.tsx b/src/AbstractChart.tsx index b9c45967..612ffdfb 100644 --- a/src/AbstractChart.tsx +++ b/src/AbstractChart.tsx @@ -30,10 +30,13 @@ export interface AbstractChartConfig extends ChartConfig { stackedBar?: boolean; verticalLabelRotation?: number; formatXLabel?: (xLabel: string) => string; + verticalLabelsHeightPercentage?: number; } export type AbstractChartState = {}; +export const DEFAULT_X_LABELS_HEIGHT_PERCENTAGE = 0.75; + class AbstractChart< IProps extends AbstractChartProps, IState extends AbstractChartState @@ -128,8 +131,15 @@ class AbstractChart< } renderHorizontalLines = config => { - const { count, width, height, paddingTop, paddingRight } = config; - const basePosition = height - height / 4; + const { + count, + width, + height, + paddingTop, + paddingRight, + verticalLabelsHeightPercentage = DEFAULT_X_LABELS_HEIGHT_PERCENTAGE + } = config; + const basePosition = height * verticalLabelsHeightPercentage; return [...new Array(count + 1)].map((_, i) => { const y = (basePosition / count) * i + paddingTop; @@ -147,14 +157,20 @@ class AbstractChart< }; renderHorizontalLine = config => { - const { width, height, paddingTop, paddingRight } = config; + const { + width, + height, + paddingTop, + paddingRight, + verticalLabelsHeightPercentage = DEFAULT_X_LABELS_HEIGHT_PERCENTAGE + } = config; return ( ); @@ -171,7 +187,8 @@ class AbstractChart< paddingRight, horizontalLabelRotation = 0, decimalPlaces = 2, - formatYLabel = (yLabel: string) => yLabel + formatYLabel = (yLabel: string) => yLabel, + verticalLabelsHeightPercentage = DEFAULT_X_LABELS_HEIGHT_PERCENTAGE } = config; const { @@ -195,12 +212,14 @@ class AbstractChart< )}${yAxisSuffix}`; } - const basePosition = height - height / 4; + const basePosition = height * verticalLabelsHeightPercentage; const x = paddingRight - yLabelsOffset; const y = count === 1 && this.props.fromZero ? paddingTop + 4 - : (height * 3) / 4 - (basePosition / count) * i + paddingTop; + : height * verticalLabelsHeightPercentage - + (basePosition / count) * i + + paddingTop; return ( xLabel + formatXLabel = xLabel => xLabel, + verticalLabelsHeightPercentage = DEFAULT_X_LABELS_HEIGHT_PERCENTAGE }: Pick< AbstractChartConfig, | "labels" @@ -239,6 +259,7 @@ class AbstractChart< | "stackedBar" | "verticalLabelRotation" | "formatXLabel" + | "verticalLabelsHeightPercentage" >) => { const { xAxisLabel = "", @@ -264,7 +285,11 @@ class AbstractChart< horizontalOffset) * fac; - const y = (height * 3) / 4 + paddingTop + fontSize * 2 + xLabelsOffset; + const y = + height * verticalLabelsHeightPercentage + + paddingTop + + fontSize * 2 + + xLabelsOffset; return ( , "data" > & { data: number[] }) => { @@ -312,7 +343,7 @@ class AbstractChart< ((width - paddingRight) / (data.length / yAxisInterval)) * i + paddingRight )} - y2={height - height / 4 + paddingTop} + y2={height * verticalLabelsHeightPercentage + paddingTop} {...this.getPropsForBackgroundLines()} /> ); @@ -323,14 +354,18 @@ class AbstractChart< renderVerticalLine = ({ height, paddingTop, - paddingRight - }: Pick) => ( + paddingRight, + verticalLabelsHeightPercentage = DEFAULT_X_LABELS_HEIGHT_PERCENTAGE + }: Pick< + AbstractChartConfig, + "height" | "paddingRight" | "paddingTop" | "verticalLabelsHeightPercentage" + >) => ( ); diff --git a/src/StackedBarChart.tsx b/src/StackedBarChart.tsx index fcee1e85..30c0e2f2 100644 --- a/src/StackedBarChart.tsx +++ b/src/StackedBarChart.tsx @@ -4,7 +4,8 @@ import { G, Rect, Svg, Text } from "react-native-svg"; import AbstractChart, { AbstractChartConfig, - AbstractChartProps + AbstractChartProps, + DEFAULT_X_LABELS_HEIGHT_PERCENTAGE } from "./AbstractChart"; export interface StackedBarChartData { @@ -48,6 +49,12 @@ export interface StackedBarChartProps extends AbstractChartProps { segments?: number; percentile?: boolean; + + /** + * Percentage of the chart height, dedicated to vertical labels + * (space below chart) + */ + verticalLabelsHeightPercentage?: number; } type StackedBarChartState = {}; @@ -75,10 +82,16 @@ class StackedBarChart extends AbstractChart< paddingRight, border, colors, - stackedBar = false + stackedBar = false, + verticalLabelsHeightPercentage }: Pick< Omit, - "width" | "height" | "paddingRight" | "paddingTop" | "stackedBar" + | "width" + | "height" + | "paddingRight" + | "paddingTop" + | "stackedBar" + | "verticalLabelsHeightPercentage" > & { border: number; colors: string[]; @@ -95,7 +108,7 @@ class StackedBarChart extends AbstractChart< fac = 0.7; } const sum = this.props.percentile ? x.reduce((a, b) => a + b, 0) : border; - const barsAreaHeight = (height / 4) * 3; + const barsAreaHeight = height * verticalLabelsHeightPercentage; for (let z = 0; z < x.length; z++) { h = barsAreaHeight * (x[z] / sum); const y = barsAreaHeight - h + st; @@ -184,7 +197,8 @@ class StackedBarChart extends AbstractChart< withVerticalLabels = true, segments = 4, decimalPlaces, - percentile = false + percentile = false, + verticalLabelsHeightPercentage = DEFAULT_X_LABELS_HEIGHT_PERCENTAGE } = this.props; const { borderRadius = 0 } = style; @@ -229,7 +243,8 @@ class StackedBarChart extends AbstractChart< {this.renderHorizontalLines({ ...config, count: segments, - paddingTop + paddingTop, + verticalLabelsHeightPercentage })} @@ -240,7 +255,8 @@ class StackedBarChart extends AbstractChart< data: [0, border], paddingTop, paddingRight, - decimalPlaces + decimalPlaces, + verticalLabelsHeightPercentage }) : null} @@ -252,7 +268,8 @@ class StackedBarChart extends AbstractChart< paddingRight: paddingRight + 28, stackedBar, paddingTop, - horizontalOffset: barWidth + horizontalOffset: barWidth, + verticalLabelsHeightPercentage }) : null} @@ -264,7 +281,8 @@ class StackedBarChart extends AbstractChart< colors: this.props.data.barColors, paddingTop, paddingRight: paddingRight + 20, - stackedBar + stackedBar, + verticalLabelsHeightPercentage })} {data.legend &&