Skip to content
Snippets Groups Projects
Commit 8f6213e9 authored by Julia Friesel's avatar Julia Friesel
Browse files

Move column info production to column and do not get earlier cycles

parent 33fa429f
No related branches found
No related tags found
No related merge requests found
......@@ -3,10 +3,10 @@ import { View, FlatList } from 'react-native'
import range from 'date-range'
import { LocalDate } from 'js-joda'
import Svg, { G } from 'react-native-svg'
import { makeYAxisLabels, normalizeToScale, makeHorizontalGrid } from './y-axis'
import { makeYAxisLabels, makeHorizontalGrid } from './y-axis'
import nfpLines from './nfp-lines'
import DayColumn from './day-column'
import { getCycleDay, getCycleDaysSortedByDate, getAmountOfCycleDays } from '../../db'
import { getCycleDaysSortedByDate, getAmountOfCycleDays } from '../../db'
import styles from './styles'
import { scaleObservable } from '../../local-storage'
import config from '../../config'
......@@ -24,20 +24,24 @@ export default class CycleChart extends Component {
constructor(props) {
super(props)
this.state = {}
this.renderColumn = ({item, index}) => {
return (
<DayColumn
{...item}
index={index}
navigate={this.props.navigate}
symptomHeight={this.symptomHeight}
columnHeight={this.columnHeight}
chartHeight={this.state.chartHeight}
symptomRowSymptoms={this.symptomRowSymptoms}
/>
)
}
this.cycleDaysSortedByDate = getCycleDaysSortedByDate()
this.getFhmAndLtlInfo = nfpLines()
}
renderColumn = ({ item, index }) => {
return (
<DayColumn
dateString={item}
index={index}
navigate={this.props.navigate}
symptomHeight={this.symptomHeight}
columnHeight={this.columnHeight}
chartHeight={this.state.chartHeight}
symptomRowSymptoms={this.symptomRowSymptoms}
chartSymptoms={this.chartSymptoms}
getFhmAndLtlInfo={this.getFhmAndLtlInfo}
/>
)
}
onLayout = ({ nativeEvent }) => {
......@@ -67,12 +71,12 @@ export default class CycleChart extends Component {
this.symptomHeight
this.columnHeight = remainingHeight - this.symptomRowHeight
const chartSymptoms = [...this.symptomRowSymptoms]
this.chartSymptoms = [...this.symptomRowSymptoms]
if (this.cycleDaysSortedByDate.some(day => day.temperature)) {
chartSymptoms.push('temperature')
this.chartSymptoms.push('temperature')
}
const columnData = this.makeColumnInfo(nfpLines(), chartSymptoms)
const columnData = this.makeColumnInfo()
this.setState({ columns: columnData })
}
......@@ -85,7 +89,7 @@ export default class CycleChart extends Component {
this.removeObvListener()
}
makeColumnInfo(getFhmAndLtlInfo, chartSymptoms) {
makeColumnInfo() {
let amountOfCycleDays = getAmountOfCycleDays()
// if there's not much data yet, we want to show at least 30 days on the chart
if (amountOfCycleDays < 30) {
......@@ -95,59 +99,13 @@ export default class CycleChart extends Component {
amountOfCycleDays += 5
}
const jsDates = getTodayAndPreviousDays(amountOfCycleDays)
const xAxisDates = jsDates.map(jsDate => {
return jsDates.map(jsDate => {
return LocalDate.of(
jsDate.getFullYear(),
jsDate.getMonth() + 1,
jsDate.getDate()
).toString()
})
const columns = xAxisDates.map(dateString => {
const column = { dateString }
const cycleDay = getCycleDay(dateString)
let symptoms = {}
if (cycleDay) {
symptoms = chartSymptoms.reduce((acc, symptom) => {
if (symptom === 'bleeding' ||
symptom === 'temperature' ||
symptom === 'mucus' ||
symptom === 'desire' ||
symptom === 'note'
) {
acc[symptom] = cycleDay[symptom] && cycleDay[symptom].value
} else if (symptom === 'cervix') {
acc.cervix = cycleDay.cervix &&
(cycleDay.cervix.opening + cycleDay.cervix.firmness)
} else if (symptom === 'sex') {
// solo = 1 + partner = 2
acc.sex = cycleDay.sex &&
(cycleDay.sex.solo + 2 * cycleDay.sex.partner)
} else if (symptom === 'pain') {
// is any pain documented?
acc.pain = cycleDay.pain &&
Object.values(cycleDay.pain).some(x => x === true)
}
acc[`${symptom}Exclude`] = cycleDay[symptom] && cycleDay[symptom].exclude
return acc
}, {})
}
const temp = symptoms.temperature
if (temp) {
column.y = normalizeToScale(temp, this.columnHeight)
}
const fhmAndLtl = getFhmAndLtlInfo(dateString, temp, this.columnHeight)
return Object.assign(column, symptoms, fhmAndLtl)
})
return columns.map((col, i) => {
const info = getInfoForNeighborColumns(i, columns)
return Object.assign(col, info)
})
}
render() {
......@@ -217,9 +175,10 @@ export default class CycleChart extends Component {
showsHorizontalScrollIndicator={false}
data={this.state.columns}
renderItem={this.renderColumn}
keyExtractor={item => item.dateString}
keyExtractor={item => item}
initialNumToRender={15}
maxToRenderPerBatch={5}
windowSize={30}
onLayout={() => this.setState({chartLoaded: true})}
/>
}
......@@ -228,7 +187,6 @@ export default class CycleChart extends Component {
}
}
function getTodayAndPreviousDays(n) {
const today = new Date()
today.setHours(0)
......@@ -240,26 +198,6 @@ function getTodayAndPreviousDays(n) {
return range(earlierDate, today).reverse()
}
function getInfoForNeighborColumns(index, cols) {
const ret = {
rightY: null,
rightTemperatureExclude: null,
leftY: null,
leftTemperatureExclude: null
}
const right = index > 0 ? cols[index - 1] : undefined
const left = index < cols.length - 1 ? cols[index + 1] : undefined
if (right && right.y) {
ret.rightY = right.y
ret.rightTemperatureExclude = right.temperatureExclude
}
if (left && left.y) {
ret.leftY = left.y
ret.leftTemperatureExclude = left.temperatureExclude
}
return ret
}
const symptomIcons = {
'bleeding': {
'viewBox': '10 10 320 400',
......
......@@ -9,15 +9,55 @@ import styles from './styles'
import config from '../../config'
import { getOrCreateCycleDay } from '../../db'
import cycleModule from '../../lib/cycle'
import { getCycleDay } from '../../db'
import DotAndLine from './dot-and-line'
import { normalizeToScale } from './y-axis'
const label = styles.column.label
export default class DayColumn extends Component {
constructor() {
constructor(props) {
super()
const dateString = props.dateString
const columnHeight = props.columnHeight
this.getCycleDayNumber = cycleModule().getCycleDayNumber
const cycleDay = getCycleDay(dateString)
this.data = {}
if (cycleDay) {
this.data = props.chartSymptoms.reduce((acc, symptom) => {
if (['bleeding', 'temperature', 'mucus', 'desire', 'note'].includes(symptom)) {
acc[symptom] = cycleDay[symptom] && cycleDay[symptom].value
if (symptom === 'temperature' && acc.temperature) {
acc.y = normalizeToScale(acc.temperature, columnHeight)
const neighbor = getInfoForNeighborColumns(dateString, columnHeight)
for (const key in neighbor) {
acc[key] = neighbor[key]
}
}
} else if (symptom === 'cervix') {
acc.cervix = cycleDay.cervix &&
(cycleDay.cervix.opening + cycleDay.cervix.firmness)
} else if (symptom === 'sex') {
// solo = 1 + partner = 2
acc.sex = cycleDay.sex &&
(cycleDay.sex.solo + 2 * cycleDay.sex.partner)
} else if (symptom === 'pain') {
// is any pain documented?
acc.pain = cycleDay.pain &&
Object.values(cycleDay.pain).some(x => x === true)
}
acc[`${symptom}Exclude`] = cycleDay[symptom] && cycleDay[symptom].exclude
return acc
}, this.data)
}
this.fhmAndLtl = props.getFhmAndLtlInfo(
props.dateString,
props.temp,
props.columnHeight
)
}
passDateToDayView(dateString) {
const cycleDay = getOrCreateCycleDay(dateString)
this.props.navigate('CycleDay', { cycleDay })
......@@ -28,45 +68,29 @@ export default class DayColumn extends Component {
}
render() {
const {
dateString,
y,
temperatureExclude,
drawFhmLine,
drawLtlAt,
rightY,
rightTemperatureExclude,
leftY,
leftTemperatureExclude,
columnHeight,
symptomHeight,
chartHeight,
symptomRowSymptoms,
xAxisHeight
} = this.props
const columnElements = []
const dateString = this.props.dateString
const symptomHeight = this.props.symptomHeight
if(drawLtlAt) {
if(this.fhmAndLtl.drawLtlAt) {
const ltlLine = (<Line
x1={0}
y1={drawLtlAt}
y1={this.fhmAndLtl.drawLtlAt}
x2={config.columnWidth}
y2={drawLtlAt}
y2={this.fhmAndLtl.drawLtlAt}
{...styles.nfpLine}
key='ltl'
/>)
columnElements.push(ltlLine)
}
if (drawFhmLine) {
if (this.fhmAndLtl.drawFhmLine) {
const x = styles.nfpLine.strokeWidth / 2
const fhmLine = (<Line
x1={x}
y1={x}
x2={x}
y2={columnHeight}
y2={this.props.columnHeight}
{...styles.nfpLine}
key='fhm'
/>)
......@@ -74,15 +98,15 @@ export default class DayColumn extends Component {
}
if (y) {
if (this.data.y) {
columnElements.push(
<DotAndLine
y={y}
exclude={temperatureExclude}
rightY={rightY}
rightTemperatureExclude={rightTemperatureExclude}
leftY={leftY}
leftTemperatureExclude={leftTemperatureExclude}
y={this.data.y}
exclude={this.data.temperatureExclude}
rightY={this.data.rightY}
rightTemperatureExclude={this.data.rightTemperatureExclude}
leftY={this.data.leftY}
leftTemperatureExclude={this.data.leftTemperatureExclude}
key='dotandline'
/>
)
......@@ -108,7 +132,7 @@ export default class DayColumn extends Component {
const column = (
<G>
<Rect
height={chartHeight}
height={this.props.chartHeight}
{...styles.column.rect}
/>
{ columnElements }
......@@ -118,68 +142,71 @@ export default class DayColumn extends Component {
const symptomIconViews = {
bleeding: (
<SymptomIconView
value={this.props.bleeding}
value={this.data.bleeding}
symptomHeight={symptomHeight}
key='bleeding'
>
<View
{...styles.symptomIcon}
backgroundColor={styles.iconShades.bleeding[this.props.bleeding]}
backgroundColor={styles.iconShades.bleeding[this.data.bleeding]}
/>
</SymptomIconView>
),
mucus: (
<SymptomIconView
value={this.props.mucus}
value={this.data.mucus}
symptomHeight={symptomHeight}
key='mucus'
>
<View
{...styles.symptomIcon}
backgroundColor={styles.iconShades.mucus[this.props.mucus]}
backgroundColor={styles.iconShades.mucus[this.data.mucus]}
/>
</SymptomIconView>
),
cervix: (
<SymptomIconView
value={this.props.cervix}
value={this.data.cervix}
symptomHeight={symptomHeight}
key='cervix'
>
<View
{...styles.symptomIcon}
// cervix is sum of openess and firmness - fertile only when closed and hard (=0)
backgroundColor={this.props.cervix > 0 ? styles.iconShades.cervix[2] : styles.iconShades.cervix[0]}
backgroundColor={this.data.cervix > 0 ?
styles.iconShades.cervix[2] :
styles.iconShades.cervix[0]
}
/>
</SymptomIconView>
),
sex: (
<SymptomIconView
value={this.props.sex}
value={this.data.sex}
symptomHeight={symptomHeight}
key='sex'
>
<View
{...styles.symptomIcon}
backgroundColor={styles.iconShades.sex[this.props.sex - 1]}
backgroundColor={styles.iconShades.sex[this.data.sex - 1]}
/>
</SymptomIconView>
),
desire: (
<SymptomIconView
value={this.props.desire}
value={this.data.desire}
symptomHeight={symptomHeight}
key='desire'
>
<View
{...styles.symptomIcon}
backgroundColor={styles.iconShades.desire[this.props.desire]}
backgroundColor={styles.iconShades.desire[this.data.desire]}
/>
</SymptomIconView>
),
pain: (
<SymptomIconView
value={this.props.pain}
value={this.data.pain}
symptomHeight={symptomHeight}
key='pain'
>
......@@ -191,7 +218,7 @@ export default class DayColumn extends Component {
),
note: (
<SymptomIconView
value={this.props.note}
value={this.data.note}
symptomHeight={symptomHeight}
key='note'
>
......@@ -209,14 +236,16 @@ export default class DayColumn extends Component {
activeOpacity={1}
>
<View>
{symptomRowSymptoms.map(symptomName => symptomIconViews[symptomName])}
{this.props.symptomRowSymptoms.map(symptomName => {
return symptomIconViews[symptomName]
})}
</View>
<Svg width={config.columnWidth} height={columnHeight}>
<Svg width={config.columnWidth} height={this.props.columnHeight}>
{column}
</Svg>
<View style={{height: xAxisHeight}}>
<View style={{height: this.props.xAxisHeight}}>
{cycleDayLabel}
{dateLabel}
</View>
......@@ -237,3 +266,26 @@ function SymptomIconView(props) {
)
}
function getInfoForNeighborColumns(dateString, columnHeight) {
const ret = {
rightY: null,
rightTemperatureExclude: null,
leftY: null,
leftTemperatureExclude: null
}
const target = LocalDate.parse(dateString)
const dayBefore = target.minusDays(1).toString()
const dayAfter = target.plusDays(1).toString()
const cycleDayBefore = getCycleDay(dayBefore)
const cycleDayAfter = getCycleDay(dayAfter)
if (cycleDayAfter && cycleDayAfter.temperature) {
ret.rightY = normalizeToScale(cycleDayAfter.temperature.value, columnHeight)
ret.rightTemperatureExclude = cycleDayAfter.temperature.exclude
}
if (cycleDayBefore && cycleDayBefore.temperature) {
ret.leftY = normalizeToScale(cycleDayBefore.temperature.value, columnHeight)
ret.leftTemperatureExclude = cycleDayBefore.temperature.exclude
}
return ret
}
......@@ -7,7 +7,12 @@ export default function () {
}
function updateCurrentCycle(dateString) {
cycle.status = getCycleStatusForDay(dateString)
// for the NFP lines, we don't care about potentially extending the
// preOvu phase, so we don't include all earlier cycles, as that is
// an expensive db operation at the moment
cycle.status = getCycleStatusForDay(
dateString, { excludeEarlierCycles: true }
)
if(!cycle.status) {
cycle.noMoreCycles = true
return
......
......@@ -21,7 +21,7 @@ export function getFertilityStatusStringForDay(dateString) {
return mapToString(phaseNameForDay, dateString, status)
}
export function getCycleStatusForDay(dateString) {
export function getCycleStatusForDay(dateString, opts = {}) {
const {
getCycleForDay,
getCyclesBefore,
......@@ -37,6 +37,8 @@ export function getCycleStatusForDay(dateString) {
if (previousCycle) {
cycleInfo.previousCycle = formatCycleForSympto(previousCycle)
}
if (previousCycle && !opts.excludeEarlierCycles) {
const earlierCycles = getCyclesBefore(previousCycle[0])
if (earlierCycles) {
cycleInfo.earlierCycles = earlierCycles.map(formatCycleForSympto)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment