From ee0b83d1ca0b4f32b8334332f1aaf6443345f9f3 Mon Sep 17 00:00:00 2001 From: Maria Zadnepryanets Date: Sat, 28 Mar 2020 13:03:51 +0000 Subject: [PATCH] Resolve "don't show temperature chart part of chart when temp not tracked" --- components/chart/chart-legend.js | 9 +- components/chart/chart.js | 171 ++++++++++++++++------------ components/chart/cycle-day-label.js | 2 +- components/chart/day-column.js | 18 +-- components/chart/no-data.js | 31 +++++ components/chart/styles.js | 13 ++- components/chart/symptom-cell.js | 3 +- components/chart/y-axis.js | 15 ++- config.js | 14 ++- i18n/en/labels.js | 5 +- 10 files changed, 187 insertions(+), 94 deletions(-) create mode 100644 components/chart/no-data.js diff --git a/components/chart/chart-legend.js b/components/chart/chart-legend.js index df6f8a6..4dc00b6 100644 --- a/components/chart/chart-legend.js +++ b/components/chart/chart-legend.js @@ -1,4 +1,5 @@ import React from 'react' +import PropTypes from 'prop-types' import { View } from 'react-native' import AppText from '../app-text' @@ -9,9 +10,9 @@ import { cycleDayColor } from '../../styles' import { shared as labels } from '../../i18n/en/labels' -const ChartLegend = () => { +const ChartLegend = ({ xAxisHeight }) => { return ( - + { ) } +ChartLegend.propTypes = { + xAxisHeight: PropTypes.number.isRequired +} + export default ChartLegend diff --git a/components/chart/chart.js b/components/chart/chart.js index d11131a..ed0feba 100644 --- a/components/chart/chart.js +++ b/components/chart/chart.js @@ -2,11 +2,13 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import { View, FlatList, ActivityIndicator } from 'react-native' +import NoData from './no-data' import AppLoadingView from '../app-loading' import YAxis from './y-axis' import nfpLines from './nfp-lines' import DayColumn from './day-column' import HorizontalGrid from './horizontal-grid' +import AppText from '../app-text' import { getCycleDaysSortedByDate } from '../../db' import nothingChanged from '../../db/db-unchanged' @@ -14,7 +16,7 @@ import { scaleObservable } from '../../local-storage' import { makeColumnInfo } from '../helpers/chart' import config from '../../config' - +import { shared } from '../../i18n/en/labels' import styles from './styles' export default class CycleChart extends Component { @@ -25,9 +27,26 @@ export default class CycleChart extends Component { constructor(props) { super(props) + this.state = {} this.cycleDaysSortedByDate = getCycleDaysSortedByDate() this.getFhmAndLtlInfo = nfpLines() + this.shouldShowTemperatureColumn = false + + this.prepareSymptomData() + } + + prepareSymptomData = () => { + this.symptomRowSymptoms = config.symptoms.filter((symptomName) => { + return this.cycleDaysSortedByDate.some(cycleDay => { + return cycleDay[symptomName] + }) + }) + this.chartSymptoms = [...this.symptomRowSymptoms] + if (this.cycleDaysSortedByDate.some(day => day.temperature)) { + this.chartSymptoms.push('temperature') + this.shouldShowTemperatureColumn = true + } } renderColumn = ({ item, index }) => { @@ -40,52 +59,40 @@ export default class CycleChart extends Component { columnHeight={this.columnHeight} symptomRowSymptoms={this.symptomRowSymptoms} chartSymptoms={this.chartSymptoms} + shouldShowTemperatureColumn={this.shouldShowTemperatureColumn} getFhmAndLtlInfo={this.getFhmAndLtlInfo} + xAxisHeight={this.xAxisHeight} /> ) } + reCalculateChartInfo = (nativeEvent) => { + const { height, width } = nativeEvent.layout + const xAxisCoefficient = this.shouldShowTemperatureColumn ? + config.xAxisHeightPercentage : config.xAxisHeightPercentageLarge + const symptomCoefficient = this.shouldShowTemperatureColumn ? + config.symptomHeightPercentage : config.symptomHeightPercentageLarge + + this.xAxisHeight = height * xAxisCoefficient + const remainingHeight = height - this.xAxisHeight + this.symptomHeight = remainingHeight * symptomCoefficient + this.symptomRowHeight = this.symptomRowSymptoms.length * + this.symptomHeight + this.columnHeight = remainingHeight - this.symptomRowHeight + const chartHeight = this.shouldShowTemperatureColumn ? + height : (this.symptomRowHeight + this.xAxisHeight) + + const numberOfColumnsToRender = Math.round(width / config.columnWidth) + const columns = makeColumnInfo() + + this.setState({ columns, chartHeight, numberOfColumnsToRender }) + } + onLayout = ({ nativeEvent }) => { if (this.state.chartHeight) return - const height = nativeEvent.layout.height - const reCalculateChartInfo = () => { - // how many symptoms need to be displayed on the chart's upper symptom row? - this.symptomRowSymptoms = [ - 'bleeding', - 'mucus', - 'cervix', - 'sex', - 'desire', - 'pain', - 'mood', - 'note' - ].filter((symptomName) => { - return this.cycleDaysSortedByDate.some(cycleDay => { - return cycleDay[symptomName] - }) - }) - this.xAxisHeight = height * config.xAxisHeightPercentage - const remainingHeight = height - this.xAxisHeight - this.symptomHeight = config.symptomHeightPercentage * remainingHeight - this.symptomRowHeight = this.symptomRowSymptoms.length * - this.symptomHeight - this.columnHeight = remainingHeight - this.symptomRowHeight - - this.chartSymptoms = [...this.symptomRowSymptoms] - if (this.cycleDaysSortedByDate.some(day => day.temperature)) { - this.chartSymptoms.push('temperature') - } - - const columnData = makeColumnInfo() - this.setState({ - columns: columnData, - chartHeight: height - }) - } - - reCalculateChartInfo() - this.updateListeners(reCalculateChartInfo) + this.reCalculateChartInfo(nativeEvent) + this.updateListeners(this.reCalculateChartInfo) } updateListeners(dataUpdateHandler) { @@ -110,44 +117,60 @@ export default class CycleChart extends Component { } render() { - const { chartHeight, chartLoaded } = this.state + const { chartHeight, chartLoaded, numberOfColumnsToRender } = this.state + const shouldShowChart = this.chartSymptoms.length > 0 ? true : false + return ( - - {!chartLoaded && } + + {!shouldShowChart && } + {shouldShowChart && !chartHeight && !chartLoaded && } + + {shouldShowChart && ( + - {chartHeight && chartLoaded && ( - - - - - )} + {chartHeight && chartLoaded && ( + + + {this.shouldShowTemperatureColumn && ()} + + )} - {chartHeight && - item} - initialNumToRender={15} - windowSize={30} - onLayout={() => this.setState({chartLoaded: true})} - onEndReached={() => this.setState({end: true})} - ListFooterComponent={} - updateCellsBatchingPeriod={800} - /> - } + {chartHeight && + item} + initialNumToRender={numberOfColumnsToRender} + windowSize={30} + onLayout={() => this.setState({chartLoaded: true})} + onEndReached={() => this.setState({end: true})} + ListFooterComponent={} + updateCellsBatchingPeriod={800} + contentContainerStyle={{height: chartHeight}} + /> + } + + )} + + {shouldShowChart && chartLoaded && !this.shouldShowTemperatureColumn + && ( + + {shared.noTemperatureWarning} + + )} ) } diff --git a/components/chart/cycle-day-label.js b/components/chart/cycle-day-label.js index 38a0d2e..bb794f4 100644 --- a/components/chart/cycle-day-label.js +++ b/components/chart/cycle-day-label.js @@ -20,7 +20,7 @@ const CycleDayLabel = ({ height, date }) => { const boldDateLabel = isFirstDayOfMonth ? {fontWeight: 'bold'} : {} return ( - + {cycleDayNumber ? cycleDayNumber : ' '} diff --git a/components/chart/day-column.js b/components/chart/day-column.js index 687b993..efefe2e 100644 --- a/components/chart/day-column.js +++ b/components/chart/day-column.js @@ -26,9 +26,10 @@ class DayColumn extends Component { getFhmAndLtlInfo: PropTypes.func.isRequired, navigate: PropTypes.func.isRequired, setDate: PropTypes.func.isRequired, + shouldShowTemperatureColumn: PropTypes.bool, symptomHeight: PropTypes.number.isRequired, symptomRowSymptoms: PropTypes.array, - xAxisHeight: PropTypes.number + xAxisHeight: PropTypes.number, } constructor(props) { @@ -77,10 +78,13 @@ class DayColumn extends Component { } render() { - const { dateString, + const { columnHeight, + dateString, + shouldShowTemperatureColumn, + symptomHeight, symptomRowSymptoms, - columnHeight, - xAxisHeight } = this.props + xAxisHeight + } = this.props return ( ) } )} - + />} { + return ( + + + {shared.noDataWarning} + {navigate('CycleDay')}} + style={{marginHorizontal: 40}} + > + {shared.noDataButtonText} + + + + ) +} + +NoData.propTypes = { + navigate: PropTypes.func, +} + +export default NoData \ No newline at end of file diff --git a/components/chart/styles.js b/components/chart/styles.js index 450b408..fba4df1 100644 --- a/components/chart/styles.js +++ b/components/chart/styles.js @@ -25,9 +25,14 @@ const orangeColor = '#bc6642' const mintColor = '#6ca299' const styles = { - container: { - flexDirection: 'row', - flex: 1, + container: { flex: 1 }, + chartContainer: { flexDirection: 'column' }, + chartArea: { flexDirection: 'row' }, + centerItem: { + flex:1, + alignItems: 'center', + justifyContent: 'center', + marginHorizontal: 25, }, curve: { stroke: colorTemperature, @@ -137,7 +142,7 @@ const styles = { }, chartLegend: { alignItems: 'center', - justifyContent: 'center', + justifyContent: 'flex-end', }, boldTick: { fontWeight: 'bold', diff --git a/components/chart/symptom-cell.js b/components/chart/symptom-cell.js index fa76042..4b1124c 100644 --- a/components/chart/symptom-cell.js +++ b/components/chart/symptom-cell.js @@ -3,6 +3,7 @@ import PropTypes from 'prop-types' import { View } from 'react-native' import styles from './styles' +import config from '../../config' const SymptomCell = ({ height, @@ -12,7 +13,7 @@ const SymptomCell = ({ }) => { const shouldDrawDot = symptomValue !== false - const styleParent = [styles.symptomRow, { height }] + const styleParent = [styles.symptomRow, { height, width: config.columnWidth }] let styleChild if (shouldDrawDot) { diff --git a/components/chart/y-axis.js b/components/chart/y-axis.js index acd3ccf..db27e10 100644 --- a/components/chart/y-axis.js +++ b/components/chart/y-axis.js @@ -8,8 +8,15 @@ import ChartLegend from './chart-legend' import styles from './styles' -const YAxis = ({ height, symptomsToDisplay, symptomsSectionHeight }) => { +const YAxis = ({ + height, + symptomsToDisplay, + symptomsSectionHeight, + shouldShowTemperatureColumn, + xAxisHeight +}) => { const symptomIconHeight = symptomsSectionHeight / symptomsToDisplay.length + return ( @@ -22,8 +29,8 @@ const YAxis = ({ height, symptomsToDisplay, symptomsSectionHeight }) => { ) )} - - + {shouldShowTemperatureColumn && } + ) } @@ -32,6 +39,8 @@ YAxis.propTypes = { height: PropTypes.number, symptomsToDisplay: PropTypes.array, symptomsSectionHeight: PropTypes.number, + shouldShowTemperatureColumn: PropTypes.bool, + xAxisHeight: PropTypes.number.isRequired } export default YAxis diff --git a/config.js b/config.js index d0c471e..0fd19c5 100644 --- a/config.js +++ b/config.js @@ -1,7 +1,9 @@ const config = { columnWidth: 25, xAxisHeightPercentage: 0.08, + xAxisHeightPercentageLarge: 0.12, symptomHeightPercentage: 0.05, + symptomHeightPercentageLarge: 0.1, temperatureScale: { defaultLow: 35, defaultHigh: 38, @@ -9,7 +11,17 @@ const config = { max: 40, units: 0.1, verticalPadding: 0.03 - } + }, + symptoms: [ + 'bleeding', + 'mucus', + 'cervix', + 'sex', + 'desire', + 'pain', + 'mood', + 'note' + ], } config.columnMiddle = config.columnWidth / 2 diff --git a/i18n/en/labels.js b/i18n/en/labels.js index ad20e17..8047813 100644 --- a/i18n/en/labels.js +++ b/i18n/en/labels.js @@ -15,7 +15,10 @@ export const shared = { date: 'Date', cycleDayWithLinebreak: 'Cycle\nday', loading: 'Loading ...', - enter: 'Enter' + noDataWarning: 'You haven\'t entered any data yet.', + noTemperatureWarning: 'You haven\'t entered any temperature data yet.', + noDataButtonText: 'Start entering data now', + enter: 'Enter', } export const headerTitles = {