diff --git a/android/app/build.gradle b/android/app/build.gradle
index 9c525a6..d82743d 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -151,6 +151,7 @@ android {
dependencies {
compile project(':nodejs-mobile-react-native')
compile project(':react-native-restart')
+ compile project(':react-native-svg')
compile project(':react-native-push-notification')
compile project(':react-native-vector-icons')
compile project(':react-native-fs')
diff --git a/android/app/src/main/java/com/drip/MainApplication.java b/android/app/src/main/java/com/drip/MainApplication.java
index dc83fe7..bbf0a07 100644
--- a/android/app/src/main/java/com/drip/MainApplication.java
+++ b/android/app/src/main/java/com/drip/MainApplication.java
@@ -5,6 +5,7 @@ import android.app.Application;
import com.facebook.react.ReactApplication;
import com.janeasystems.rn_nodejs_mobile.RNNodeJsMobilePackage;
import com.avishayil.rnrestart.ReactNativeRestartPackage;
+import com.horcrux.svg.SvgPackage;
import com.dieam.reactnativepushnotification.ReactNativePushNotificationPackage;
import com.oblador.vectoricons.VectorIconsPackage;
import com.rnfs.RNFSPackage;
@@ -34,6 +35,7 @@ public class MainApplication extends Application implements ReactApplication, Sh
new MainReactPackage(),
new RNNodeJsMobilePackage(),
new ReactNativeRestartPackage(),
+ new SvgPackage(),
new ReactNativePushNotificationPackage(),
new VectorIconsPackage(),
new RNFSPackage(),
diff --git a/android/settings.gradle b/android/settings.gradle
index 327fbe1..05a2c69 100644
--- a/android/settings.gradle
+++ b/android/settings.gradle
@@ -3,6 +3,8 @@ include ':nodejs-mobile-react-native'
project(':nodejs-mobile-react-native').projectDir = new File(rootProject.projectDir, '../node_modules/nodejs-mobile-react-native/android')
include ':react-native-restart'
project(':react-native-restart').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-restart/android')
+include ':react-native-svg'
+project(':react-native-svg').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-svg/android')
include ':react-native-push-notification'
project(':react-native-push-notification').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-push-notification/android')
include ':react-native-vector-icons'
diff --git a/components/chart/chart.js b/components/chart/chart.js
index ddd8d00..4ee6dd6 100644
--- a/components/chart/chart.js
+++ b/components/chart/chart.js
@@ -33,7 +33,7 @@ export default class CycleChart extends Component {
const height = nativeEvent.layout.height
this.setState({ chartHeight: height })
this.reCalculateChartInfo = () => {
- this.setState({ columns: this.makeColumnInfo(nfpLines(height)) })
+ this.setState({ columns: this.makeColumnInfo(nfpLines()) })
}
this.cycleDaysSortedByDate.addListener(this.reCalculateChartInfo)
@@ -62,6 +62,7 @@ export default class CycleChart extends Component {
jsDate.getDate()
).toString()
})
+
const chartSymptoms = [
'bleeding',
'temperature',
@@ -103,8 +104,8 @@ export default class CycleChart extends Component {
return {
dateString,
y: temp ? normalizeToScale(temp, columnHeight) : null,
- symptoms,
- ...getFhmAndLtlInfo(dateString, temp)
+ ...symptoms,
+ ...getFhmAndLtlInfo(dateString, temp, columnHeight)
}
})
diff --git a/components/chart/day-column.js b/components/chart/day-column.js
index e541ab0..0e64d88 100644
--- a/components/chart/day-column.js
+++ b/components/chart/day-column.js
@@ -2,6 +2,7 @@ import React, { Component } from 'react'
import {
Text, View, TouchableOpacity
} from 'react-native'
+import Svg,{ G, Rect, Line } from 'react-native-svg'
import Icon from 'react-native-vector-icons/Entypo'
import styles from './styles'
import config from '../../config'
@@ -30,7 +31,6 @@ export default class DayColumn extends Component {
dateString,
y,
temperatureExclude,
- symptoms,
drawFhmLine,
drawLtlAt,
rightY,
@@ -47,16 +47,31 @@ export default class DayColumn extends Component {
const columnElements = []
if(drawLtlAt) {
- const ltlLine = ()
columnElements.push(ltlLine)
}
+ if (drawFhmLine) {
+ const x = styles.nfpLine.strokeWidth / 2
+ const fhmLine = ()
+ columnElements.push(fhmLine)
+ }
+
+
if (y) {
columnElements.push(
)
- // we merge the colors here instead of from the stylesheet because of a RN
- // bug that doesn't apply borderLeftColor otherwise
- const potentialCustomStyle = {
- height: columnHeight,
- borderLeftColor: 'grey',
- }
-
- if (drawFhmLine) {
- potentialCustomStyle.borderLeftColor = styles.nfpLine.borderColor
- potentialCustomStyle.borderLeftWidth = 3
- }
- const column = React.createElement(
- TouchableOpacity,
- {
- style: [styles.column.rect, potentialCustomStyle],
- key: this.props.index.toString(),
- onPress: () => {
- this.passDateToDayView(dateString)
- },
- activeOpacity: 1
- },
- columnElements
+ const column = (
+
+
+ { columnElements }
+
)
return (
-
+ this.passDateToDayView(dateString)}
+ activeOpacity={1}
+ >
- {typeof symptoms.bleeding === 'number' &&
+ {typeof this.props.bleeding === 'number' &&
}
- {typeof symptoms.mucus === 'number' &&
+ {typeof this.props.mucus === 'number' &&
}
- {typeof symptoms.cervix === 'number' &&
+ {typeof this.props.cervix === 'number' &&
0 ? 'blue' : 'green'}
+ backgroundColor={this.props.cervix > 0 ? 'blue' : 'green'}
key='cervix'
/>
}
- {typeof symptoms.sex === 'number' &&
+ {typeof this.props.sex === 'number' &&
- {typeof symptoms.desire === 'number' &&
+ {typeof this.props.desire === 'number' &&
- {symptoms.pain &&
+ {this.props.pain &&
- {symptoms.note &&
+ {this.props.note &&
- {column}
+
+
{cycleDayLabel}
{dateLabel}
-
+
)
}
}
diff --git a/components/chart/dot-and-line.js b/components/chart/dot-and-line.js
index 9d6daed..4d49008 100644
--- a/components/chart/dot-and-line.js
+++ b/components/chart/dot-and-line.js
@@ -1,5 +1,6 @@
import React, { Component } from 'react'
-import { View } from 'react-native'
+import { Circle, Line } from 'react-native-svg'
+
import styles from './styles'
import config from '../../config'
@@ -17,21 +18,20 @@ export default class DotAndLine extends Component {
if (this.props.leftY) {
const middleY = ((this.props.leftY - y) / 2) + y
const excludedLine = this.props.leftTemperatureExclude || exclude
- lineToLeft = makeLine(middleY, y, 'left', excludedLine)
+ lineToLeft = makeLine(y, middleY, 0, excludedLine)
}
if (this.props.rightY) {
const middleY = ((y - this.props.rightY) / 2) + this.props.rightY
const excludedLine = this.props.rightTemperatureExclude || exclude
- lineToRight = makeLine(y, middleY, 'right', excludedLine)
+ lineToRight = makeLine(y, middleY, config.columnWidth, excludedLine)
}
const dotStyle = exclude ? styles.curveDotsExcluded : styles.curveDots
const dot = (
-
)
@@ -39,33 +39,15 @@ export default class DotAndLine extends Component {
}
}
-function makeLine(leftY, rightY, direction, excludeLine) {
- const colWidth = config.columnWidth
- const heightDiff = -(leftY - rightY)
- const angle = Math.atan2(heightDiff, colWidth / 2)
+function makeLine(currY, middleY, x, excludeLine) {
const lineStyle = excludeLine ? styles.curveExcluded : styles.curve
- // hypotenuse, we add 3px for good measure, because otherwise the lines
- // don't quite touch at the day border
- const h = (colWidth / 2) / Math.cos(angle) + 10
- // the rotation by default rotates from the middle of the line,
- // but we want the transform origin to be at its beginning
- // react native doesn't have transformOrigin, so we do this manually
- // if it's the right line, we put the pivot at 3/4 of the column
- // if it's to the left, at 1/4
- const pivot = direction === 'right' ? colWidth / 4 : -(colWidth / 4)
- const projectedX = -(h - colWidth) / 2 + pivot
- return ()
+ key={x.toString()}
+ />
}
\ No newline at end of file
diff --git a/components/chart/nfp-lines.js b/components/chart/nfp-lines.js
index ded95e8..51842d5 100644
--- a/components/chart/nfp-lines.js
+++ b/components/chart/nfp-lines.js
@@ -1,7 +1,7 @@
import { getCycleStatusForDay } from '../../lib/sympto-adapter'
import { normalizeToScale } from './y-axis'
-export default function (chartHeight) {
+export default function () {
const cycle = {
status: null
}
@@ -49,7 +49,7 @@ export default function (chartHeight) {
)
}
- return function(dateString, temperature) {
+ return function(dateString, temperature, columnHeight) {
const ret = {
drawLtlAt: null,
drawFhmLine: false
@@ -71,7 +71,7 @@ export default function (chartHeight) {
dateIsInPeriOrPostPhase(dateString) &&
isInTempMeasuringPhase(temperature, dateString)
) {
- ret.drawLtlAt = normalizeToScale(tempShift.ltl, chartHeight)
+ ret.drawLtlAt = normalizeToScale(tempShift.ltl, columnHeight)
}
}
diff --git a/components/chart/styles.js b/components/chart/styles.js
index 56cede6..318fd54 100644
--- a/components/chart/styles.js
+++ b/components/chart/styles.js
@@ -3,32 +3,28 @@ import {primaryColor, shadesOfRed} from '../../styles/index'
const colorTemperature = '#765285'
const colorTemperatureLight = '#a67fb5'
-const dotWidth = 10
-const lineWidth = 2
+const dotRadius = 5
+const lineWidth = 1.5
const colorLtl = '#feb47b'
+const gridColor = 'lightgrey'
+const gridLineWidth = 0.5
const styles = {
curve: {
- borderStyle: 'solid',
- borderColor: colorTemperature,
- borderWidth: lineWidth,
+ stroke: colorTemperature,
+ strokeWidth: lineWidth,
},
curveExcluded: {
- borderColor: colorTemperatureLight,
- borderWidth: lineWidth,
- borderStyle: 'dotted'
+ stroke: colorTemperatureLight,
+ strokeWidth: lineWidth
},
curveDots: {
- backgroundColor: colorTemperature,
- width: dotWidth,
- height: dotWidth,
- borderRadius: 50
+ fill: colorTemperature,
+ r: dotRadius
},
curveDotsExcluded: {
- backgroundColor: colorTemperatureLight,
- width: dotWidth,
- height: dotWidth,
- borderRadius: 50
+ fill: colorTemperatureLight,
+ r: dotRadius
},
column: {
label: {
@@ -44,9 +40,12 @@ const styles = {
}
},
rect: {
+ x:'0',
+ y:'0',
width: config.columnWidth,
- borderStyle: 'solid',
- borderLeftWidth: 0.5,
+ stroke: gridColor,
+ strokeWidth: gridLineWidth,
+ fill: 'transparent'
}
},
bleedingIcon: {
@@ -83,16 +82,15 @@ const styles = {
},
horizontalGrid: {
position:'absolute',
- borderColor: 'lightgrey',
- borderWidth: 0.5,
+ borderColor: gridColor,
+ borderWidth: gridLineWidth,
width: '100%',
borderStyle: 'solid',
left: config.columnWidth
},
nfpLine: {
- borderColor: colorLtl,
- borderWidth: lineWidth,
- borderStyle: 'solid'
+ stroke: colorLtl,
+ strokeWidth: lineWidth,
},
symptomRow: {
alignItems: 'center',
diff --git a/ios/drip.xcodeproj/project.pbxproj b/ios/drip.xcodeproj/project.pbxproj
index 34660c7..c6a9665 100644
--- a/ios/drip.xcodeproj/project.pbxproj
+++ b/ios/drip.xcodeproj/project.pbxproj
@@ -64,6 +64,8 @@
8EA186B6112C41D1B206762D /* NodeMobile.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C225FC4966694B9FBD32E946 /* NodeMobile.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
E4584E55EEC24302A3E84A23 /* nodejs-project in Resources */ = {isa = PBXBuildFile; fileRef = 6466AE2461BE4FA88B8372F0 /* nodejs-project */; };
A16B351C3F3644CF95F104D2 /* builtin_modules in Resources */ = {isa = PBXBuildFile; fileRef = 36F1B55D0DEE47AA9AF4BBDD /* builtin_modules */; };
+ 45794BEC42E34672A759220F /* libRNSVG.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 93C745A8EE95400C96FD5CF7 /* libRNSVG.a */; };
+ 3E63FB3C405F4AF39969C7E3 /* libRNSVG-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AD4FC2FD95A84EFCBB59195F /* libRNSVG-tvOS.a */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -402,6 +404,9 @@
C225FC4966694B9FBD32E946 /* NodeMobile.framework */ = {isa = PBXFileReference; name = "NodeMobile.framework"; path = "../node_modules/nodejs-mobile-react-native/ios/NodeMobile.framework"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = wrapper.framework; explicitFileType = undefined; includeInIndex = 0; };
6466AE2461BE4FA88B8372F0 /* nodejs-project */ = {isa = PBXFileReference; name = "nodejs-project"; path = "../nodejs-assets/nodejs-project"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
36F1B55D0DEE47AA9AF4BBDD /* builtin_modules */ = {isa = PBXFileReference; name = "builtin_modules"; path = "../node_modules/nodejs-mobile-react-native/install/resources/nodejs-modules/builtin_modules"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
+ DEB488BF9A9642508320FB42 /* RNSVG.xcodeproj */ = {isa = PBXFileReference; name = "RNSVG.xcodeproj"; path = "../node_modules/react-native-svg/ios/RNSVG.xcodeproj"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; };
+ 93C745A8EE95400C96FD5CF7 /* libRNSVG.a */ = {isa = PBXFileReference; name = "libRNSVG.a"; path = "libRNSVG.a"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
+ AD4FC2FD95A84EFCBB59195F /* libRNSVG-tvOS.a */ = {isa = PBXFileReference; name = "libRNSVG-tvOS.a"; path = "libRNSVG-tvOS.a"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -440,6 +445,7 @@
72DA6B4241504DB096AFAD40 /* libRCTRestart.a in Frameworks */,
E09F3B05A4F84E9883101CC7 /* libRNNodeJsMobile.a in Frameworks */,
E43EF009AC8C4698AB322190 /* NodeMobile.framework in Frameworks */,
+ 45794BEC42E34672A759220F /* libRNSVG.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -456,6 +462,7 @@
2D02E4C71E0B4AEC006451C7 /* libRCTText-tvOS.a in Frameworks */,
2D02E4C81E0B4AEC006451C7 /* libRCTWebSocket-tvOS.a in Frameworks */,
934282049FA3497D9062CEC1 /* libRNSVG-tvOS.a in Frameworks */,
+ 3E63FB3C405F4AF39969C7E3 /* libRNSVG-tvOS.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -637,6 +644,7 @@
49089E09BFCF4F3DB209B6E9 /* RNFS.xcodeproj */,
50DBC4BCDDF74A10AEDC99D5 /* RCTRestart.xcodeproj */,
65F706FAFA1444AE9937D472 /* RNNodeJsMobile.xcodeproj */,
+ DEB488BF9A9642508320FB42 /* RNSVG.xcodeproj */,
);
name = Libraries;
sourceTree = "";
@@ -1482,6 +1490,7 @@ fi
"$(inherited)",
"\"../node_modules/nodejs-mobile-react-native/ios\"",
"\"../node_modules/nodejs-mobile-react-native/ios\"",
+ "$(SRCROOT)/../node_modules/react-native-svg/ios/**",
);
ENABLE_BITCODE = NO;
};
@@ -1523,6 +1532,7 @@ fi
"$(inherited)",
"\"../node_modules/nodejs-mobile-react-native/ios\"",
"\"../node_modules/nodejs-mobile-react-native/ios\"",
+ "$(SRCROOT)/../node_modules/react-native-svg/ios/**",
);
ENABLE_BITCODE = NO;
};
@@ -1552,6 +1562,7 @@ fi
"$(SRCROOT)/../node_modules/react-native-fs/**",
"$(SRCROOT)/../node_modules/react-native-restart/ios/RCTRestart/**",
"$(SRCROOT)/../node_modules/nodejs-mobile-react-native/ios/**",
+ "$(SRCROOT)/../node_modules/react-native-svg/ios/**",
);
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -1584,6 +1595,7 @@ fi
"$(SRCROOT)/../node_modules/react-native-fs/**",
"$(SRCROOT)/../node_modules/react-native-restart/ios/RCTRestart/**",
"$(SRCROOT)/../node_modules/nodejs-mobile-react-native/ios/**",
+ "$(SRCROOT)/../node_modules/react-native-svg/ios/**",
);
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -1638,6 +1650,7 @@ fi
"$(inherited)",
"\"../node_modules/nodejs-mobile-react-native/ios\"",
"\"../node_modules/nodejs-mobile-react-native/ios\"",
+ "$(SRCROOT)/../node_modules/react-native-svg/ios/**",
);
ENABLE_BITCODE = NO;
};
@@ -1688,6 +1701,7 @@ fi
"$(inherited)",
"\"../node_modules/nodejs-mobile-react-native/ios\"",
"\"../node_modules/nodejs-mobile-react-native/ios\"",
+ "$(SRCROOT)/../node_modules/react-native-svg/ios/**",
);
ENABLE_BITCODE = NO;
};
@@ -1732,6 +1746,7 @@ fi
"$(SRCROOT)/../node_modules/react-native-fs/**",
"$(SRCROOT)/../node_modules/react-native-restart/ios/RCTRestart/**",
"$(SRCROOT)/../node_modules/nodejs-mobile-react-native/ios/**",
+ "$(SRCROOT)/../node_modules/react-native-svg/ios/**",
);
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -1781,6 +1796,7 @@ fi
"$(SRCROOT)/../node_modules/react-native-fs/**",
"$(SRCROOT)/../node_modules/react-native-restart/ios/RCTRestart/**",
"$(SRCROOT)/../node_modules/nodejs-mobile-react-native/ios/**",
+ "$(SRCROOT)/../node_modules/react-native-svg/ios/**",
);
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
diff --git a/package-lock.json b/package-lock.json
index 26216ec..fa9d4d5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2566,6 +2566,15 @@
"object-visit": "^1.0.0"
}
},
+ "color": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color/-/color-2.0.1.tgz",
+ "integrity": "sha512-ubUCVVKfT7r2w2D3qtHakj8mbmKms+tThR8gI8zEYCbUBl8/voqFGt3kgBqGwXAopgXybnkuOq+qMYCRrp4cXw==",
+ "requires": {
+ "color-convert": "^1.9.1",
+ "color-string": "^1.5.2"
+ }
+ },
"color-convert": {
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz",
@@ -2579,6 +2588,15 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz",
"integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok="
},
+ "color-string": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz",
+ "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==",
+ "requires": {
+ "color-name": "^1.0.0",
+ "simple-swizzle": "^0.2.2"
+ }
+ },
"color-support": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
@@ -6650,6 +6668,16 @@
"resolved": "https://registry.npmjs.org/react-native-share/-/react-native-share-1.1.0.tgz",
"integrity": "sha512-uQXo+HzZGUo9VlfgfWwGa9vLrY9OBQOFAsxhH/e3GWAlCxrGGjXNu/La+aJzMJdhoHzzn1+NRWDp1LWvlxJHew=="
},
+ "react-native-svg": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-7.0.2.tgz",
+ "integrity": "sha512-vDHePF9sSPp3s+AmAkk4HBvgWHdlaH5ns1mCAcrPqTiyF1QsApAtp3/3AHh8G8o57F2eJjEQ7LrRFNYyQPUBEw==",
+ "requires": {
+ "color": "^2.0.1",
+ "lodash": "^4.16.6",
+ "pegjs": "^0.10.0"
+ }
+ },
"react-native-vector-icons": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-5.0.0.tgz",
@@ -7577,6 +7605,21 @@
}
}
},
+ "simple-swizzle": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+ "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
+ "requires": {
+ "is-arrayish": "^0.3.1"
+ },
+ "dependencies": {
+ "is-arrayish": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
+ "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
+ }
+ }
+ },
"slash": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
diff --git a/package.json b/package.json
index 035ca51..0fff50d 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
"react-native-push-notification": "^3.1.1",
"react-native-restart": "0.0.7",
"react-native-share": "^1.1.0",
+ "react-native-svg": "^7.0.2",
"react-native-vector-icons": "^5.0.0",
"realm": "^2.7.1"
},