From 53e22110540c237ab0200112fed09f9aa366dc54 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Fri, 10 Aug 2018 06:54:37 +0200 Subject: [PATCH 1/6] Remove ScrollView and make DayColumn component --- components/chart/chart.js | 100 ++++++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 43 deletions(-) diff --git a/components/chart/chart.js b/components/chart/chart.js index 79bea87..7a90b87 100644 --- a/components/chart/chart.js +++ b/components/chart/chart.js @@ -1,5 +1,5 @@ import React, { Component } from 'react' -import { Text as ReactNativeText, View, FlatList, ScrollView } from 'react-native' +import { Text as ReactNativeText, View, FlatList } from 'react-native' import range from 'date-range' import Svg,{ G, @@ -45,21 +45,36 @@ export default class CycleChart extends Component { this.props.navigation.navigate('cycleDay', { cycleDay }) } - placeHorizontalGrid() { - return yAxis.tickPositions.map(tick => { - return ( - - ) - }) + render() { + return ( + + {yAxis.labels} + { + const cols = this.state.columns + return ( + 0 ? cols[index - 1] : undefined } + leftNeighbor = {index < cols.length - 1 ? cols[index + 1] : undefined } + /> + ) + }} + keyExtractor={item => item.dateString} + initialNumToRender={20} + > + + + ) } +} +class DayColumn extends Component { makeDayColumn({ dateString, cycleDay, y }, index) { const cycleDayNumber = getCycleDayNumber(dateString) const label = styles.column.label @@ -116,16 +131,15 @@ export default class CycleChart extends Component { /> : null} {y ? - this.drawDotAndLines(y, cycleDay.temperature.exclude, index) + this.drawDotAndLines(y, cycleDay.temperature.exclude) : null} ) } - drawDotAndLines(currY, exclude, index) { + drawDotAndLines(currY, exclude) { let lineToRight let lineToLeft - const cols = this.state.columns function makeLine(otherColY, x, excludeLine) { const middleY = ((otherColY - currY) / 2) + currY @@ -141,18 +155,18 @@ export default class CycleChart extends Component { /> } - const thereIsADotToTheRight = index > 0 && cols[index - 1].y - const thereIsADotToTheLeft = index < cols.length - 1 && cols[index + 1].y + const thereIsADotToTheRight = this.props.rightNeighbor && this.props.rightNeighbor.y + const thereIsADotToTheLeft = this.props.leftNeighbor && this.props.leftNeighbor.y if (thereIsADotToTheRight) { - const otherDot = cols[index - 1] - const excludedLine = otherDot.cycleDay.temperature.exclude || exclude - lineToRight = makeLine(otherDot.y, config.columnWidth, excludedLine) + const neighbor = this.props.rightNeighbor + const excludedLine = neighbor.cycleDay.temperature.exclude || exclude + lineToRight = makeLine(neighbor.y, config.columnWidth, excludedLine) } if (thereIsADotToTheLeft) { - const otherDot = cols[index + 1] - const excludedLine = otherDot.cycleDay.temperature.exclude || exclude - lineToLeft = makeLine(otherDot.y, 0, excludedLine) + const neighbor = this.props.leftNeighbor + const excludedLine = neighbor.cycleDay.temperature.exclude || exclude + lineToLeft = makeLine(neighbor.y, 0, excludedLine) } const dotStyle = exclude ? styles.curveDotsExcluded : styles.curveDots @@ -167,26 +181,26 @@ export default class CycleChart extends Component { ) } + placeHorizontalGrid() { + return yAxis.tickPositions.map(tick => { + return ( + + ) + }) + } + render() { return ( - - {yAxis.labels} - { - return ( - - {this.makeDayColumn(item, index)} - - ) - }} - keyExtractor={item => item.dateString} - > - - + + {this.makeDayColumn(this.props.item, this.props.index)} + ) } } From 8b7beb517a4448846e2af309e9aa938d92f5cfcf Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Fri, 10 Aug 2018 08:16:38 +0200 Subject: [PATCH 2/6] Separate DayColumn components --- components/chart/chart.js | 272 +-------------------------------- components/chart/day-column.js | 145 ++++++++++++++++++ components/chart/nfp-lines.js | 78 ++++++++++ components/chart/y-axis.js | 56 +++++++ 4 files changed, 287 insertions(+), 264 deletions(-) create mode 100644 components/chart/day-column.js create mode 100644 components/chart/nfp-lines.js create mode 100644 components/chart/y-axis.js diff --git a/components/chart/chart.js b/components/chart/chart.js index 7a90b87..49ddaa1 100644 --- a/components/chart/chart.js +++ b/components/chart/chart.js @@ -1,24 +1,14 @@ import React, { Component } from 'react' -import { Text as ReactNativeText, View, FlatList } from 'react-native' +import { View, FlatList } from 'react-native' import range from 'date-range' -import Svg,{ - G, - Rect, - Text, - Circle, - Line, - Path -} from 'react-native-svg' import { LocalDate } from 'js-joda' -import { getCycleDay, getOrCreateCycleDay, cycleDaysSortedByDate } from '../../db' -import cycleModule from '../../lib/cycle' +import { yAxis, normalizeToScale } from './y-axis' +import DayColumn from './day-column' +import { getCycleDay, cycleDaysSortedByDate } from '../../db' import styles from './styles' import config from './config' -import { getCycleStatusForDay } from '../../lib/sympto-adapter' -const getCycleDayNumber = cycleModule().getCycleDayNumber - -const yAxis = makeYAxis(config) +const yAxisView = {yAxis.labels} export default class CycleChart extends Component { constructor(props) { @@ -40,15 +30,11 @@ export default class CycleChart extends Component { cycleDaysSortedByDate.removeListener(this.reCalculateChartInfo) } - passDateToDayView(dateString) { - const cycleDay = getOrCreateCycleDay(dateString) - this.props.navigation.navigate('cycleDay', { cycleDay }) - } render() { return ( - {yAxis.labels} + { yAxisView } 0 ? cols[index - 1] : undefined } leftNeighbor = {index < cols.length - 1 ? cols[index + 1] : undefined } + navigate={this.props.navigation.navigate} /> ) }} keyExtractor={item => item.dateString} - initialNumToRender={20} + initialNumToRender={15} > @@ -74,137 +61,6 @@ export default class CycleChart extends Component { } } -class DayColumn extends Component { - makeDayColumn({ dateString, cycleDay, y }, index) { - const cycleDayNumber = getCycleDayNumber(dateString) - const label = styles.column.label - const dateLabel = dateString.split('-').slice(1).join('-') - const getFhmAndLtlInfo = setUpFertilityStatusFunc() - const nfpLineInfo = getFhmAndLtlInfo(dateString, cycleDay) - - return ( - this.passDateToDayView(dateString)}> - - {nfpLineInfo.drawFhmLine ? - : null} - - {this.placeHorizontalGrid()} - - - {cycleDayNumber} - - - {dateLabel} - - - {cycleDay && cycleDay.bleeding ? - - : null} - - {nfpLineInfo.drawLtlAt ? - : null} - - {y ? - this.drawDotAndLines(y, cycleDay.temperature.exclude, index) - : null - } - {cycleDay && cycleDay.mucus ? - : null} - - {y ? - this.drawDotAndLines(y, cycleDay.temperature.exclude) - : null} - - ) - } - - drawDotAndLines(currY, exclude) { - let lineToRight - let lineToLeft - - function makeLine(otherColY, x, excludeLine) { - const middleY = ((otherColY - currY) / 2) + currY - const target = [x, middleY] - const lineStyle = excludeLine ? styles.curveExcluded : styles.curve - - return - } - - const thereIsADotToTheRight = this.props.rightNeighbor && this.props.rightNeighbor.y - const thereIsADotToTheLeft = this.props.leftNeighbor && this.props.leftNeighbor.y - - if (thereIsADotToTheRight) { - const neighbor = this.props.rightNeighbor - const excludedLine = neighbor.cycleDay.temperature.exclude || exclude - lineToRight = makeLine(neighbor.y, config.columnWidth, excludedLine) - } - if (thereIsADotToTheLeft) { - const neighbor = this.props.leftNeighbor - const excludedLine = neighbor.cycleDay.temperature.exclude || exclude - lineToLeft = makeLine(neighbor.y, 0, excludedLine) - } - - const dotStyle = exclude ? styles.curveDotsExcluded : styles.curveDots - return ( - {lineToRight} - {lineToLeft} - - ) - } - - placeHorizontalGrid() { - return yAxis.tickPositions.map(tick => { - return ( - - ) - }) - } - - render() { - return ( - - {this.makeDayColumn(this.props.item, this.props.index)} - - ) - } -} - function makeColumnInfo(n) { const xAxisDates = getPreviousDays(n).map(jsDate => { return LocalDate.of( @@ -234,116 +90,4 @@ function getPreviousDays(n) { const earlierDate = new Date(today - (range.DAY * n)) return range(earlierDate, today).reverse() -} - -function normalizeToScale(temp) { - const scale = config.temperatureScale - const valueRelativeToScale = (scale.high - temp) / (scale.high - scale.low) - const scaleHeight = config.chartHeight - return scaleHeight * valueRelativeToScale -} - -function makeYAxis() { - const scaleMin = config.temperatureScale.low - const scaleMax = config.temperatureScale.high - const numberOfTicks = (scaleMax - scaleMin) * 2 - const tickDistance = config.chartHeight / numberOfTicks - - const tickPositions = [] - const labels = [] - // for style reasons, we don't want the first and last tick - for (let i = 1; i < numberOfTicks - 1; i++) { - const y = tickDistance * i - const style = styles.yAxisLabel - // 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 - style.top = y - 8 - labels.push( - - {scaleMax - i * 0.5} - - ) - tickPositions.push(y) - } - - return {labels, tickPositions} -} - -function setUpFertilityStatusFunc() { - let cycleStatus - let cycleStartDate - let noMoreCycles = false - - function updateCurrentCycle(dateString) { - cycleStatus = getCycleStatusForDay(dateString) - if(!cycleStatus) { - noMoreCycles = true - return - } - if (cycleStatus.phases.preOvulatory) { - cycleStartDate = cycleStatus.phases.preOvulatory.start.date - } else { - cycleStartDate = cycleStatus.phases.periOvulatory.start.date - } - } - - function dateIsInPeriOrPostPhase(dateString) { - return ( - dateString >= cycleStatus.phases.periOvulatory.start.date - ) - } - - function precededByAnotherTempValue(dateString) { - return ( - // we are only interested in days that have a preceding - // temp - Object.keys(cycleStatus.phases).some(phaseName => { - return cycleStatus.phases[phaseName].cycleDays.some(day => { - return day.temperature && day.date < dateString - }) - }) - // and also a following temp, so we don't draw the line - // longer than necessary - && - cycleStatus.phases.postOvulatory.cycleDays.some(day => { - return day.temperature && day.date > dateString - }) - ) - } - - function isInTempMeasuringPhase(cycleDay, dateString) { - return ( - cycleDay && cycleDay.temperature - || precededByAnotherTempValue(dateString) - ) - } - - return function(dateString, cycleDay) { - const ret = {} - if (!cycleStatus && !noMoreCycles) updateCurrentCycle(dateString) - if (noMoreCycles) return ret - - if (dateString < cycleStartDate) updateCurrentCycle(dateString) - if (noMoreCycles) return ret - - const tempShift = cycleStatus.temperatureShift - - if (tempShift) { - if (tempShift.firstHighMeasurementDay.date === dateString) { - ret.drawFhmLine = true - } - - if ( - dateIsInPeriOrPostPhase(dateString) && - isInTempMeasuringPhase(cycleDay, dateString) - ) { - ret.drawLtlAt = normalizeToScale(tempShift.ltl) - } - } - - return ret - } } \ No newline at end of file diff --git a/components/chart/day-column.js b/components/chart/day-column.js new file mode 100644 index 0000000..1b9b2f1 --- /dev/null +++ b/components/chart/day-column.js @@ -0,0 +1,145 @@ +import React, { Component } from 'react' +import Svg,{ + G, + Rect, + Text, + Circle, + Line, + Path +} from 'react-native-svg' +import styles from './styles' +import config from './config' +import { getOrCreateCycleDay } from '../../db' +import cycleModule from '../../lib/cycle' +import setUpFertilityStatusFunc from './nfp-lines' +import { horizontalGrid } from './y-axis' + +const getCycleDayNumber = cycleModule().getCycleDayNumber + +export default class DayColumn extends Component { + makeDayColumn({ dateString, cycleDay, y }, index) { + const cycleDayNumber = getCycleDayNumber(dateString) + const label = styles.column.label + const dateLabel = dateString.split('-').slice(1).join('-') + const getFhmAndLtlInfo = setUpFertilityStatusFunc() + const nfpLineInfo = getFhmAndLtlInfo(dateString, cycleDay) + + return ( + this.passDateToDayView(dateString)}> + + {horizontalGrid} + {nfpLineInfo.drawFhmLine ? + : null} + + + + {cycleDayNumber} + + + {dateLabel} + + + {cycleDay && cycleDay.bleeding ? + + : null} + + {nfpLineInfo.drawLtlAt ? + : null} + + {y ? + this.drawDotAndLines(y, cycleDay.temperature.exclude, index) + : null + } + {cycleDay && cycleDay.mucus ? + : null} + + {y ? + this.drawDotAndLines(y, cycleDay.temperature.exclude) + : null} + + ) + } + + drawDotAndLines(currY, exclude) { + let lineToRight + let lineToLeft + + function makeLine(otherColY, x, excludeLine) { + const middleY = ((otherColY - currY) / 2) + currY + const target = [x, middleY] + const lineStyle = excludeLine ? styles.curveExcluded : styles.curve + + return + } + + const thereIsADotToTheRight = this.props.rightNeighbor && this.props.rightNeighbor.y + const thereIsADotToTheLeft = this.props.leftNeighbor && this.props.leftNeighbor.y + + if (thereIsADotToTheRight) { + const neighbor = this.props.rightNeighbor + const excludedLine = neighbor.cycleDay.temperature.exclude || exclude + lineToRight = makeLine(neighbor.y, config.columnWidth, excludedLine) + } + if (thereIsADotToTheLeft) { + const neighbor = this.props.leftNeighbor + const excludedLine = neighbor.cycleDay.temperature.exclude || exclude + lineToLeft = makeLine(neighbor.y, 0, excludedLine) + } + + const dotStyle = exclude ? styles.curveDotsExcluded : styles.curveDots + return ( + {lineToRight} + {lineToLeft} + + ) + } + + + passDateToDayView(dateString) { + const cycleDay = getOrCreateCycleDay(dateString) + this.props.navigate('cycleDay', { cycleDay }) + } + + shouldComponentUpdate() { + // for now, until we've solved the mysterious re-rendering + return false + } + + render() { + console.log(this.props.index) + return ( + + {this.makeDayColumn(this.props.item, this.props.index)} + + ) + } +} \ No newline at end of file diff --git a/components/chart/nfp-lines.js b/components/chart/nfp-lines.js new file mode 100644 index 0000000..e091597 --- /dev/null +++ b/components/chart/nfp-lines.js @@ -0,0 +1,78 @@ +import { getCycleStatusForDay } from '../../lib/sympto-adapter' +import { normalizeToScale } from './y-axis' + +export default function () { + let cycleStatus + let cycleStartDate + let noMoreCycles = false + + function updateCurrentCycle(dateString) { + cycleStatus = getCycleStatusForDay(dateString) + if(!cycleStatus) { + noMoreCycles = true + return + } + if (cycleStatus.phases.preOvulatory) { + cycleStartDate = cycleStatus.phases.preOvulatory.start.date + } else { + cycleStartDate = cycleStatus.phases.periOvulatory.start.date + } + } + + function dateIsInPeriOrPostPhase(dateString) { + return ( + dateString >= cycleStatus.phases.periOvulatory.start.date + ) + } + + function precededByAnotherTempValue(dateString) { + return ( + // we are only interested in days that have a preceding + // temp + Object.keys(cycleStatus.phases).some(phaseName => { + return cycleStatus.phases[phaseName].cycleDays.some(day => { + return day.temperature && day.date < dateString + }) + }) + // and also a following temp, so we don't draw the line + // longer than necessary + && + cycleStatus.phases.postOvulatory.cycleDays.some(day => { + return day.temperature && day.date > dateString + }) + ) + } + + function isInTempMeasuringPhase(cycleDay, dateString) { + return ( + cycleDay && cycleDay.temperature + || precededByAnotherTempValue(dateString) + ) + } + + return function(dateString, cycleDay) { + const ret = {} + if (!cycleStatus && !noMoreCycles) updateCurrentCycle(dateString) + if (noMoreCycles) return ret + + if (dateString < cycleStartDate) updateCurrentCycle(dateString) + if (noMoreCycles) return ret + + const tempShift = cycleStatus.temperatureShift + + if (tempShift) { + if (tempShift.firstHighMeasurementDay.date === dateString) { + ret.drawFhmLine = true + } + + if ( + dateIsInPeriOrPostPhase(dateString) && + isInTempMeasuringPhase(cycleDay, dateString) + ) { + ret.drawLtlAt = normalizeToScale(tempShift.ltl) + } + } + + return ret + } +} \ No newline at end of file diff --git a/components/chart/y-axis.js b/components/chart/y-axis.js new file mode 100644 index 0000000..0e9179a --- /dev/null +++ b/components/chart/y-axis.js @@ -0,0 +1,56 @@ +import React from 'react' +import { Text as ReactNativeText } from 'react-native' +import { Line } from 'react-native-svg' +import config from './config' +import styles from './styles' + +function makeYAxis() { + const scaleMin = config.temperatureScale.low + const scaleMax = config.temperatureScale.high + const numberOfTicks = (scaleMax - scaleMin) * 2 + const tickDistance = config.chartHeight / numberOfTicks + + const tickPositions = [] + const labels = [] + // for style reasons, we don't want the first and last tick + for (let i = 1; i < numberOfTicks - 1; i++) { + const y = tickDistance * i + const style = styles.yAxisLabel + // 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 + style.top = y - 8 + labels.push( + + {scaleMax - i * 0.5} + + ) + tickPositions.push(y) + } + + return {labels, tickPositions} +} + +export const yAxis = makeYAxis() + +export const horizontalGrid = yAxis.tickPositions.map(tick => { + return ( + + ) +}) + +export function normalizeToScale(temp) { + const scale = config.temperatureScale + const valueRelativeToScale = (scale.high - temp) / (scale.high - scale.low) + const scaleHeight = config.chartHeight + return scaleHeight * valueRelativeToScale +} \ No newline at end of file From 93a7ba853f8058f9cbf699b971daab1076ea5ef7 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Fri, 10 Aug 2018 11:32:50 +0200 Subject: [PATCH 3/6] Make props flat and try recyclerView --- components/chart/chart.js | 84 ++++++++++++++++++++++++---------- components/chart/day-column.js | 10 +++- components/chart/nfp-lines.js | 9 ++-- package.json | 1 + 4 files changed, 73 insertions(+), 31 deletions(-) diff --git a/components/chart/chart.js b/components/chart/chart.js index 49ddaa1..ffc311f 100644 --- a/components/chart/chart.js +++ b/components/chart/chart.js @@ -1,5 +1,6 @@ import React, { Component } from 'react' -import { View, FlatList } from 'react-native' +import { View } from 'react-native' +import { RecyclerListView, DataProvider, LayoutProvider } from "recyclerlistview" import range from 'date-range' import { LocalDate } from 'js-joda' import { yAxis, normalizeToScale } from './y-axis' @@ -10,12 +11,53 @@ import config from './config' const yAxisView = {yAxis.labels} +const dataProvider = new DataProvider((a,b) => { + return Object.keys(a).some(key => a[key] != b[key]) +}) + +const layoutProvider = new LayoutProvider( + () => DayColumn, + (_, item) => { + item.height = config.chartHeight + item.width = config.columnWidth + return item + } +) + +function getInfoForNeighborColumns(index, cols) { + const ret = {} + 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 +} + +function rowRenderer (_, item, index) { + return ( + + ) +} + export default class CycleChart extends Component { constructor(props) { super(props) + this.columns = makeColumnInfo(config.xAxisRangeInDays) this.state = { - columns: makeColumnInfo(config.xAxisRangeInDays) + dataProvider: dataProvider.cloneWithRows(this.columns) } + this.rowRenderer = rowRenderer.bind(this) this.reCalculateChartInfo = (function(Chart) { return function() { @@ -35,34 +77,21 @@ export default class CycleChart extends Component { return ( { yAxisView } - { - const cols = this.state.columns - return ( - 0 ? cols[index - 1] : undefined } - leftNeighbor = {index < cols.length - 1 ? cols[index + 1] : undefined } - navigate={this.props.navigation.navigate} - /> - ) - }} - keyExtractor={item => item.dateString} + - + ) } } function makeColumnInfo(n) { - const xAxisDates = getPreviousDays(n).map(jsDate => { + const xAxisDates = getPreviousDays(n).reverse().map(jsDate => { return LocalDate.of( jsDate.getFullYear(), jsDate.getMonth() + 1, @@ -72,11 +101,16 @@ function makeColumnInfo(n) { return xAxisDates.map(dateString => { const cycleDay = getCycleDay(dateString) - const temp = cycleDay && cycleDay.temperature && cycleDay.temperature.value + const symptoms = ['temperature', 'mucus', 'bleeding'].reduce((acc, symptom) => { + acc[symptom] = cycleDay && cycleDay[symptom] && cycleDay[symptom].value + acc[`${symptom}Exclude`] = cycleDay && cycleDay[symptom] && cycleDay[symptom].exclude + return acc + }, {}) + return { dateString, - cycleDay, - y: temp ? normalizeToScale(temp) : null + y: symptoms.temperature ? normalizeToScale(symptoms.temperature) : null, + ...symptoms } }) } diff --git a/components/chart/day-column.js b/components/chart/day-column.js index 1b9b2f1..2fda961 100644 --- a/components/chart/day-column.js +++ b/components/chart/day-column.js @@ -17,7 +17,15 @@ import { horizontalGrid } from './y-axis' const getCycleDayNumber = cycleModule().getCycleDayNumber export default class DayColumn extends Component { - makeDayColumn({ dateString, cycleDay, y }, index) { + makeDayColumn(data, index) { + const { + dateString, + y, + temperature, + temperatureExclude, + bleeding, + mucus + } = data const cycleDayNumber = getCycleDayNumber(dateString) const label = styles.column.label const dateLabel = dateString.split('-').slice(1).join('-') diff --git a/components/chart/nfp-lines.js b/components/chart/nfp-lines.js index e091597..a58abc0 100644 --- a/components/chart/nfp-lines.js +++ b/components/chart/nfp-lines.js @@ -43,14 +43,13 @@ export default function () { ) } - function isInTempMeasuringPhase(cycleDay, dateString) { + function isInTempMeasuringPhase(temperature, dateString) { return ( - cycleDay && cycleDay.temperature - || precededByAnotherTempValue(dateString) + temperature || precededByAnotherTempValue(dateString) ) } - return function(dateString, cycleDay) { + return function(dateString, temperature) { const ret = {} if (!cycleStatus && !noMoreCycles) updateCurrentCycle(dateString) if (noMoreCycles) return ret @@ -67,7 +66,7 @@ export default function () { if ( dateIsInPeriOrPostPhase(dateString) && - isInTempMeasuringPhase(cycleDay, dateString) + isInTempMeasuringPhase(temperature, dateString) ) { ret.drawLtlAt = normalizeToScale(tempShift.ltl) } diff --git a/package.json b/package.json index 217d5ff..d54f08b 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "react-native-svg": "^6.3.1", "react-navigation": "^2.0.4", "realm": "^2.7.1", + "recyclerlistview": "^1.3.4", "uuid": "^3.2.1" }, "devDependencies": { From 611e9057b4903cc88c3aac825b6011d6e461e791 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Fri, 10 Aug 2018 13:17:51 +0200 Subject: [PATCH 4/6] Back to FlatList and try loading screen --- components/chart/chart.js | 75 ++++++++++++++++------------------ components/chart/config.js | 4 +- components/chart/day-column.js | 47 +++++++++++---------- package-lock.json | 5 +++ package.json | 2 +- 5 files changed, 66 insertions(+), 67 deletions(-) diff --git a/components/chart/chart.js b/components/chart/chart.js index ffc311f..604966e 100644 --- a/components/chart/chart.js +++ b/components/chart/chart.js @@ -1,6 +1,5 @@ import React, { Component } from 'react' -import { View } from 'react-native' -import { RecyclerListView, DataProvider, LayoutProvider } from "recyclerlistview" +import { View, FlatList, Dimensions } from 'react-native' import range from 'date-range' import { LocalDate } from 'js-joda' import { yAxis, normalizeToScale } from './y-axis' @@ -11,19 +10,6 @@ import config from './config' const yAxisView = {yAxis.labels} -const dataProvider = new DataProvider((a,b) => { - return Object.keys(a).some(key => a[key] != b[key]) -}) - -const layoutProvider = new LayoutProvider( - () => DayColumn, - (_, item) => { - item.height = config.chartHeight - item.width = config.columnWidth - return item - } -) - function getInfoForNeighborColumns(index, cols) { const ret = {} const right = index > 0 ? cols[index - 1] : undefined @@ -39,25 +25,24 @@ function getInfoForNeighborColumns(index, cols) { return ret } -function rowRenderer (_, item, index) { - return ( - - ) -} - export default class CycleChart extends Component { constructor(props) { super(props) - this.columns = makeColumnInfo(config.xAxisRangeInDays) this.state = { - dataProvider: dataProvider.cloneWithRows(this.columns) + columns: makeColumnInfo(config.xAxisRangeInDays), + loading: true + } + this.renderColumn = ({item, index}) => { + if (index === 15 + 1 && this.state.loading) this.setState({loading: false}) + return ( + + ) } - this.rowRenderer = rowRenderer.bind(this) this.reCalculateChartInfo = (function(Chart) { return function() { @@ -74,24 +59,34 @@ export default class CycleChart extends Component { render() { + const {height, width} = Dimensions.get('window') return ( - - { yAxisView } - - + + {this.state.loading && + } + + {yAxisView} + item.dateString} + > + + ) } } function makeColumnInfo(n) { - const xAxisDates = getPreviousDays(n).reverse().map(jsDate => { + const xAxisDates = getPreviousDays(n).map(jsDate => { return LocalDate.of( jsDate.getFullYear(), jsDate.getMonth() + 1, diff --git a/components/chart/config.js b/components/chart/config.js index d18c722..e9d5f95 100644 --- a/components/chart/config.js +++ b/components/chart/config.js @@ -2,10 +2,10 @@ const config = { chartHeight: 350, columnWidth: 30, temperatureScale: { - low: 33, + low: 35, high: 40 }, - xAxisRangeInDays: 40 + xAxisRangeInDays: 50 } const margin = 3 diff --git a/components/chart/day-column.js b/components/chart/day-column.js index 2fda961..a24899a 100644 --- a/components/chart/day-column.js +++ b/components/chart/day-column.js @@ -13,10 +13,17 @@ import { getOrCreateCycleDay } from '../../db' import cycleModule from '../../lib/cycle' import setUpFertilityStatusFunc from './nfp-lines' import { horizontalGrid } from './y-axis' +import slowlog from 'react-native-slowlog' const getCycleDayNumber = cycleModule().getCycleDayNumber +const label = styles.column.label export default class DayColumn extends Component { + constructor(props) { + super(props) + this.getFhmAndLtlInfo = setUpFertilityStatusFunc() + // slowlog(this, /.*/) + } makeDayColumn(data, index) { const { dateString, @@ -27,10 +34,9 @@ export default class DayColumn extends Component { mucus } = data const cycleDayNumber = getCycleDayNumber(dateString) - const label = styles.column.label const dateLabel = dateString.split('-').slice(1).join('-') - const getFhmAndLtlInfo = setUpFertilityStatusFunc() - const nfpLineInfo = getFhmAndLtlInfo(dateString, cycleDay) + // const nfpLineInfo = this.getFhmAndLtlInfo(dateString, temperature) + const nfpLineInfo = {} return ( this.passDateToDayView(dateString)}> @@ -53,7 +59,7 @@ export default class DayColumn extends Component { {dateLabel} - {cycleDay && cycleDay.bleeding ? + {bleeding ? Date: Fri, 10 Aug 2018 13:26:34 +0200 Subject: [PATCH 5/6] Remove loading screen again --- components/chart/chart.js | 37 +++++++++++++------------------------ 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/components/chart/chart.js b/components/chart/chart.js index 604966e..6e7da68 100644 --- a/components/chart/chart.js +++ b/components/chart/chart.js @@ -1,5 +1,5 @@ import React, { Component } from 'react' -import { View, FlatList, Dimensions } from 'react-native' +import { View, FlatList } from 'react-native' import range from 'date-range' import { LocalDate } from 'js-joda' import { yAxis, normalizeToScale } from './y-axis' @@ -29,11 +29,9 @@ export default class CycleChart extends Component { constructor(props) { super(props) this.state = { - columns: makeColumnInfo(config.xAxisRangeInDays), - loading: true + columns: makeColumnInfo(config.xAxisRangeInDays) } this.renderColumn = ({item, index}) => { - if (index === 15 + 1 && this.state.loading) this.setState({loading: false}) return ( - {this.state.loading && - } - - {yAxisView} - item.dateString} - > - - + + {yAxisView} + item.dateString} + > + ) } From b3e2ce0ea743fb6d6ce3e9b32f3f43c0ec862179 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Fri, 10 Aug 2018 15:26:41 +0200 Subject: [PATCH 6/6] Fix bug: Don't produce closure for every item --- components/chart/chart.js | 2 ++ components/chart/day-column.js | 7 +++---- components/chart/nfp-lines.js | 36 +++++++++++++++++----------------- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/components/chart/chart.js b/components/chart/chart.js index 6e7da68..8a91920 100644 --- a/components/chart/chart.js +++ b/components/chart/chart.js @@ -67,6 +67,8 @@ export default class CycleChart extends Component { data={this.state.columns} renderItem={this.renderColumn} keyExtractor={item => item.dateString} + initialNumToRender={15} + maxToRenderPerBatch={5} > diff --git a/components/chart/day-column.js b/components/chart/day-column.js index a24899a..bb6e834 100644 --- a/components/chart/day-column.js +++ b/components/chart/day-column.js @@ -17,12 +17,12 @@ import slowlog from 'react-native-slowlog' const getCycleDayNumber = cycleModule().getCycleDayNumber const label = styles.column.label +const getFhmAndLtlInfo = setUpFertilityStatusFunc() export default class DayColumn extends Component { constructor(props) { super(props) - this.getFhmAndLtlInfo = setUpFertilityStatusFunc() - // slowlog(this, /.*/) + slowlog(this, /.*/) } makeDayColumn(data, index) { const { @@ -35,8 +35,7 @@ export default class DayColumn extends Component { } = data const cycleDayNumber = getCycleDayNumber(dateString) const dateLabel = dateString.split('-').slice(1).join('-') - // const nfpLineInfo = this.getFhmAndLtlInfo(dateString, temperature) - const nfpLineInfo = {} + const nfpLineInfo = getFhmAndLtlInfo(dateString, temperature) return ( this.passDateToDayView(dateString)}> diff --git a/components/chart/nfp-lines.js b/components/chart/nfp-lines.js index a58abc0..e5265ac 100644 --- a/components/chart/nfp-lines.js +++ b/components/chart/nfp-lines.js @@ -2,26 +2,26 @@ import { getCycleStatusForDay } from '../../lib/sympto-adapter' import { normalizeToScale } from './y-axis' export default function () { - let cycleStatus - let cycleStartDate - let noMoreCycles = false + const cycle = { + status: null + } function updateCurrentCycle(dateString) { - cycleStatus = getCycleStatusForDay(dateString) - if(!cycleStatus) { - noMoreCycles = true + cycle.status = getCycleStatusForDay(dateString) + if(!cycle.status) { + cycle.noMoreCycles = true return } - if (cycleStatus.phases.preOvulatory) { - cycleStartDate = cycleStatus.phases.preOvulatory.start.date + if (cycle.status.phases.preOvulatory) { + cycle.startDate = cycle.status.phases.preOvulatory.start.date } else { - cycleStartDate = cycleStatus.phases.periOvulatory.start.date + cycle.startDate = cycle.status.phases.periOvulatory.start.date } } function dateIsInPeriOrPostPhase(dateString) { return ( - dateString >= cycleStatus.phases.periOvulatory.start.date + dateString >= cycle.status.phases.periOvulatory.start.date ) } @@ -29,15 +29,15 @@ export default function () { return ( // we are only interested in days that have a preceding // temp - Object.keys(cycleStatus.phases).some(phaseName => { - return cycleStatus.phases[phaseName].cycleDays.some(day => { + Object.keys(cycle.status.phases).some(phaseName => { + return cycle.status.phases[phaseName].cycleDays.some(day => { return day.temperature && day.date < dateString }) }) // and also a following temp, so we don't draw the line // longer than necessary && - cycleStatus.phases.postOvulatory.cycleDays.some(day => { + cycle.status.phases.postOvulatory.cycleDays.some(day => { return day.temperature && day.date > dateString }) ) @@ -51,13 +51,13 @@ export default function () { return function(dateString, temperature) { const ret = {} - if (!cycleStatus && !noMoreCycles) updateCurrentCycle(dateString) - if (noMoreCycles) return ret + if (!cycle.status && !cycle.noMoreCycles) updateCurrentCycle(dateString) + if (cycle.noMoreCycles) return ret - if (dateString < cycleStartDate) updateCurrentCycle(dateString) - if (noMoreCycles) return ret + if (dateString < cycle.startDate) updateCurrentCycle(dateString) + if (cycle.noMoreCycles) return ret - const tempShift = cycleStatus.temperatureShift + const tempShift = cycle.status.temperatureShift if (tempShift) { if (tempShift.firstHighMeasurementDay.date === dateString) {