From 1e81cd8298abddbcff3d8acf73a0c46b4e929dd5 Mon Sep 17 00:00:00 2001 From: tina <lt-bloody@riox.eu> Date: Fri, 7 Sep 2018 19:32:45 +0200 Subject: [PATCH] every symptom has its own row --- components/chart/chart.js | 34 +++++++++++-- components/chart/day-column.js | 86 +++++++++++++++++++++++++------- components/chart/dot-and-line.js | 2 +- components/chart/styles.js | 9 ++-- components/chart/y-axis.js | 35 +++---------- config.js | 4 +- local-storage/index.js | 14 ++++++ 7 files changed, 125 insertions(+), 59 deletions(-) diff --git a/components/chart/chart.js b/components/chart/chart.js index 02489794..4f011bde 100644 --- a/components/chart/chart.js +++ b/components/chart/chart.js @@ -28,7 +28,6 @@ export default class CycleChart extends Component { onLayout = ({ nativeEvent }) => { if (this.state.chartHeight) return - const height = nativeEvent.layout.height this.setState({ chartHeight: height }) this.reCalculateChartInfo = () => { @@ -61,11 +60,38 @@ export default class CycleChart extends Component { jsDate.getDate() ).toString() }) + const chartSymptoms = [ + 'bleeding', + 'temperature', + 'mucus', + 'cervix', + 'sex', + 'desire', + 'pain', + 'note' + ].filter((symptomName) => { + return cycleDaysSortedByDate.some(cycleDay => cycleDay[symptomName]) + }) const columns = xAxisDates.map(dateString => { const cycleDay = getCycleDay(dateString) - const symptoms = ['temperature', 'mucus', 'bleeding'].reduce((acc, symptom) => { - acc[symptom] = cycleDay && cycleDay[symptom] && cycleDay[symptom].value + const symptoms = chartSymptoms.reduce((acc, symptom) => { + if (symptom === 'bleeding' || + symptom === 'temperature' || + symptom === 'mucus' || + symptom === 'desire' || + symptom === 'note' + ) { + acc[symptom] = cycleDay && cycleDay[symptom] && cycleDay[symptom].value + } else if (symptom === 'cervix') { + acc[symptom] = cycleDay && cycleDay['cervix'] && (cycleDay['cervix'].opening + cycleDay['cervix'].firmness) + } else if (symptom === 'sex') { + // solo = 1 + partner = 2 + acc[symptom] = cycleDay && cycleDay['sex'] && (cycleDay['sex'].solo + cycleDay['sex'].partner) + } else if (symptom === 'pain') { + // is any pain documented? + acc[symptom] = cycleDay && cycleDay['pain'] && Object.values(cycleDay['pain']).some(x => x === true) + } acc[`${symptom}Exclude`] = cycleDay && cycleDay[symptom] && cycleDay[symptom].exclude return acc }, {}) @@ -75,7 +101,7 @@ export default class CycleChart extends Component { return { dateString, y: temp ? normalizeToScale(temp, columnHeight) : null, - ...symptoms, + symptoms, ...getFhmAndLtlInfo(dateString, temp) } }) diff --git a/components/chart/day-column.js b/components/chart/day-column.js index f7012a98..790acda9 100644 --- a/components/chart/day-column.js +++ b/components/chart/day-column.js @@ -27,8 +27,7 @@ export default class DayColumn extends Component { dateString, y, temperatureExclude, - bleeding, - mucus, + symptoms, drawFhmLine, drawLtlAt, rightY, @@ -108,24 +107,73 @@ export default class DayColumn extends Component { return ( <View> - <View style={[styles.symptomRow, {height: symptomHeight}]}> - {typeof mucus === 'number' && - <View - {...styles.mucusIcon} - backgroundColor={styles.mucusIconShades[mucus]} - key='mucus' - /> - } - {typeof bleeding === 'number' && - <Icon - name='drop' - size={18} - color={styles.bleedingIconShades[bleeding]} - key='bleeding' - /> - } + <View height={symptomHeight}> + <View style={styles.symptomRow}> + {typeof symptoms.bleeding === 'number' && + <Icon + name='drop' + size={12} + color={styles.bleedingIconShades[symptoms.bleeding]} + key='bleeding' + /> + } + </View> + <View style={styles.symptomRow}> + {typeof symptoms.mucus === 'number' && + <View + {...styles.mucusIcon} + backgroundColor={styles.mucusIconShades[symptoms.mucus]} + key='mucus' + /> + } + </View> + <View style={styles.symptomRow}> + {typeof symptoms.cervix === 'number' && + <View + {...styles.mucusIcon} + // cervix is sum of openess and firmness - fertile only when closed and hard (=0) + backgroundColor={symptoms.cervix > 0 ? 'blue' : 'green'} + key='cervix' + /> + } + </View> + <View style={styles.symptomRow}> + {typeof symptoms.sex === 'number' && + <View + {...styles.mucusIcon} + backgroundColor={styles.mucusIconShades[symptoms.mucus]} + key='sex' + /> + } + </View> + <View style={styles.symptomRow}> + {typeof symptoms.desire === 'number' && + <View + {...styles.mucusIcon} + backgroundColor='red' + key='desire' + /> + } + </View> + <View style={styles.symptomRow}> + {symptoms.pain && + <View + {...styles.mucusIcon} + backgroundColor='blue' + key='pain' + /> + } + </View> + <View style={styles.symptomRow}> + {symptoms.note && + <View + {...styles.mucusIcon} + backgroundColor='green' + key='note' + /> + } + </View> </View> - {column} <View style={{height: xAxisHeight}}> diff --git a/components/chart/dot-and-line.js b/components/chart/dot-and-line.js index 418457f0..9d6daed3 100644 --- a/components/chart/dot-and-line.js +++ b/components/chart/dot-and-line.js @@ -41,7 +41,7 @@ export default class DotAndLine extends Component { function makeLine(leftY, rightY, direction, excludeLine) { const colWidth = config.columnWidth - const heightDiff = -leftY - -rightY + const heightDiff = -(leftY - rightY) const angle = Math.atan2(heightDiff, colWidth / 2) const lineStyle = excludeLine ? styles.curveExcluded : styles.curve // hypotenuse, we add 3px for good measure, because otherwise the lines diff --git a/components/chart/styles.js b/components/chart/styles.js index bffb407c..25b33be2 100644 --- a/components/chart/styles.js +++ b/components/chart/styles.js @@ -46,8 +46,7 @@ const styles = { rect: { width: config.columnWidth, borderStyle: 'solid', - borderLeftWidth: 0.5, - borderRightWidth: 0.5, + borderRightWidth: 0.25, } }, bleedingIcon: { @@ -85,7 +84,7 @@ const styles = { horizontalGrid: { position:'absolute', borderColor: 'lightgrey', - borderWidth: 0.5, + borderTopWidth: 0.25, width: '100%', borderStyle: 'solid', left: config.columnWidth @@ -97,7 +96,9 @@ const styles = { }, symptomRow: { alignItems: 'center', - justifyContent: 'center' + justifyContent: 'center', + width: '100%', + flex: 1 } } diff --git a/components/chart/y-axis.js b/components/chart/y-axis.js index ccdf02b1..074b18f7 100644 --- a/components/chart/y-axis.js +++ b/components/chart/y-axis.js @@ -2,34 +2,20 @@ import React from 'react' import { Text, View } from 'react-native' import config from '../../config' import styles from './styles' -import { scaleObservable } from '../../local-storage' +import { scaleObservable, unitObservable } from '../../local-storage' export function makeYAxisLabels(columnHeight) { - const units = config.temperatureScale.units + const units = unitObservable.value const scaleMax = scaleObservable.value.max - const scaleMin = scaleObservable.value.min const style = styles.yAxisLabel return getTickPositions(columnHeight).map((y, i) => { // this eyeballing is sadly necessary because RN does not // support percentage values for transforms, which we'd need // to reliably place the label vertically centered to the grid - let tickLabelDistance - let tickUnit - if (scaleMax - scaleMin <= 3) { - tickLabelDistance = 2 - tickUnit = 1 - } else if (scaleMax - scaleMin <= 5) { - tickLabelDistance = 2 - tickUnit = 2 - } else { - tickLabelDistance = 5 - tickUnit = 5 - } - if (scaleMax - i * tickUnit * units === 37) console.log(y) - const tick = scaleMax - i * tickUnit * units + const tick = scaleMax - i * units const tickLabel = tick * 10 % 10 ? tick.toString() : tick.toString() + '.0' - const showTick = tick * 10 % tickLabelDistance ? false : true + const showTick = (tick * 10 % 2) ? false : true const tickBold = tick * 10 % 5 ? {} : {fontWeight: 'bold'} return ( <Text @@ -54,19 +40,11 @@ export function makeHorizontalGrid(columnHeight, symptomRowHeight) { } function getTickPositions(columnHeight) { - const units = config.temperatureScale.units + const units = unitObservable.value const scaleMin = scaleObservable.value.min const scaleMax = scaleObservable.value.max const numberOfTicks = (scaleMax - scaleMin) * (1 / units) + 1 - let tickDistance - if (numberOfTicks <= 31) { - tickDistance = 1 / (numberOfTicks - 1) - } else if (numberOfTicks <= 51) { - tickDistance = 2 / (numberOfTicks - 1) - } else { - tickDistance = 5 / (numberOfTicks - 1) - } - + const tickDistance = 1 / (numberOfTicks - 1) const tickPositions = [] for (let i = 0; i < numberOfTicks; i++) { const position = getAbsoluteValue(tickDistance * i, columnHeight) @@ -86,5 +64,4 @@ function getAbsoluteValue(relative, columnHeight) { const verticalPadding = columnHeight * config.temperatureScale.verticalPadding const scaleHeight = columnHeight - 2 * verticalPadding return scaleHeight * relative + verticalPadding - } \ No newline at end of file diff --git a/config.js b/config.js index 772e8282..7cea4e1f 100644 --- a/config.js +++ b/config.js @@ -1,8 +1,8 @@ const config = { columnWidth: 25, - columnHeightPercentage: 0.84, + columnHeightPercentage: 0.62, xAxisHeightPercentage: 0.08, - symptomRowHeightPercentage: 0.08, + symptomRowHeightPercentage: 0.30, temperatureScale: { defaultLow: 35, defaultHigh: 38, diff --git a/local-storage/index.js b/local-storage/index.js index 62962711..ef1f7575 100644 --- a/local-storage/index.js +++ b/local-storage/index.js @@ -8,6 +8,20 @@ setObvWithInitValue('tempScale', scaleObservable, { max: config.temperatureScale.defaultHigh }) +export const unitObservable = Observable() +unitObservable.set(config.temperatureScale.units) +scaleObservable((scale) => { + const scaleRange = scale.max - scale.min + if (scaleRange <= 3) { + unitObservable.set(0.1) + } else if (scaleRange <= 5) { + unitObservable.set(0.2) + } else { + unitObservable.set(0.5) + } +}) + + export const tempReminderObservable = Observable() setObvWithInitValue('tempReminder', tempReminderObservable, { enabled: false -- GitLab