Merge branch '183-show-no-temperature-when-not-tracked' into 'master'
Resolve "don't show temperature chart part of chart when temp not tracked" Closes #183 See merge request bloodyhealth/drip!257
This commit is contained in:
@@ -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 (
|
||||
<View style={[styles.yAxis, styles.chartLegend]}>
|
||||
<View style={[styles.yAxis, styles.chartLegend, {height: xAxisHeight}]}>
|
||||
<DripHomeIcon
|
||||
name="circle"
|
||||
size={styles.yAxis.width - 7}
|
||||
@@ -24,4 +25,8 @@ const ChartLegend = () => {
|
||||
)
|
||||
}
|
||||
|
||||
ChartLegend.propTypes = {
|
||||
xAxisHeight: PropTypes.number.isRequired
|
||||
}
|
||||
|
||||
export default ChartLegend
|
||||
|
||||
+97
-74
@@ -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 (
|
||||
<View
|
||||
onLayout={this.onLayout}
|
||||
style={styles.container}
|
||||
>
|
||||
{!chartLoaded && <AppLoadingView />}
|
||||
<View onLayout={this.onLayout} style={styles.container}>
|
||||
{!shouldShowChart && <NoData navigate={this.props.navigate}/>}
|
||||
{shouldShowChart && !chartHeight && !chartLoaded && <AppLoadingView />}
|
||||
<View style={styles.chartContainer}>
|
||||
{shouldShowChart && (
|
||||
<View style={styles.chartArea}>
|
||||
|
||||
{chartHeight && chartLoaded && (
|
||||
<React.Fragment>
|
||||
<YAxis
|
||||
height={this.columnHeight}
|
||||
symptomsToDisplay={this.symptomRowSymptoms}
|
||||
symptomsSectionHeight={this.symptomRowHeight}
|
||||
/>
|
||||
<HorizontalGrid
|
||||
height={this.columnHeight}
|
||||
startPosition={this.symptomRowHeight}
|
||||
/>
|
||||
</React.Fragment>
|
||||
)}
|
||||
{chartHeight && chartLoaded && (
|
||||
<React.Fragment>
|
||||
<YAxis
|
||||
height={this.columnHeight}
|
||||
symptomsToDisplay={this.symptomRowSymptoms}
|
||||
symptomsSectionHeight={this.symptomRowHeight}
|
||||
shouldShowTemperatureColumn=
|
||||
{this.shouldShowTemperatureColumn}
|
||||
xAxisHeight={this.xAxisHeight}
|
||||
/>
|
||||
{this.shouldShowTemperatureColumn && (<HorizontalGrid
|
||||
height={this.columnHeight}
|
||||
startPosition={this.symptomRowHeight}
|
||||
/>)}
|
||||
</React.Fragment>
|
||||
)}
|
||||
|
||||
{chartHeight &&
|
||||
<FlatList
|
||||
horizontal={true}
|
||||
inverted={true}
|
||||
showsHorizontalScrollIndicator={false}
|
||||
data={this.state.columns}
|
||||
renderItem={this.renderColumn}
|
||||
keyExtractor={item => item}
|
||||
initialNumToRender={15}
|
||||
windowSize={30}
|
||||
onLayout={() => this.setState({chartLoaded: true})}
|
||||
onEndReached={() => this.setState({end: true})}
|
||||
ListFooterComponent={<LoadingMoreView end={this.state.end}/>}
|
||||
updateCellsBatchingPeriod={800}
|
||||
/>
|
||||
}
|
||||
{chartHeight &&
|
||||
<FlatList
|
||||
horizontal={true}
|
||||
inverted={true}
|
||||
showsHorizontalScrollIndicator={false}
|
||||
data={this.state.columns}
|
||||
renderItem={this.renderColumn}
|
||||
keyExtractor={item => item}
|
||||
initialNumToRender={numberOfColumnsToRender}
|
||||
windowSize={30}
|
||||
onLayout={() => this.setState({chartLoaded: true})}
|
||||
onEndReached={() => this.setState({end: true})}
|
||||
ListFooterComponent={<LoadingMoreView end={this.state.end}/>}
|
||||
updateCellsBatchingPeriod={800}
|
||||
contentContainerStyle={{height: chartHeight}}
|
||||
/>
|
||||
}
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
{shouldShowChart && chartLoaded && !this.shouldShowTemperatureColumn
|
||||
&& (
|
||||
<View style={styles.centerItem}>
|
||||
<AppText style={{textAlign: 'center'}}>{shared.noTemperatureWarning}</AppText>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ const CycleDayLabel = ({ height, date }) => {
|
||||
const boldDateLabel = isFirstDayOfMonth ? {fontWeight: 'bold'} : {}
|
||||
|
||||
return (
|
||||
<View style={{ height }}>
|
||||
<View style={[styles.chartLegend, { height }]}>
|
||||
<Text style={label.number}>
|
||||
{cycleDayNumber ? cycleDayNumber : ' '}
|
||||
</Text>
|
||||
|
||||
@@ -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 (
|
||||
<TouchableOpacity
|
||||
@@ -98,17 +102,17 @@ class DayColumn extends Component {
|
||||
isSymptomDataComplete={
|
||||
hasSymptomData && isSymptomDataComplete(symptom, dateString)
|
||||
}
|
||||
height={this.props.symptomHeight}
|
||||
height={symptomHeight}
|
||||
/>)
|
||||
}
|
||||
)}
|
||||
|
||||
<TemperatureColumn
|
||||
{shouldShowTemperatureColumn && <TemperatureColumn
|
||||
horizontalLinePosition={this.fhmAndLtl.drawLtlAt}
|
||||
isVerticalLine={this.fhmAndLtl.drawFhmLine}
|
||||
data={this.data && this.data.temperature}
|
||||
columnHeight={columnHeight}
|
||||
/>
|
||||
/>}
|
||||
|
||||
<CycleDayLabel
|
||||
height={xAxisHeight}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { View } from 'react-native'
|
||||
|
||||
import AppText from '../app-text'
|
||||
import SettingsButton from '../settings/shared/settings-button'
|
||||
|
||||
import { shared } from '../../i18n/en/labels'
|
||||
import styles from './styles'
|
||||
|
||||
const NoData = ({ navigate }) => {
|
||||
return (
|
||||
<View flex={1}>
|
||||
<View style={styles.centerItem}>
|
||||
<AppText>{shared.noDataWarning}</AppText>
|
||||
<SettingsButton
|
||||
onPress={() => {navigate('CycleDay')}}
|
||||
style={{marginHorizontal: 40}}
|
||||
>
|
||||
{shared.noDataButtonText}
|
||||
</SettingsButton>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
NoData.propTypes = {
|
||||
navigate: PropTypes.func,
|
||||
}
|
||||
|
||||
export default NoData
|
||||
@@ -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',
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 (
|
||||
<View>
|
||||
<View style={[styles.yAxis, {height: symptomsSectionHeight}]}>
|
||||
@@ -22,8 +29,8 @@ const YAxis = ({ height, symptomsToDisplay, symptomsSectionHeight }) => {
|
||||
)
|
||||
)}
|
||||
</View>
|
||||
<TickList height={height} />
|
||||
<ChartLegend />
|
||||
{shouldShowTemperatureColumn && <TickList height={height} />}
|
||||
<ChartLegend xAxisHeight={xAxisHeight} />
|
||||
</View>
|
||||
)
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
+4
-1
@@ -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 = {
|
||||
|
||||
Reference in New Issue
Block a user