}
123 | BottomAxisLabel={() => }
124 | />
125 | ```
126 |
127 | ### `Range`
128 |
129 |
130 |
131 | Used to define a range for the graph canvas
132 |
133 | This range has to be bigger than the span of the provided data points. This feature can be used, e.g. if the graph should show a fixed timeframe, whether there's data for that period or not.
134 |
135 |
136 |
137 |
138 | This example shows data in the timeframe between 01/01/2000 to 01/31/2000 and caps the value between 0 and 200:
139 |
140 | ```jsx
141 |
160 | ```
161 |
162 | ---
163 |
164 | ### `SelectionDot`
165 |
166 |
167 |
168 | Used to render the selection dot.
169 |
170 | > Requires `animated` and `enablePanGesture` to be `true`.
171 |
172 | If `SelectionDot` is missing or `undefined`, a default one is provided with an outer ring and light shadow.
173 |
174 | Example:
175 |
176 | ```jsx
177 |
184 | ```
185 |
186 | See this [example ` ` component](./example/src/components/CustomSelectionDot.tsx).
187 |
188 | ## Sponsor
189 |
190 |
191 |
192 | **react-native-graph** is sponsored by [Pink Panda](https://pinkpanda.io).
193 |
194 | Download the Pink Panda mobile app to see react-native-graph in action!
195 |
196 | ## Community Discord
197 |
198 | [Join the Margelo Community Discord](https://discord.gg/6CSHz2qAvA) to chat about react-native-graph or other Margelo libraries.
199 |
200 | ## Adopting at scale
201 |
202 | react-native-graph was built at Margelo, an elite app development agency. For enterprise support or other business inquiries, contact us at hello@margelo.io !
203 |
204 | ## Thanks
205 |
206 | Special thanks to [William Candillon](https://github.com/wcandillon) and [Christian Falch](https://github.com/chrfalch) for their amazing help and support for React Native Skia ❤️
207 |
--------------------------------------------------------------------------------
/example/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
4 | ruby '>= 2.6.10'
5 |
6 | gem 'cocoapods', '>= 1.11.3'
7 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # Example App Setup
2 |
3 | Want to try our react-native-graph right away? Check out the example app.
4 |
5 | ## Steps to get the example app working on iOS
6 |
7 | 1. `git clone` this repo
8 | 2. `yarn install` in both the `/example` folder and in the top level.
9 | 3. In the `example` folder, `npx pod-install` or `cd ios && pod install` to install iOS dependencies
10 | 4. In the `example` folder, run `yarn ios`
11 |
--------------------------------------------------------------------------------
/example/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.application"
2 | apply plugin: "com.facebook.react"
3 |
4 | import com.android.build.OutputFile
5 |
6 | /**
7 | * This is the configuration block to customize your React Native Android app.
8 | * By default you don't need to apply any configuration, just uncomment the lines you need.
9 | */
10 | react {
11 | /* Folders */
12 | // The root of your project, i.e. where "package.json" lives. Default is '..'
13 | // root = file("../")
14 | // The folder where the react-native NPM package is. Default is ../node_modules/react-native
15 | // reactNativeDir = file("../node_modules/react-native")
16 | // The folder where the react-native Codegen package is. Default is ../node_modules/react-native-codegen
17 | // codegenDir = file("../node_modules/react-native-codegen")
18 | // The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js
19 | // cliFile = file("../node_modules/react-native/cli.js")
20 |
21 | /* Variants */
22 | // The list of variants to that are debuggable. For those we're going to
23 | // skip the bundling of the JS bundle and the assets. By default is just 'debug'.
24 | // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants.
25 | // debuggableVariants = ["liteDebug", "prodDebug"]
26 |
27 | /* Bundling */
28 | // A list containing the node command and its flags. Default is just 'node'.
29 | // nodeExecutableAndArgs = ["node"]
30 | //
31 | // The command to run when bundling. By default is 'bundle'
32 | // bundleCommand = "ram-bundle"
33 | //
34 | // The path to the CLI configuration file. Default is empty.
35 | // bundleConfig = file(../rn-cli.config.js)
36 | //
37 | // The name of the generated asset file containing your JS bundle
38 | // bundleAssetName = "MyApplication.android.bundle"
39 | //
40 | // The entry file for bundle generation. Default is 'index.android.js' or 'index.js'
41 | // entryFile = file("../js/MyApplication.android.js")
42 | //
43 | // A list of extra flags to pass to the 'bundle' commands.
44 | // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle
45 | // extraPackagerArgs = []
46 |
47 | /* Hermes Commands */
48 | // The hermes compiler command to run. By default it is 'hermesc'
49 | // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc"
50 | //
51 | // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
52 | // hermesFlags = ["-O", "-output-source-map"]
53 | }
54 |
55 | /**
56 | * Set this to true to create four separate APKs instead of one,
57 | * one for each native architecture. This is useful if you don't
58 | * use App Bundles (https://developer.android.com/guide/app-bundle/)
59 | * and want to have separate APKs to upload to the Play Store.
60 | */
61 | def enableSeparateBuildPerCPUArchitecture = false
62 |
63 | /**
64 | * Set this to true to Run Proguard on Release builds to minify the Java bytecode.
65 | */
66 | def enableProguardInReleaseBuilds = false
67 |
68 | /**
69 | * The preferred build flavor of JavaScriptCore (JSC)
70 | *
71 | * For example, to use the international variant, you can use:
72 | * `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
73 | *
74 | * The international variant includes ICU i18n library and necessary data
75 | * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
76 | * give correct results when using with locales other than en-US. Note that
77 | * this variant is about 6MiB larger per architecture than default.
78 | */
79 | def jscFlavor = 'org.webkit:android-jsc:+'
80 |
81 | /**
82 | * Private function to get the list of Native Architectures you want to build.
83 | * This reads the value from reactNativeArchitectures in your gradle.properties
84 | * file and works together with the --active-arch-only flag of react-native run-android.
85 | */
86 | def reactNativeArchitectures() {
87 | def value = project.getProperties().get("reactNativeArchitectures")
88 | return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
89 | }
90 |
91 | android {
92 | ndkVersion rootProject.ext.ndkVersion
93 |
94 | compileSdkVersion rootProject.ext.compileSdkVersion
95 |
96 | namespace "com.example.reactnativegraph"
97 | defaultConfig {
98 | applicationId "com.example.reactnativegraph"
99 | minSdkVersion rootProject.ext.minSdkVersion
100 | targetSdkVersion rootProject.ext.targetSdkVersion
101 | versionCode 1
102 | versionName "1.0"
103 | }
104 |
105 | splits {
106 | abi {
107 | reset()
108 | enable enableSeparateBuildPerCPUArchitecture
109 | universalApk false // If true, also generate a universal APK
110 | include (*reactNativeArchitectures())
111 | }
112 | }
113 | signingConfigs {
114 | debug {
115 | storeFile file('debug.keystore')
116 | storePassword 'android'
117 | keyAlias 'androiddebugkey'
118 | keyPassword 'android'
119 | }
120 | }
121 | buildTypes {
122 | debug {
123 | signingConfig signingConfigs.debug
124 | }
125 | release {
126 | // Caution! In production, you need to generate your own keystore file.
127 | // see https://reactnative.dev/docs/signed-apk-android.
128 | signingConfig signingConfigs.debug
129 | minifyEnabled enableProguardInReleaseBuilds
130 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
131 | }
132 | }
133 |
134 | // applicationVariants are e.g. debug, release
135 | applicationVariants.all { variant ->
136 | variant.outputs.each { output ->
137 | // For each separate APK per architecture, set a unique version code as described here:
138 | // https://developer.android.com/studio/build/configure-apk-splits.html
139 | // Example: versionCode 1 will generate 1001 for armeabi-v7a, 1002 for x86, etc.
140 | def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
141 | def abi = output.getFilter(OutputFile.ABI)
142 | if (abi != null) { // null for the universal-debug, universal-release variants
143 | output.versionCodeOverride =
144 | defaultConfig.versionCode * 1000 + versionCodes.get(abi)
145 | }
146 |
147 | }
148 | }
149 | }
150 |
151 | dependencies {
152 | // The version of react-native is set by the React Native Gradle Plugin
153 | implementation("com.facebook.react:react-android")
154 |
155 | implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.0.0")
156 |
157 | debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}")
158 | debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
159 | exclude group:'com.squareup.okhttp3', module:'okhttp'
160 | }
161 |
162 | debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}")
163 | if (hermesEnabled.toBoolean()) {
164 | implementation("com.facebook.react:hermes-android")
165 | } else {
166 | implementation jscFlavor
167 | }
168 | }
169 |
170 | apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
171 |
--------------------------------------------------------------------------------
/example/android/app/debug.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/margelo/react-native-graph/388b3e6bac7fc175fdb99f32defea0d3d271e8ac/example/android/app/debug.keystore
--------------------------------------------------------------------------------
/example/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
--------------------------------------------------------------------------------
/example/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
9 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/example/android/app/src/debug/java/com/example/reactnativegraph/ReactNativeFlipper.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Meta Platforms, Inc. and affiliates.
3 | *
4 | * This source code is licensed under the MIT license found in the LICENSE file in the root
5 | * directory of this source tree.
6 | */
7 | package com.example.reactnativegraph;
8 |
9 | import android.content.Context;
10 | import com.facebook.flipper.android.AndroidFlipperClient;
11 | import com.facebook.flipper.android.utils.FlipperUtils;
12 | import com.facebook.flipper.core.FlipperClient;
13 | import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin;
14 | import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin;
15 | import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin;
16 | import com.facebook.flipper.plugins.inspector.DescriptorMapping;
17 | import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
18 | import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
19 | import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
20 | import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
21 | import com.facebook.react.ReactInstanceEventListener;
22 | import com.facebook.react.ReactInstanceManager;
23 | import com.facebook.react.bridge.ReactContext;
24 | import com.facebook.react.modules.network.NetworkingModule;
25 | import okhttp3.OkHttpClient;
26 |
27 | /**
28 | * Class responsible of loading Flipper inside your React Native application. This is the debug
29 | * flavor of it. Here you can add your own plugins and customize the Flipper setup.
30 | */
31 | public class ReactNativeFlipper {
32 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
33 | if (FlipperUtils.shouldEnableFlipper(context)) {
34 | final FlipperClient client = AndroidFlipperClient.getInstance(context);
35 |
36 | client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
37 | client.addPlugin(new DatabasesFlipperPlugin(context));
38 | client.addPlugin(new SharedPreferencesFlipperPlugin(context));
39 | client.addPlugin(CrashReporterPlugin.getInstance());
40 |
41 | NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
42 | NetworkingModule.setCustomClientBuilder(
43 | new NetworkingModule.CustomClientBuilder() {
44 | @Override
45 | public void apply(OkHttpClient.Builder builder) {
46 | builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
47 | }
48 | });
49 | client.addPlugin(networkFlipperPlugin);
50 | client.start();
51 |
52 | // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
53 | // Hence we run if after all native modules have been initialized
54 | ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
55 | if (reactContext == null) {
56 | reactInstanceManager.addReactInstanceEventListener(
57 | new ReactInstanceEventListener() {
58 | @Override
59 | public void onReactContextInitialized(ReactContext reactContext) {
60 | reactInstanceManager.removeReactInstanceEventListener(this);
61 | reactContext.runOnNativeModulesQueueThread(
62 | new Runnable() {
63 | @Override
64 | public void run() {
65 | client.addPlugin(new FrescoFlipperPlugin());
66 | }
67 | });
68 | }
69 | });
70 | } else {
71 | client.addPlugin(new FrescoFlipperPlugin());
72 | }
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
13 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/com/example/reactnativegraph/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.reactnativegraph;
2 |
3 | import com.facebook.react.ReactActivity;
4 | import com.facebook.react.ReactActivityDelegate;
5 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
6 | import com.facebook.react.defaults.DefaultReactActivityDelegate;
7 |
8 | public class MainActivity extends ReactActivity {
9 |
10 | /**
11 | * Returns the name of the main component registered from JavaScript. This is used to schedule
12 | * rendering of the component.
13 | */
14 | @Override
15 | protected String getMainComponentName() {
16 | return "GraphExample";
17 | }
18 |
19 | /**
20 | * Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link
21 | * DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent React
22 | * (aka React 18) with two boolean flags.
23 | */
24 | @Override
25 | protected ReactActivityDelegate createReactActivityDelegate() {
26 | return new DefaultReactActivityDelegate(
27 | this,
28 | getMainComponentName(),
29 | // If you opted-in for the New Architecture, we enable the Fabric Renderer.
30 | DefaultNewArchitectureEntryPoint.getFabricEnabled(), // fabricEnabled
31 | // If you opted-in for the New Architecture, we enable Concurrent React (i.e. React 18).
32 | DefaultNewArchitectureEntryPoint.getConcurrentReactEnabled() // concurrentRootEnabled
33 | );
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/com/example/reactnativegraph/MainApplication.java:
--------------------------------------------------------------------------------
1 | package com.example.reactnativegraph;
2 |
3 | import android.app.Application;
4 | import com.facebook.react.PackageList;
5 | import com.facebook.react.ReactApplication;
6 | import com.facebook.react.ReactNativeHost;
7 | import com.facebook.react.ReactPackage;
8 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
9 | import com.facebook.react.defaults.DefaultReactNativeHost;
10 | import com.facebook.soloader.SoLoader;
11 | import java.util.List;
12 |
13 | public class MainApplication extends Application implements ReactApplication {
14 |
15 | private final ReactNativeHost mReactNativeHost =
16 | new DefaultReactNativeHost(this) {
17 | @Override
18 | public boolean getUseDeveloperSupport() {
19 | return BuildConfig.DEBUG;
20 | }
21 |
22 | @Override
23 | protected List getPackages() {
24 | @SuppressWarnings("UnnecessaryLocalVariable")
25 | List packages = new PackageList(this).getPackages();
26 | // Packages that cannot be autolinked yet can be added manually here, for example:
27 | // packages.add(new MyReactNativePackage());
28 | return packages;
29 | }
30 |
31 | @Override
32 | protected String getJSMainModuleName() {
33 | return "index";
34 | }
35 |
36 | @Override
37 | protected boolean isNewArchEnabled() {
38 | return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
39 | }
40 |
41 | @Override
42 | protected Boolean isHermesEnabled() {
43 | return BuildConfig.IS_HERMES_ENABLED;
44 | }
45 | };
46 |
47 | @Override
48 | public ReactNativeHost getReactNativeHost() {
49 | return mReactNativeHost;
50 | }
51 |
52 | @Override
53 | public void onCreate() {
54 | super.onCreate();
55 | SoLoader.init(this, /* native exopackage */ false);
56 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
57 | // If you opted-in for the New Architecture, we load the native entry point for this app.
58 | DefaultNewArchitectureEntryPoint.load();
59 | }
60 | ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable/rn_edit_text_material.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
21 |
22 |
23 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/margelo/react-native-graph/388b3e6bac7fc175fdb99f32defea0d3d271e8ac/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/margelo/react-native-graph/388b3e6bac7fc175fdb99f32defea0d3d271e8ac/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/margelo/react-native-graph/388b3e6bac7fc175fdb99f32defea0d3d271e8ac/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/margelo/react-native-graph/388b3e6bac7fc175fdb99f32defea0d3d271e8ac/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/margelo/react-native-graph/388b3e6bac7fc175fdb99f32defea0d3d271e8ac/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/margelo/react-native-graph/388b3e6bac7fc175fdb99f32defea0d3d271e8ac/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/margelo/react-native-graph/388b3e6bac7fc175fdb99f32defea0d3d271e8ac/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/margelo/react-native-graph/388b3e6bac7fc175fdb99f32defea0d3d271e8ac/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/margelo/react-native-graph/388b3e6bac7fc175fdb99f32defea0d3d271e8ac/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/margelo/react-native-graph/388b3e6bac7fc175fdb99f32defea0d3d271e8ac/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Graph Example
3 |
4 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/example/android/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext {
5 | buildToolsVersion = "33.0.0"
6 | minSdkVersion = 21
7 | compileSdkVersion = 33
8 | targetSdkVersion = 33
9 |
10 | // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP.
11 | ndkVersion = "23.1.7779620"
12 | }
13 | repositories {
14 | google()
15 | mavenCentral()
16 | }
17 | dependencies {
18 | classpath("com.android.tools.build:gradle:7.3.1")
19 | classpath("com.facebook.react:react-native-gradle-plugin")
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/example/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | # AndroidX package structure to make it clearer which packages are bundled with the
21 | # Android operating system, and which are packaged with your app's APK
22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
23 | android.useAndroidX=true
24 | # Automatically convert third-party libraries to use AndroidX
25 | android.enableJetifier=true
26 |
27 | # Version of flipper SDK to use with React Native
28 | FLIPPER_VERSION=0.125.0
29 |
30 | # Use this property to specify which architecture you want to build.
31 | # You can also override it from the CLI using
32 | # ./gradlew -PreactNativeArchitectures=x86_64
33 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
34 |
35 | # Use this property to enable support to the new architecture.
36 | # This will allow you to use TurboModules and the Fabric render in
37 | # your application. You should enable this flag either if you want
38 | # to write custom TurboModules/Fabric components OR use libraries that
39 | # are providing them.
40 | newArchEnabled=false
41 |
42 | # Use this property to enable or disable the Hermes JS engine.
43 | # If set to false, you will be using JSC instead.
44 | hermesEnabled=true
45 |
--------------------------------------------------------------------------------
/example/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/margelo/react-native-graph/388b3e6bac7fc175fdb99f32defea0d3d271e8ac/example/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/example/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon May 08 13:38:07 CEST 2023
2 | distributionBase=GRADLE_USER_HOME
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip
4 | distributionPath=wrapper/dists
5 | zipStorePath=wrapper/dists
6 | zipStoreBase=GRADLE_USER_HOME
7 |
--------------------------------------------------------------------------------
/example/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Copyright © 2015-2021 the original authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | #
21 | # Gradle start up script for POSIX generated by Gradle.
22 | #
23 | # Important for running:
24 | #
25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
26 | # noncompliant, but you have some other compliant shell such as ksh or
27 | # bash, then to run this script, type that shell name before the whole
28 | # command line, like:
29 | #
30 | # ksh Gradle
31 | #
32 | # Busybox and similar reduced shells will NOT work, because this script
33 | # requires all of these POSIX shell features:
34 | # * functions;
35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
37 | # * compound commands having a testable exit status, especially «case»;
38 | # * various built-in commands including «command», «set», and «ulimit».
39 | #
40 | # Important for patching:
41 | #
42 | # (2) This script targets any POSIX shell, so it avoids extensions provided
43 | # by Bash, Ksh, etc; in particular arrays are avoided.
44 | #
45 | # The "traditional" practice of packing multiple parameters into a
46 | # space-separated string is a well documented source of bugs and security
47 | # problems, so this is (mostly) avoided, by progressively accumulating
48 | # options in "$@", and eventually passing that to Java.
49 | #
50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
52 | # see the in-line comments for details.
53 | #
54 | # There are tweaks for specific operating systems such as AIX, CygWin,
55 | # Darwin, MinGW, and NonStop.
56 | #
57 | # (3) This script is generated from the Groovy template
58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
59 | # within the Gradle project.
60 | #
61 | # You can find Gradle at https://github.com/gradle/gradle/.
62 | #
63 | ##############################################################################
64 |
65 | # Attempt to set APP_HOME
66 |
67 | # Resolve links: $0 may be a link
68 | app_path=$0
69 |
70 | # Need this for daisy-chained symlinks.
71 | while
72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
73 | [ -h "$app_path" ]
74 | do
75 | ls=$( ls -ld "$app_path" )
76 | link=${ls#*' -> '}
77 | case $link in #(
78 | /*) app_path=$link ;; #(
79 | *) app_path=$APP_HOME$link ;;
80 | esac
81 | done
82 |
83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
84 |
85 | APP_NAME="Gradle"
86 | APP_BASE_NAME=${0##*/}
87 |
88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
90 |
91 | # Use the maximum available, or set MAX_FD != -1 to use that value.
92 | MAX_FD=maximum
93 |
94 | warn () {
95 | echo "$*"
96 | } >&2
97 |
98 | die () {
99 | echo
100 | echo "$*"
101 | echo
102 | exit 1
103 | } >&2
104 |
105 | # OS specific support (must be 'true' or 'false').
106 | cygwin=false
107 | msys=false
108 | darwin=false
109 | nonstop=false
110 | case "$( uname )" in #(
111 | CYGWIN* ) cygwin=true ;; #(
112 | Darwin* ) darwin=true ;; #(
113 | MSYS* | MINGW* ) msys=true ;; #(
114 | NONSTOP* ) nonstop=true ;;
115 | esac
116 |
117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
118 |
119 |
120 | # Determine the Java command to use to start the JVM.
121 | if [ -n "$JAVA_HOME" ] ; then
122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
123 | # IBM's JDK on AIX uses strange locations for the executables
124 | JAVACMD=$JAVA_HOME/jre/sh/java
125 | else
126 | JAVACMD=$JAVA_HOME/bin/java
127 | fi
128 | if [ ! -x "$JAVACMD" ] ; then
129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
130 |
131 | Please set the JAVA_HOME variable in your environment to match the
132 | location of your Java installation."
133 | fi
134 | else
135 | JAVACMD=java
136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
137 |
138 | Please set the JAVA_HOME variable in your environment to match the
139 | location of your Java installation."
140 | fi
141 |
142 | # Increase the maximum file descriptors if we can.
143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
144 | case $MAX_FD in #(
145 | max*)
146 | MAX_FD=$( ulimit -H -n ) ||
147 | warn "Could not query maximum file descriptor limit"
148 | esac
149 | case $MAX_FD in #(
150 | '' | soft) :;; #(
151 | *)
152 | ulimit -n "$MAX_FD" ||
153 | warn "Could not set maximum file descriptor limit to $MAX_FD"
154 | esac
155 | fi
156 |
157 | # Collect all arguments for the java command, stacking in reverse order:
158 | # * args from the command line
159 | # * the main class name
160 | # * -classpath
161 | # * -D...appname settings
162 | # * --module-path (only if needed)
163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
164 |
165 | # For Cygwin or MSYS, switch paths to Windows format before running java
166 | if "$cygwin" || "$msys" ; then
167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
169 |
170 | JAVACMD=$( cygpath --unix "$JAVACMD" )
171 |
172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
173 | for arg do
174 | if
175 | case $arg in #(
176 | -*) false ;; # don't mess with options #(
177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
178 | [ -e "$t" ] ;; #(
179 | *) false ;;
180 | esac
181 | then
182 | arg=$( cygpath --path --ignore --mixed "$arg" )
183 | fi
184 | # Roll the args list around exactly as many times as the number of
185 | # args, so each arg winds up back in the position where it started, but
186 | # possibly modified.
187 | #
188 | # NB: a `for` loop captures its iteration list before it begins, so
189 | # changing the positional parameters here affects neither the number of
190 | # iterations, nor the values presented in `arg`.
191 | shift # remove old arg
192 | set -- "$@" "$arg" # push replacement arg
193 | done
194 | fi
195 |
196 | # Collect all arguments for the java command;
197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
198 | # shell script including quotes and variable substitutions, so put them in
199 | # double quotes to make sure that they get re-expanded; and
200 | # * put everything else in single quotes, so that it's not re-expanded.
201 |
202 | set -- \
203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \
204 | -classpath "$CLASSPATH" \
205 | org.gradle.wrapper.GradleWrapperMain \
206 | "$@"
207 |
208 | # Use "xargs" to parse quoted args.
209 | #
210 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
211 | #
212 | # In Bash we could simply go:
213 | #
214 | # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
215 | # set -- "${ARGS[@]}" "$@"
216 | #
217 | # but POSIX shell has neither arrays nor command substitution, so instead we
218 | # post-process each arg (as a line of input to sed) to backslash-escape any
219 | # character that might be a shell metacharacter, then use eval to reverse
220 | # that process (while maintaining the separation between arguments), and wrap
221 | # the whole thing up as a single "set" statement.
222 | #
223 | # This will of course break if any of these variables contains a newline or
224 | # an unmatched quote.
225 | #
226 |
227 | eval "set -- $(
228 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
229 | xargs -n1 |
230 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
231 | tr '\n' ' '
232 | )" '"$@"'
233 |
234 | exec "$JAVACMD" "$@"
235 |
--------------------------------------------------------------------------------
/example/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem http://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto init
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto init
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :init
68 | @rem Get command-line arguments, handling Windows variants
69 |
70 | if not "%OS%" == "Windows_NT" goto win9xME_args
71 |
72 | :win9xME_args
73 | @rem Slurp the command line arguments.
74 | set CMD_LINE_ARGS=
75 | set _SKIP=2
76 |
77 | :win9xME_args_slurp
78 | if "x%~1" == "x" goto execute
79 |
80 | set CMD_LINE_ARGS=%*
81 |
82 | :execute
83 | @rem Setup the command line
84 |
85 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
86 |
87 | @rem Execute Gradle
88 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
89 |
90 | :end
91 | @rem End local scope for the variables with windows NT shell
92 | if "%ERRORLEVEL%"=="0" goto mainEnd
93 |
94 | :fail
95 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
96 | rem the _cmd.exe /c_ return code!
97 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
98 | exit /b 1
99 |
100 | :mainEnd
101 | if "%OS%"=="Windows_NT" endlocal
102 |
103 | :omega
104 |
--------------------------------------------------------------------------------
/example/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'GraphExample'
2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
3 | include ':app'
4 | includeBuild('../node_modules/react-native-gradle-plugin')
5 |
--------------------------------------------------------------------------------
/example/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "GraphExample",
3 | "displayName": "Graph Example"
4 | }
5 |
--------------------------------------------------------------------------------
/example/babel.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const pak = require('../package.json')
3 |
4 | module.exports = {
5 | presets: ['module:metro-react-native-babel-preset'],
6 | plugins: [
7 | [
8 | 'module-resolver',
9 | {
10 | extensions: ['.tsx', '.ts', '.js', '.json'],
11 | alias: {
12 | [pak.name]: path.join(__dirname, '..', pak.source),
13 | },
14 | },
15 | ],
16 | 'react-native-reanimated/plugin',
17 | ],
18 | }
19 |
--------------------------------------------------------------------------------
/example/index.js:
--------------------------------------------------------------------------------
1 | import { AppRegistry } from 'react-native'
2 | import App from './src/App'
3 | import { name as appName } from './app.json'
4 |
5 | AppRegistry.registerComponent(appName, () => App)
6 |
--------------------------------------------------------------------------------
/example/ios/.xcode.env:
--------------------------------------------------------------------------------
1 | export NODE_BINARY=$(command -v node)
2 |
--------------------------------------------------------------------------------
/example/ios/File.swift:
--------------------------------------------------------------------------------
1 | //
2 | // File.swift
3 | // GraphExample
4 | //
5 |
6 | import Foundation
7 |
--------------------------------------------------------------------------------
/example/ios/GraphExample-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Use this file to import your target's public headers that you would like to expose to Swift.
3 | //
4 |
--------------------------------------------------------------------------------
/example/ios/GraphExample.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 00E356F31AD99517003FC87E /* GraphExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* GraphExampleTests.m */; };
11 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
12 | 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
13 | 2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
14 | 2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
15 | 2DCD954D1E0B4F2C00145EB5 /* GraphExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* GraphExampleTests.m */; };
16 | 4C39C56BAD484C67AA576FFA /* libPods-GraphExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CA3E69C5B9553B26FBA2DF04 /* libPods-GraphExample.a */; };
17 | 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
18 | 839319722A092059003A5ECD /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 839319712A092059003A5ECD /* AppDelegate.mm */; };
19 | 839319732A092059003A5ECD /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 839319712A092059003A5ECD /* AppDelegate.mm */; };
20 | 9BAA1FA43628F10FEB728A45 /* libPods-GraphExample-GraphExampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A2B94668C2CD80C9D9D08FF /* libPods-GraphExample-GraphExampleTests.a */; };
21 | /* End PBXBuildFile section */
22 |
23 | /* Begin PBXContainerItemProxy section */
24 | 00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = {
25 | isa = PBXContainerItemProxy;
26 | containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
27 | proxyType = 1;
28 | remoteGlobalIDString = 13B07F861A680F5B00A75B9A;
29 | remoteInfo = GraphExample;
30 | };
31 | 2D02E4911E0B4A5D006451C7 /* PBXContainerItemProxy */ = {
32 | isa = PBXContainerItemProxy;
33 | containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
34 | proxyType = 1;
35 | remoteGlobalIDString = 2D02E47A1E0B4A5D006451C7;
36 | remoteInfo = "GraphExample-tvOS";
37 | };
38 | /* End PBXContainerItemProxy section */
39 |
40 | /* Begin PBXFileReference section */
41 | 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = ""; };
42 | 00E356EE1AD99517003FC87E /* GraphExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GraphExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
43 | 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
44 | 00E356F21AD99517003FC87E /* GraphExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GraphExampleTests.m; sourceTree = ""; };
45 | 13B07F961A680F5B00A75B9A /* GraphExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GraphExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
46 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = GraphExample/AppDelegate.h; sourceTree = ""; };
47 | 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = GraphExample/Images.xcassets; sourceTree = ""; };
48 | 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = GraphExample/Info.plist; sourceTree = ""; };
49 | 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = GraphExample/main.m; sourceTree = ""; };
50 | 2D02E47B1E0B4A5D006451C7 /* GraphExample-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "GraphExample-tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
51 | 2D02E4901E0B4A5D006451C7 /* GraphExample-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "GraphExample-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
52 | 47F7ED3B7971BE374F7B8635 /* Pods-GraphExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GraphExample.debug.xcconfig"; path = "Target Support Files/Pods-GraphExample/Pods-GraphExample.debug.xcconfig"; sourceTree = ""; };
53 | 4A2B94668C2CD80C9D9D08FF /* libPods-GraphExample-GraphExampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-GraphExample-GraphExampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
54 | 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = GraphExample/LaunchScreen.storyboard; sourceTree = ""; };
55 | 839319712A092059003A5ECD /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = GraphExample/AppDelegate.mm; sourceTree = ""; };
56 | B55BB517EB695BEFC799066A /* Pods-GraphExample-GraphExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GraphExample-GraphExampleTests.release.xcconfig"; path = "Target Support Files/Pods-GraphExample-GraphExampleTests/Pods-GraphExample-GraphExampleTests.release.xcconfig"; sourceTree = ""; };
57 | CA3E69C5B9553B26FBA2DF04 /* libPods-GraphExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-GraphExample.a"; sourceTree = BUILT_PRODUCTS_DIR; };
58 | E00ACF0FDA8BF921659E2F9A /* Pods-GraphExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GraphExample.release.xcconfig"; path = "Target Support Files/Pods-GraphExample/Pods-GraphExample.release.xcconfig"; sourceTree = ""; };
59 | E59B6C08E4036D22EB039CCF /* Pods-GraphExample-GraphExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GraphExample-GraphExampleTests.debug.xcconfig"; path = "Target Support Files/Pods-GraphExample-GraphExampleTests/Pods-GraphExample-GraphExampleTests.debug.xcconfig"; sourceTree = ""; };
60 | ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
61 | ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; };
62 | /* End PBXFileReference section */
63 |
64 | /* Begin PBXFrameworksBuildPhase section */
65 | 00E356EB1AD99517003FC87E /* Frameworks */ = {
66 | isa = PBXFrameworksBuildPhase;
67 | buildActionMask = 2147483647;
68 | files = (
69 | 9BAA1FA43628F10FEB728A45 /* libPods-GraphExample-GraphExampleTests.a in Frameworks */,
70 | );
71 | runOnlyForDeploymentPostprocessing = 0;
72 | };
73 | 13B07F8C1A680F5B00A75B9A /* Frameworks */ = {
74 | isa = PBXFrameworksBuildPhase;
75 | buildActionMask = 2147483647;
76 | files = (
77 | 4C39C56BAD484C67AA576FFA /* libPods-GraphExample.a in Frameworks */,
78 | );
79 | runOnlyForDeploymentPostprocessing = 0;
80 | };
81 | 2D02E4781E0B4A5D006451C7 /* Frameworks */ = {
82 | isa = PBXFrameworksBuildPhase;
83 | buildActionMask = 2147483647;
84 | files = (
85 | );
86 | runOnlyForDeploymentPostprocessing = 0;
87 | };
88 | 2D02E48D1E0B4A5D006451C7 /* Frameworks */ = {
89 | isa = PBXFrameworksBuildPhase;
90 | buildActionMask = 2147483647;
91 | files = (
92 | );
93 | runOnlyForDeploymentPostprocessing = 0;
94 | };
95 | /* End PBXFrameworksBuildPhase section */
96 |
97 | /* Begin PBXGroup section */
98 | 00E356EF1AD99517003FC87E /* GraphExampleTests */ = {
99 | isa = PBXGroup;
100 | children = (
101 | 00E356F21AD99517003FC87E /* GraphExampleTests.m */,
102 | 00E356F01AD99517003FC87E /* Supporting Files */,
103 | );
104 | path = GraphExampleTests;
105 | sourceTree = "";
106 | };
107 | 00E356F01AD99517003FC87E /* Supporting Files */ = {
108 | isa = PBXGroup;
109 | children = (
110 | 00E356F11AD99517003FC87E /* Info.plist */,
111 | );
112 | name = "Supporting Files";
113 | sourceTree = "";
114 | };
115 | 13B07FAE1A68108700A75B9A /* GraphExample */ = {
116 | isa = PBXGroup;
117 | children = (
118 | 008F07F21AC5B25A0029DE68 /* main.jsbundle */,
119 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */,
120 | 839319712A092059003A5ECD /* AppDelegate.mm */,
121 | 13B07FB51A68108700A75B9A /* Images.xcassets */,
122 | 13B07FB61A68108700A75B9A /* Info.plist */,
123 | 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */,
124 | 13B07FB71A68108700A75B9A /* main.m */,
125 | );
126 | name = GraphExample;
127 | sourceTree = "";
128 | };
129 | 2D16E6871FA4F8E400B85C8A /* Frameworks */ = {
130 | isa = PBXGroup;
131 | children = (
132 | ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
133 | ED2971642150620600B7C4FE /* JavaScriptCore.framework */,
134 | CA3E69C5B9553B26FBA2DF04 /* libPods-GraphExample.a */,
135 | 4A2B94668C2CD80C9D9D08FF /* libPods-GraphExample-GraphExampleTests.a */,
136 | );
137 | name = Frameworks;
138 | sourceTree = "";
139 | };
140 | 6B9684456A2045ADE5A6E47E /* Pods */ = {
141 | isa = PBXGroup;
142 | children = (
143 | 47F7ED3B7971BE374F7B8635 /* Pods-GraphExample.debug.xcconfig */,
144 | E00ACF0FDA8BF921659E2F9A /* Pods-GraphExample.release.xcconfig */,
145 | E59B6C08E4036D22EB039CCF /* Pods-GraphExample-GraphExampleTests.debug.xcconfig */,
146 | B55BB517EB695BEFC799066A /* Pods-GraphExample-GraphExampleTests.release.xcconfig */,
147 | );
148 | path = Pods;
149 | sourceTree = "";
150 | };
151 | 832341AE1AAA6A7D00B99B32 /* Libraries */ = {
152 | isa = PBXGroup;
153 | children = (
154 | );
155 | name = Libraries;
156 | sourceTree = "";
157 | };
158 | 83CBB9F61A601CBA00E9B192 = {
159 | isa = PBXGroup;
160 | children = (
161 | 13B07FAE1A68108700A75B9A /* GraphExample */,
162 | 832341AE1AAA6A7D00B99B32 /* Libraries */,
163 | 00E356EF1AD99517003FC87E /* GraphExampleTests */,
164 | 83CBBA001A601CBA00E9B192 /* Products */,
165 | 2D16E6871FA4F8E400B85C8A /* Frameworks */,
166 | 6B9684456A2045ADE5A6E47E /* Pods */,
167 | );
168 | indentWidth = 2;
169 | sourceTree = "";
170 | tabWidth = 2;
171 | usesTabs = 0;
172 | };
173 | 83CBBA001A601CBA00E9B192 /* Products */ = {
174 | isa = PBXGroup;
175 | children = (
176 | 13B07F961A680F5B00A75B9A /* GraphExample.app */,
177 | 00E356EE1AD99517003FC87E /* GraphExampleTests.xctest */,
178 | 2D02E47B1E0B4A5D006451C7 /* GraphExample-tvOS.app */,
179 | 2D02E4901E0B4A5D006451C7 /* GraphExample-tvOSTests.xctest */,
180 | );
181 | name = Products;
182 | sourceTree = "";
183 | };
184 | /* End PBXGroup section */
185 |
186 | /* Begin PBXNativeTarget section */
187 | 00E356ED1AD99517003FC87E /* GraphExampleTests */ = {
188 | isa = PBXNativeTarget;
189 | buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "GraphExampleTests" */;
190 | buildPhases = (
191 | EB8AD276CAB60267E82B8877 /* [CP] Check Pods Manifest.lock */,
192 | 00E356EA1AD99517003FC87E /* Sources */,
193 | 00E356EB1AD99517003FC87E /* Frameworks */,
194 | 00E356EC1AD99517003FC87E /* Resources */,
195 | 0A43EDE4F329CE1FB28633DA /* [CP] Embed Pods Frameworks */,
196 | E63619F1CE8AA8AE84A53F55 /* [CP] Copy Pods Resources */,
197 | );
198 | buildRules = (
199 | );
200 | dependencies = (
201 | 00E356F51AD99517003FC87E /* PBXTargetDependency */,
202 | );
203 | name = GraphExampleTests;
204 | productName = GraphExampleTests;
205 | productReference = 00E356EE1AD99517003FC87E /* GraphExampleTests.xctest */;
206 | productType = "com.apple.product-type.bundle.unit-test";
207 | };
208 | 13B07F861A680F5B00A75B9A /* GraphExample */ = {
209 | isa = PBXNativeTarget;
210 | buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "GraphExample" */;
211 | buildPhases = (
212 | 4F0A6FC082772762E3E4C96C /* [CP] Check Pods Manifest.lock */,
213 | FD10A7F022414F080027D42C /* Start Packager */,
214 | 13B07F871A680F5B00A75B9A /* Sources */,
215 | 13B07F8C1A680F5B00A75B9A /* Frameworks */,
216 | 13B07F8E1A680F5B00A75B9A /* Resources */,
217 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
218 | C1D60D28B925C94BD88E79D7 /* [CP] Copy Pods Resources */,
219 | C3C3C6AF747B841AC8CB0F15 /* [CP] Embed Pods Frameworks */,
220 | );
221 | buildRules = (
222 | );
223 | dependencies = (
224 | );
225 | name = GraphExample;
226 | productName = GraphExample;
227 | productReference = 13B07F961A680F5B00A75B9A /* GraphExample.app */;
228 | productType = "com.apple.product-type.application";
229 | };
230 | 2D02E47A1E0B4A5D006451C7 /* GraphExample-tvOS */ = {
231 | isa = PBXNativeTarget;
232 | buildConfigurationList = 2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "GraphExample-tvOS" */;
233 | buildPhases = (
234 | FD10A7F122414F3F0027D42C /* Start Packager */,
235 | 2D02E4771E0B4A5D006451C7 /* Sources */,
236 | 2D02E4781E0B4A5D006451C7 /* Frameworks */,
237 | 2D02E4791E0B4A5D006451C7 /* Resources */,
238 | 2D02E4CB1E0B4B27006451C7 /* Bundle React Native Code And Images */,
239 | );
240 | buildRules = (
241 | );
242 | dependencies = (
243 | );
244 | name = "GraphExample-tvOS";
245 | productName = "GraphExample-tvOS";
246 | productReference = 2D02E47B1E0B4A5D006451C7 /* GraphExample-tvOS.app */;
247 | productType = "com.apple.product-type.application";
248 | };
249 | 2D02E48F1E0B4A5D006451C7 /* GraphExample-tvOSTests */ = {
250 | isa = PBXNativeTarget;
251 | buildConfigurationList = 2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "GraphExample-tvOSTests" */;
252 | buildPhases = (
253 | 2D02E48C1E0B4A5D006451C7 /* Sources */,
254 | 2D02E48D1E0B4A5D006451C7 /* Frameworks */,
255 | 2D02E48E1E0B4A5D006451C7 /* Resources */,
256 | );
257 | buildRules = (
258 | );
259 | dependencies = (
260 | 2D02E4921E0B4A5D006451C7 /* PBXTargetDependency */,
261 | );
262 | name = "GraphExample-tvOSTests";
263 | productName = "GraphExample-tvOSTests";
264 | productReference = 2D02E4901E0B4A5D006451C7 /* GraphExample-tvOSTests.xctest */;
265 | productType = "com.apple.product-type.bundle.unit-test";
266 | };
267 | /* End PBXNativeTarget section */
268 |
269 | /* Begin PBXProject section */
270 | 83CBB9F71A601CBA00E9B192 /* Project object */ = {
271 | isa = PBXProject;
272 | attributes = {
273 | LastUpgradeCheck = 1130;
274 | TargetAttributes = {
275 | 00E356ED1AD99517003FC87E = {
276 | CreatedOnToolsVersion = 6.2;
277 | TestTargetID = 13B07F861A680F5B00A75B9A;
278 | };
279 | 13B07F861A680F5B00A75B9A = {
280 | DevelopmentTeam = CJW62Q77E7;
281 | LastSwiftMigration = 1120;
282 | };
283 | 2D02E47A1E0B4A5D006451C7 = {
284 | CreatedOnToolsVersion = 8.2.1;
285 | ProvisioningStyle = Automatic;
286 | };
287 | 2D02E48F1E0B4A5D006451C7 = {
288 | CreatedOnToolsVersion = 8.2.1;
289 | ProvisioningStyle = Automatic;
290 | TestTargetID = 2D02E47A1E0B4A5D006451C7;
291 | };
292 | };
293 | };
294 | buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "GraphExample" */;
295 | compatibilityVersion = "Xcode 3.2";
296 | developmentRegion = en;
297 | hasScannedForEncodings = 0;
298 | knownRegions = (
299 | en,
300 | Base,
301 | );
302 | mainGroup = 83CBB9F61A601CBA00E9B192;
303 | productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
304 | projectDirPath = "";
305 | projectRoot = "";
306 | targets = (
307 | 13B07F861A680F5B00A75B9A /* GraphExample */,
308 | 00E356ED1AD99517003FC87E /* GraphExampleTests */,
309 | 2D02E47A1E0B4A5D006451C7 /* GraphExample-tvOS */,
310 | 2D02E48F1E0B4A5D006451C7 /* GraphExample-tvOSTests */,
311 | );
312 | };
313 | /* End PBXProject section */
314 |
315 | /* Begin PBXResourcesBuildPhase section */
316 | 00E356EC1AD99517003FC87E /* Resources */ = {
317 | isa = PBXResourcesBuildPhase;
318 | buildActionMask = 2147483647;
319 | files = (
320 | );
321 | runOnlyForDeploymentPostprocessing = 0;
322 | };
323 | 13B07F8E1A680F5B00A75B9A /* Resources */ = {
324 | isa = PBXResourcesBuildPhase;
325 | buildActionMask = 2147483647;
326 | files = (
327 | 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */,
328 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
329 | );
330 | runOnlyForDeploymentPostprocessing = 0;
331 | };
332 | 2D02E4791E0B4A5D006451C7 /* Resources */ = {
333 | isa = PBXResourcesBuildPhase;
334 | buildActionMask = 2147483647;
335 | files = (
336 | 2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */,
337 | );
338 | runOnlyForDeploymentPostprocessing = 0;
339 | };
340 | 2D02E48E1E0B4A5D006451C7 /* Resources */ = {
341 | isa = PBXResourcesBuildPhase;
342 | buildActionMask = 2147483647;
343 | files = (
344 | );
345 | runOnlyForDeploymentPostprocessing = 0;
346 | };
347 | /* End PBXResourcesBuildPhase section */
348 |
349 | /* Begin PBXShellScriptBuildPhase section */
350 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = {
351 | isa = PBXShellScriptBuildPhase;
352 | buildActionMask = 2147483647;
353 | files = (
354 | );
355 | inputPaths = (
356 | );
357 | name = "Bundle React Native code and images";
358 | outputPaths = (
359 | );
360 | runOnlyForDeploymentPostprocessing = 0;
361 | shellPath = /bin/sh;
362 | shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh";
363 | };
364 | 0A43EDE4F329CE1FB28633DA /* [CP] Embed Pods Frameworks */ = {
365 | isa = PBXShellScriptBuildPhase;
366 | buildActionMask = 2147483647;
367 | files = (
368 | );
369 | inputPaths = (
370 | "${PODS_ROOT}/Target Support Files/Pods-GraphExample-GraphExampleTests/Pods-GraphExample-GraphExampleTests-frameworks.sh",
371 | "${PODS_XCFRAMEWORKS_BUILD_DIR}/Flipper-DoubleConversion/double-conversion.framework/double-conversion",
372 | "${PODS_XCFRAMEWORKS_BUILD_DIR}/Flipper-Glog/glog.framework/glog",
373 | "${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL-Universal/OpenSSL.framework/OpenSSL",
374 | "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
375 | );
376 | name = "[CP] Embed Pods Frameworks";
377 | outputPaths = (
378 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/double-conversion.framework",
379 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/glog.framework",
380 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework",
381 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
382 | );
383 | runOnlyForDeploymentPostprocessing = 0;
384 | shellPath = /bin/sh;
385 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-GraphExample-GraphExampleTests/Pods-GraphExample-GraphExampleTests-frameworks.sh\"\n";
386 | showEnvVarsInLog = 0;
387 | };
388 | 2D02E4CB1E0B4B27006451C7 /* Bundle React Native Code And Images */ = {
389 | isa = PBXShellScriptBuildPhase;
390 | buildActionMask = 2147483647;
391 | files = (
392 | );
393 | inputPaths = (
394 | );
395 | name = "Bundle React Native Code And Images";
396 | outputPaths = (
397 | );
398 | runOnlyForDeploymentPostprocessing = 0;
399 | shellPath = /bin/sh;
400 | shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh";
401 | };
402 | 4F0A6FC082772762E3E4C96C /* [CP] Check Pods Manifest.lock */ = {
403 | isa = PBXShellScriptBuildPhase;
404 | buildActionMask = 2147483647;
405 | files = (
406 | );
407 | inputFileListPaths = (
408 | );
409 | inputPaths = (
410 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
411 | "${PODS_ROOT}/Manifest.lock",
412 | );
413 | name = "[CP] Check Pods Manifest.lock";
414 | outputFileListPaths = (
415 | );
416 | outputPaths = (
417 | "$(DERIVED_FILE_DIR)/Pods-GraphExample-checkManifestLockResult.txt",
418 | );
419 | runOnlyForDeploymentPostprocessing = 0;
420 | shellPath = /bin/sh;
421 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
422 | showEnvVarsInLog = 0;
423 | };
424 | C1D60D28B925C94BD88E79D7 /* [CP] Copy Pods Resources */ = {
425 | isa = PBXShellScriptBuildPhase;
426 | buildActionMask = 2147483647;
427 | files = (
428 | );
429 | inputPaths = (
430 | "${PODS_ROOT}/Target Support Files/Pods-GraphExample/Pods-GraphExample-resources.sh",
431 | "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
432 | );
433 | name = "[CP] Copy Pods Resources";
434 | outputPaths = (
435 | "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
436 | );
437 | runOnlyForDeploymentPostprocessing = 0;
438 | shellPath = /bin/sh;
439 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-GraphExample/Pods-GraphExample-resources.sh\"\n";
440 | showEnvVarsInLog = 0;
441 | };
442 | C3C3C6AF747B841AC8CB0F15 /* [CP] Embed Pods Frameworks */ = {
443 | isa = PBXShellScriptBuildPhase;
444 | buildActionMask = 2147483647;
445 | files = (
446 | );
447 | inputPaths = (
448 | "${PODS_ROOT}/Target Support Files/Pods-GraphExample/Pods-GraphExample-frameworks.sh",
449 | "${PODS_XCFRAMEWORKS_BUILD_DIR}/Flipper-DoubleConversion/double-conversion.framework/double-conversion",
450 | "${PODS_XCFRAMEWORKS_BUILD_DIR}/Flipper-Glog/glog.framework/glog",
451 | "${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL-Universal/OpenSSL.framework/OpenSSL",
452 | "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
453 | );
454 | name = "[CP] Embed Pods Frameworks";
455 | outputPaths = (
456 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/double-conversion.framework",
457 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/glog.framework",
458 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework",
459 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
460 | );
461 | runOnlyForDeploymentPostprocessing = 0;
462 | shellPath = /bin/sh;
463 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-GraphExample/Pods-GraphExample-frameworks.sh\"\n";
464 | showEnvVarsInLog = 0;
465 | };
466 | E63619F1CE8AA8AE84A53F55 /* [CP] Copy Pods Resources */ = {
467 | isa = PBXShellScriptBuildPhase;
468 | buildActionMask = 2147483647;
469 | files = (
470 | );
471 | inputPaths = (
472 | "${PODS_ROOT}/Target Support Files/Pods-GraphExample-GraphExampleTests/Pods-GraphExample-GraphExampleTests-resources.sh",
473 | "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
474 | );
475 | name = "[CP] Copy Pods Resources";
476 | outputPaths = (
477 | "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
478 | );
479 | runOnlyForDeploymentPostprocessing = 0;
480 | shellPath = /bin/sh;
481 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-GraphExample-GraphExampleTests/Pods-GraphExample-GraphExampleTests-resources.sh\"\n";
482 | showEnvVarsInLog = 0;
483 | };
484 | EB8AD276CAB60267E82B8877 /* [CP] Check Pods Manifest.lock */ = {
485 | isa = PBXShellScriptBuildPhase;
486 | buildActionMask = 2147483647;
487 | files = (
488 | );
489 | inputFileListPaths = (
490 | );
491 | inputPaths = (
492 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
493 | "${PODS_ROOT}/Manifest.lock",
494 | );
495 | name = "[CP] Check Pods Manifest.lock";
496 | outputFileListPaths = (
497 | );
498 | outputPaths = (
499 | "$(DERIVED_FILE_DIR)/Pods-GraphExample-GraphExampleTests-checkManifestLockResult.txt",
500 | );
501 | runOnlyForDeploymentPostprocessing = 0;
502 | shellPath = /bin/sh;
503 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
504 | showEnvVarsInLog = 0;
505 | };
506 | FD10A7F022414F080027D42C /* Start Packager */ = {
507 | isa = PBXShellScriptBuildPhase;
508 | buildActionMask = 2147483647;
509 | files = (
510 | );
511 | inputFileListPaths = (
512 | );
513 | inputPaths = (
514 | );
515 | name = "Start Packager";
516 | outputFileListPaths = (
517 | );
518 | outputPaths = (
519 | );
520 | runOnlyForDeploymentPostprocessing = 0;
521 | shellPath = /bin/sh;
522 | shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n";
523 | showEnvVarsInLog = 0;
524 | };
525 | FD10A7F122414F3F0027D42C /* Start Packager */ = {
526 | isa = PBXShellScriptBuildPhase;
527 | buildActionMask = 2147483647;
528 | files = (
529 | );
530 | inputFileListPaths = (
531 | );
532 | inputPaths = (
533 | );
534 | name = "Start Packager";
535 | outputFileListPaths = (
536 | );
537 | outputPaths = (
538 | );
539 | runOnlyForDeploymentPostprocessing = 0;
540 | shellPath = /bin/sh;
541 | shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n";
542 | showEnvVarsInLog = 0;
543 | };
544 | /* End PBXShellScriptBuildPhase section */
545 |
546 | /* Begin PBXSourcesBuildPhase section */
547 | 00E356EA1AD99517003FC87E /* Sources */ = {
548 | isa = PBXSourcesBuildPhase;
549 | buildActionMask = 2147483647;
550 | files = (
551 | 00E356F31AD99517003FC87E /* GraphExampleTests.m in Sources */,
552 | );
553 | runOnlyForDeploymentPostprocessing = 0;
554 | };
555 | 13B07F871A680F5B00A75B9A /* Sources */ = {
556 | isa = PBXSourcesBuildPhase;
557 | buildActionMask = 2147483647;
558 | files = (
559 | 839319722A092059003A5ECD /* AppDelegate.mm in Sources */,
560 | 13B07FC11A68108700A75B9A /* main.m in Sources */,
561 | );
562 | runOnlyForDeploymentPostprocessing = 0;
563 | };
564 | 2D02E4771E0B4A5D006451C7 /* Sources */ = {
565 | isa = PBXSourcesBuildPhase;
566 | buildActionMask = 2147483647;
567 | files = (
568 | 839319732A092059003A5ECD /* AppDelegate.mm in Sources */,
569 | 2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */,
570 | );
571 | runOnlyForDeploymentPostprocessing = 0;
572 | };
573 | 2D02E48C1E0B4A5D006451C7 /* Sources */ = {
574 | isa = PBXSourcesBuildPhase;
575 | buildActionMask = 2147483647;
576 | files = (
577 | 2DCD954D1E0B4F2C00145EB5 /* GraphExampleTests.m in Sources */,
578 | );
579 | runOnlyForDeploymentPostprocessing = 0;
580 | };
581 | /* End PBXSourcesBuildPhase section */
582 |
583 | /* Begin PBXTargetDependency section */
584 | 00E356F51AD99517003FC87E /* PBXTargetDependency */ = {
585 | isa = PBXTargetDependency;
586 | target = 13B07F861A680F5B00A75B9A /* GraphExample */;
587 | targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */;
588 | };
589 | 2D02E4921E0B4A5D006451C7 /* PBXTargetDependency */ = {
590 | isa = PBXTargetDependency;
591 | target = 2D02E47A1E0B4A5D006451C7 /* GraphExample-tvOS */;
592 | targetProxy = 2D02E4911E0B4A5D006451C7 /* PBXContainerItemProxy */;
593 | };
594 | /* End PBXTargetDependency section */
595 |
596 | /* Begin XCBuildConfiguration section */
597 | 00E356F61AD99517003FC87E /* Debug */ = {
598 | isa = XCBuildConfiguration;
599 | baseConfigurationReference = E59B6C08E4036D22EB039CCF /* Pods-GraphExample-GraphExampleTests.debug.xcconfig */;
600 | buildSettings = {
601 | BUNDLE_LOADER = "$(TEST_HOST)";
602 | GCC_PREPROCESSOR_DEFINITIONS = (
603 | "DEBUG=1",
604 | "$(inherited)",
605 | );
606 | INFOPLIST_FILE = GraphExampleTests/Info.plist;
607 | IPHONEOS_DEPLOYMENT_TARGET = 10.0;
608 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
609 | OTHER_LDFLAGS = (
610 | "-ObjC",
611 | "-lc++",
612 | "$(inherited)",
613 | );
614 | PRODUCT_BUNDLE_IDENTIFIER = com.example.reactnativegraph;
615 | PRODUCT_NAME = "$(TARGET_NAME)";
616 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GraphExample.app/GraphExample";
617 | };
618 | name = Debug;
619 | };
620 | 00E356F71AD99517003FC87E /* Release */ = {
621 | isa = XCBuildConfiguration;
622 | baseConfigurationReference = B55BB517EB695BEFC799066A /* Pods-GraphExample-GraphExampleTests.release.xcconfig */;
623 | buildSettings = {
624 | BUNDLE_LOADER = "$(TEST_HOST)";
625 | COPY_PHASE_STRIP = NO;
626 | INFOPLIST_FILE = GraphExampleTests/Info.plist;
627 | IPHONEOS_DEPLOYMENT_TARGET = 10.0;
628 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
629 | OTHER_LDFLAGS = (
630 | "-ObjC",
631 | "-lc++",
632 | "$(inherited)",
633 | );
634 | PRODUCT_BUNDLE_IDENTIFIER = com.example.reactnativegraph;
635 | PRODUCT_NAME = "$(TARGET_NAME)";
636 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GraphExample.app/GraphExample";
637 | };
638 | name = Release;
639 | };
640 | 13B07F941A680F5B00A75B9A /* Debug */ = {
641 | isa = XCBuildConfiguration;
642 | baseConfigurationReference = 47F7ED3B7971BE374F7B8635 /* Pods-GraphExample.debug.xcconfig */;
643 | buildSettings = {
644 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
645 | CLANG_ENABLE_MODULES = YES;
646 | CURRENT_PROJECT_VERSION = 1;
647 | DEVELOPMENT_TEAM = CJW62Q77E7;
648 | ENABLE_BITCODE = NO;
649 | INFOPLIST_FILE = GraphExample/Info.plist;
650 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
651 | OTHER_LDFLAGS = (
652 | "$(inherited)",
653 | "-ObjC",
654 | "-lc++",
655 | );
656 | PRODUCT_BUNDLE_IDENTIFIER = com.example.reactnativegraph;
657 | PRODUCT_NAME = GraphExample;
658 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
659 | SWIFT_VERSION = 5.0;
660 | VERSIONING_SYSTEM = "apple-generic";
661 | };
662 | name = Debug;
663 | };
664 | 13B07F951A680F5B00A75B9A /* Release */ = {
665 | isa = XCBuildConfiguration;
666 | baseConfigurationReference = E00ACF0FDA8BF921659E2F9A /* Pods-GraphExample.release.xcconfig */;
667 | buildSettings = {
668 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
669 | CLANG_ENABLE_MODULES = YES;
670 | CURRENT_PROJECT_VERSION = 1;
671 | DEVELOPMENT_TEAM = CJW62Q77E7;
672 | INFOPLIST_FILE = GraphExample/Info.plist;
673 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
674 | OTHER_LDFLAGS = (
675 | "$(inherited)",
676 | "-ObjC",
677 | "-lc++",
678 | );
679 | PRODUCT_BUNDLE_IDENTIFIER = com.example.reactnativegraph;
680 | PRODUCT_NAME = GraphExample;
681 | SWIFT_VERSION = 5.0;
682 | VERSIONING_SYSTEM = "apple-generic";
683 | };
684 | name = Release;
685 | };
686 | 2D02E4971E0B4A5E006451C7 /* Debug */ = {
687 | isa = XCBuildConfiguration;
688 | buildSettings = {
689 | ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
690 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
691 | CLANG_ANALYZER_NONNULL = YES;
692 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
693 | CLANG_WARN_INFINITE_RECURSION = YES;
694 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
695 | DEBUG_INFORMATION_FORMAT = dwarf;
696 | ENABLE_TESTABILITY = YES;
697 | GCC_NO_COMMON_BLOCKS = YES;
698 | INFOPLIST_FILE = "GraphExample-tvOS/Info.plist";
699 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
700 | OTHER_LDFLAGS = (
701 | "$(inherited)",
702 | "-ObjC",
703 | "-lc++",
704 | );
705 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.GraphExample-tvOS";
706 | PRODUCT_NAME = "$(TARGET_NAME)";
707 | SDKROOT = appletvos;
708 | TARGETED_DEVICE_FAMILY = 3;
709 | TVOS_DEPLOYMENT_TARGET = 10.0;
710 | };
711 | name = Debug;
712 | };
713 | 2D02E4981E0B4A5E006451C7 /* Release */ = {
714 | isa = XCBuildConfiguration;
715 | buildSettings = {
716 | ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
717 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
718 | CLANG_ANALYZER_NONNULL = YES;
719 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
720 | CLANG_WARN_INFINITE_RECURSION = YES;
721 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
722 | COPY_PHASE_STRIP = NO;
723 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
724 | GCC_NO_COMMON_BLOCKS = YES;
725 | INFOPLIST_FILE = "GraphExample-tvOS/Info.plist";
726 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
727 | OTHER_LDFLAGS = (
728 | "$(inherited)",
729 | "-ObjC",
730 | "-lc++",
731 | );
732 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.GraphExample-tvOS";
733 | PRODUCT_NAME = "$(TARGET_NAME)";
734 | SDKROOT = appletvos;
735 | TARGETED_DEVICE_FAMILY = 3;
736 | TVOS_DEPLOYMENT_TARGET = 10.0;
737 | };
738 | name = Release;
739 | };
740 | 2D02E4991E0B4A5E006451C7 /* Debug */ = {
741 | isa = XCBuildConfiguration;
742 | buildSettings = {
743 | BUNDLE_LOADER = "$(TEST_HOST)";
744 | CLANG_ANALYZER_NONNULL = YES;
745 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
746 | CLANG_WARN_INFINITE_RECURSION = YES;
747 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
748 | DEBUG_INFORMATION_FORMAT = dwarf;
749 | ENABLE_TESTABILITY = YES;
750 | GCC_NO_COMMON_BLOCKS = YES;
751 | INFOPLIST_FILE = "GraphExample-tvOSTests/Info.plist";
752 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
753 | OTHER_LDFLAGS = (
754 | "$(inherited)",
755 | "-ObjC",
756 | "-lc++",
757 | );
758 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.GraphExample-tvOSTests";
759 | PRODUCT_NAME = "$(TARGET_NAME)";
760 | SDKROOT = appletvos;
761 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GraphExample-tvOS.app/GraphExample-tvOS";
762 | TVOS_DEPLOYMENT_TARGET = 10.1;
763 | };
764 | name = Debug;
765 | };
766 | 2D02E49A1E0B4A5E006451C7 /* Release */ = {
767 | isa = XCBuildConfiguration;
768 | buildSettings = {
769 | BUNDLE_LOADER = "$(TEST_HOST)";
770 | CLANG_ANALYZER_NONNULL = YES;
771 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
772 | CLANG_WARN_INFINITE_RECURSION = YES;
773 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
774 | COPY_PHASE_STRIP = NO;
775 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
776 | GCC_NO_COMMON_BLOCKS = YES;
777 | INFOPLIST_FILE = "GraphExample-tvOSTests/Info.plist";
778 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
779 | OTHER_LDFLAGS = (
780 | "$(inherited)",
781 | "-ObjC",
782 | "-lc++",
783 | );
784 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.GraphExample-tvOSTests";
785 | PRODUCT_NAME = "$(TARGET_NAME)";
786 | SDKROOT = appletvos;
787 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GraphExample-tvOS.app/GraphExample-tvOS";
788 | TVOS_DEPLOYMENT_TARGET = 10.1;
789 | };
790 | name = Release;
791 | };
792 | 83CBBA201A601CBA00E9B192 /* Debug */ = {
793 | isa = XCBuildConfiguration;
794 | buildSettings = {
795 | ALWAYS_SEARCH_USER_PATHS = NO;
796 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
797 | CLANG_CXX_LANGUAGE_STANDARD = "c++14";
798 | CLANG_CXX_LIBRARY = "libc++";
799 | CLANG_ENABLE_MODULES = YES;
800 | CLANG_ENABLE_OBJC_ARC = YES;
801 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
802 | CLANG_WARN_BOOL_CONVERSION = YES;
803 | CLANG_WARN_COMMA = YES;
804 | CLANG_WARN_CONSTANT_CONVERSION = YES;
805 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
806 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
807 | CLANG_WARN_EMPTY_BODY = YES;
808 | CLANG_WARN_ENUM_CONVERSION = YES;
809 | CLANG_WARN_INFINITE_RECURSION = YES;
810 | CLANG_WARN_INT_CONVERSION = YES;
811 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
812 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
813 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
814 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
815 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
816 | CLANG_WARN_STRICT_PROTOTYPES = YES;
817 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
818 | CLANG_WARN_UNREACHABLE_CODE = YES;
819 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
820 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
821 | COPY_PHASE_STRIP = NO;
822 | ENABLE_STRICT_OBJC_MSGSEND = YES;
823 | ENABLE_TESTABILITY = YES;
824 | "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
825 | GCC_C_LANGUAGE_STANDARD = gnu99;
826 | GCC_DYNAMIC_NO_PIC = NO;
827 | GCC_NO_COMMON_BLOCKS = YES;
828 | GCC_OPTIMIZATION_LEVEL = 0;
829 | GCC_PREPROCESSOR_DEFINITIONS = (
830 | "DEBUG=1",
831 | "$(inherited)",
832 | );
833 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
834 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
835 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
836 | GCC_WARN_UNDECLARED_SELECTOR = YES;
837 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
838 | GCC_WARN_UNUSED_FUNCTION = YES;
839 | GCC_WARN_UNUSED_VARIABLE = YES;
840 | IPHONEOS_DEPLOYMENT_TARGET = 10.0;
841 | LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)";
842 | LIBRARY_SEARCH_PATHS = (
843 | "$(SDKROOT)/usr/lib/swift",
844 | "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
845 | "\"$(inherited)\"",
846 | );
847 | MTL_ENABLE_DEBUG_INFO = YES;
848 | ONLY_ACTIVE_ARCH = YES;
849 | REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
850 | SDKROOT = iphoneos;
851 | };
852 | name = Debug;
853 | };
854 | 83CBBA211A601CBA00E9B192 /* Release */ = {
855 | isa = XCBuildConfiguration;
856 | buildSettings = {
857 | ALWAYS_SEARCH_USER_PATHS = NO;
858 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
859 | CLANG_CXX_LANGUAGE_STANDARD = "c++14";
860 | CLANG_CXX_LIBRARY = "libc++";
861 | CLANG_ENABLE_MODULES = YES;
862 | CLANG_ENABLE_OBJC_ARC = YES;
863 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
864 | CLANG_WARN_BOOL_CONVERSION = YES;
865 | CLANG_WARN_COMMA = YES;
866 | CLANG_WARN_CONSTANT_CONVERSION = YES;
867 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
868 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
869 | CLANG_WARN_EMPTY_BODY = YES;
870 | CLANG_WARN_ENUM_CONVERSION = YES;
871 | CLANG_WARN_INFINITE_RECURSION = YES;
872 | CLANG_WARN_INT_CONVERSION = YES;
873 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
874 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
875 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
876 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
877 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
878 | CLANG_WARN_STRICT_PROTOTYPES = YES;
879 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
880 | CLANG_WARN_UNREACHABLE_CODE = YES;
881 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
882 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
883 | COPY_PHASE_STRIP = YES;
884 | ENABLE_NS_ASSERTIONS = NO;
885 | ENABLE_STRICT_OBJC_MSGSEND = YES;
886 | "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
887 | GCC_C_LANGUAGE_STANDARD = gnu99;
888 | GCC_NO_COMMON_BLOCKS = YES;
889 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
890 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
891 | GCC_WARN_UNDECLARED_SELECTOR = YES;
892 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
893 | GCC_WARN_UNUSED_FUNCTION = YES;
894 | GCC_WARN_UNUSED_VARIABLE = YES;
895 | IPHONEOS_DEPLOYMENT_TARGET = 10.0;
896 | LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)";
897 | LIBRARY_SEARCH_PATHS = (
898 | "$(SDKROOT)/usr/lib/swift",
899 | "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
900 | "\"$(inherited)\"",
901 | );
902 | MTL_ENABLE_DEBUG_INFO = NO;
903 | REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
904 | SDKROOT = iphoneos;
905 | VALIDATE_PRODUCT = YES;
906 | };
907 | name = Release;
908 | };
909 | /* End XCBuildConfiguration section */
910 |
911 | /* Begin XCConfigurationList section */
912 | 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "GraphExampleTests" */ = {
913 | isa = XCConfigurationList;
914 | buildConfigurations = (
915 | 00E356F61AD99517003FC87E /* Debug */,
916 | 00E356F71AD99517003FC87E /* Release */,
917 | );
918 | defaultConfigurationIsVisible = 0;
919 | defaultConfigurationName = Release;
920 | };
921 | 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "GraphExample" */ = {
922 | isa = XCConfigurationList;
923 | buildConfigurations = (
924 | 13B07F941A680F5B00A75B9A /* Debug */,
925 | 13B07F951A680F5B00A75B9A /* Release */,
926 | );
927 | defaultConfigurationIsVisible = 0;
928 | defaultConfigurationName = Release;
929 | };
930 | 2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "GraphExample-tvOS" */ = {
931 | isa = XCConfigurationList;
932 | buildConfigurations = (
933 | 2D02E4971E0B4A5E006451C7 /* Debug */,
934 | 2D02E4981E0B4A5E006451C7 /* Release */,
935 | );
936 | defaultConfigurationIsVisible = 0;
937 | defaultConfigurationName = Release;
938 | };
939 | 2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "GraphExample-tvOSTests" */ = {
940 | isa = XCConfigurationList;
941 | buildConfigurations = (
942 | 2D02E4991E0B4A5E006451C7 /* Debug */,
943 | 2D02E49A1E0B4A5E006451C7 /* Release */,
944 | );
945 | defaultConfigurationIsVisible = 0;
946 | defaultConfigurationName = Release;
947 | };
948 | 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "GraphExample" */ = {
949 | isa = XCConfigurationList;
950 | buildConfigurations = (
951 | 83CBBA201A601CBA00E9B192 /* Debug */,
952 | 83CBBA211A601CBA00E9B192 /* Release */,
953 | );
954 | defaultConfigurationIsVisible = 0;
955 | defaultConfigurationName = Release;
956 | };
957 | /* End XCConfigurationList section */
958 | };
959 | rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;
960 | }
961 |
--------------------------------------------------------------------------------
/example/ios/GraphExample.xcodeproj/xcshareddata/xcschemes/GraphExample.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
51 |
52 |
53 |
54 |
64 |
66 |
72 |
73 |
74 |
75 |
81 |
83 |
89 |
90 |
91 |
92 |
94 |
95 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/example/ios/GraphExample.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/example/ios/GraphExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/GraphExample/AppDelegate.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | *
4 | * This source code is licensed under the MIT license found in the
5 | * LICENSE file in the root directory of this source tree.
6 | */
7 |
8 | #import
9 | #import
10 |
11 | @interface AppDelegate : RCTAppDelegate
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/example/ios/GraphExample/AppDelegate.mm:
--------------------------------------------------------------------------------
1 | #import "AppDelegate.h"
2 |
3 | #import
4 |
5 | @implementation AppDelegate
6 |
7 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
8 | {
9 | self.moduleName = @"GraphExample";
10 | // You can add your custom initial props in the dictionary below.
11 | // They will be passed down to the ViewController used by React Native.
12 | self.initialProps = @{};
13 |
14 | return [super application:application didFinishLaunchingWithOptions:launchOptions];
15 | }
16 |
17 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
18 | {
19 | #if DEBUG
20 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
21 | #else
22 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
23 | #endif
24 | }
25 |
26 | /// This method controls whether the `concurrentRoot`feature of React18 is turned on or off.
27 | ///
28 | /// @see: https://reactjs.org/blog/2022/03/29/react-v18.html
29 | /// @note: This requires to be rendering on Fabric (i.e. on the New Architecture).
30 | /// @return: `true` if the `concurrentRoot` feature is enabled. Otherwise, it returns `false`.
31 | - (BOOL)concurrentRootEnabled
32 | {
33 | return true;
34 | }
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/example/ios/GraphExample/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/example/ios/GraphExample/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/example/ios/GraphExample/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | Graph Example
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | LSRequiresIPhoneOS
26 |
27 | NSAppTransportSecurity
28 |
29 | NSAllowsArbitraryLoads
30 |
31 | NSExceptionDomains
32 |
33 | localhost
34 |
35 | NSExceptionAllowsInsecureHTTPLoads
36 |
37 |
38 |
39 |
40 | NSLocationWhenInUseUsageDescription
41 |
42 | UILaunchStoryboardName
43 | LaunchScreen
44 | UIRequiredDeviceCapabilities
45 |
46 | armv7
47 |
48 | UISupportedInterfaceOrientations
49 |
50 | UIInterfaceOrientationPortrait
51 | UIInterfaceOrientationLandscapeLeft
52 | UIInterfaceOrientationLandscapeRight
53 |
54 | UIViewControllerBasedStatusBarAppearance
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/example/ios/GraphExample/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/example/ios/GraphExample/main.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | *
4 | * This source code is licensed under the MIT license found in the
5 | * LICENSE file in the root directory of this source tree.
6 | */
7 |
8 | #import
9 |
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char *argv[])
13 | {
14 | @autoreleasepool {
15 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/example/ios/Podfile:
--------------------------------------------------------------------------------
1 | require_relative '../node_modules/react-native/scripts/react_native_pods'
2 | require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
3 |
4 | platform :ios, min_ios_version_supported
5 | prepare_react_native_project!
6 |
7 | # If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set.
8 | # because `react-native-flipper` depends on (FlipperKit,...) that will be excluded
9 | #
10 | # To fix this you can also exclude `react-native-flipper` using a `react-native.config.js`
11 | # ```js
12 | # module.exports = {
13 | # dependencies: {
14 | # ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}),
15 | # ```
16 | flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled
17 |
18 | linkage = ENV['USE_FRAMEWORKS']
19 | if linkage != nil
20 | Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
21 | use_frameworks! :linkage => linkage.to_sym
22 | end
23 |
24 | target 'GraphExample' do
25 | config = use_native_modules!
26 |
27 | # Flags change depending on the env values.
28 | flags = get_default_flags()
29 |
30 | use_react_native!(
31 | :path => config[:reactNativePath],
32 | # Hermes is now enabled by default. Disable by setting this flag to false.
33 | # Upcoming versions of React Native may rely on get_default_flags(), but
34 | # we make it explicit here to aid in the React Native upgrade process.
35 | :hermes_enabled => flags[:hermes_enabled],
36 | :fabric_enabled => flags[:fabric_enabled],
37 | # Enables Flipper.
38 | #
39 | # Note that if you have use_frameworks! enabled, Flipper will not work and
40 | # you should disable the next line.
41 | :flipper_configuration => flipper_config,
42 | # An absolute path to your application root.
43 | :app_path => "#{Pod::Config.instance.installation_root}/.."
44 | )
45 |
46 | target 'GraphExampleTests' do
47 | inherit! :complete
48 | # Pods for testing
49 | end
50 |
51 | post_install do |installer|
52 | react_native_post_install(
53 | installer,
54 | # Set `mac_catalyst_enabled` to `true` in order to apply patches
55 | # necessary for Mac Catalyst builds
56 | :mac_catalyst_enabled => false
57 | )
58 | __apply_Xcode_12_5_M1_post_install_workaround(installer)
59 | end
60 | end
61 |
--------------------------------------------------------------------------------
/example/ios/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - boost (1.76.0)
3 | - CocoaAsyncSocket (7.6.5)
4 | - DoubleConversion (1.1.6)
5 | - FBLazyVector (0.71.7)
6 | - FBReactNativeSpec (0.71.7):
7 | - RCT-Folly (= 2021.07.22.00)
8 | - RCTRequired (= 0.71.7)
9 | - RCTTypeSafety (= 0.71.7)
10 | - React-Core (= 0.71.7)
11 | - React-jsi (= 0.71.7)
12 | - ReactCommon/turbomodule/core (= 0.71.7)
13 | - Flipper (0.125.0):
14 | - Flipper-Folly (~> 2.6)
15 | - Flipper-RSocket (~> 1.4)
16 | - Flipper-Boost-iOSX (1.76.0.1.11)
17 | - Flipper-DoubleConversion (3.2.0.1)
18 | - Flipper-Fmt (7.1.7)
19 | - Flipper-Folly (2.6.10):
20 | - Flipper-Boost-iOSX
21 | - Flipper-DoubleConversion
22 | - Flipper-Fmt (= 7.1.7)
23 | - Flipper-Glog
24 | - libevent (~> 2.1.12)
25 | - OpenSSL-Universal (= 1.1.1100)
26 | - Flipper-Glog (0.5.0.5)
27 | - Flipper-PeerTalk (0.0.4)
28 | - Flipper-RSocket (1.4.3):
29 | - Flipper-Folly (~> 2.6)
30 | - FlipperKit (0.125.0):
31 | - FlipperKit/Core (= 0.125.0)
32 | - FlipperKit/Core (0.125.0):
33 | - Flipper (~> 0.125.0)
34 | - FlipperKit/CppBridge
35 | - FlipperKit/FBCxxFollyDynamicConvert
36 | - FlipperKit/FBDefines
37 | - FlipperKit/FKPortForwarding
38 | - SocketRocket (~> 0.6.0)
39 | - FlipperKit/CppBridge (0.125.0):
40 | - Flipper (~> 0.125.0)
41 | - FlipperKit/FBCxxFollyDynamicConvert (0.125.0):
42 | - Flipper-Folly (~> 2.6)
43 | - FlipperKit/FBDefines (0.125.0)
44 | - FlipperKit/FKPortForwarding (0.125.0):
45 | - CocoaAsyncSocket (~> 7.6)
46 | - Flipper-PeerTalk (~> 0.0.4)
47 | - FlipperKit/FlipperKitHighlightOverlay (0.125.0)
48 | - FlipperKit/FlipperKitLayoutHelpers (0.125.0):
49 | - FlipperKit/Core
50 | - FlipperKit/FlipperKitHighlightOverlay
51 | - FlipperKit/FlipperKitLayoutTextSearchable
52 | - FlipperKit/FlipperKitLayoutIOSDescriptors (0.125.0):
53 | - FlipperKit/Core
54 | - FlipperKit/FlipperKitHighlightOverlay
55 | - FlipperKit/FlipperKitLayoutHelpers
56 | - YogaKit (~> 1.18)
57 | - FlipperKit/FlipperKitLayoutPlugin (0.125.0):
58 | - FlipperKit/Core
59 | - FlipperKit/FlipperKitHighlightOverlay
60 | - FlipperKit/FlipperKitLayoutHelpers
61 | - FlipperKit/FlipperKitLayoutIOSDescriptors
62 | - FlipperKit/FlipperKitLayoutTextSearchable
63 | - YogaKit (~> 1.18)
64 | - FlipperKit/FlipperKitLayoutTextSearchable (0.125.0)
65 | - FlipperKit/FlipperKitNetworkPlugin (0.125.0):
66 | - FlipperKit/Core
67 | - FlipperKit/FlipperKitReactPlugin (0.125.0):
68 | - FlipperKit/Core
69 | - FlipperKit/FlipperKitUserDefaultsPlugin (0.125.0):
70 | - FlipperKit/Core
71 | - FlipperKit/SKIOSNetworkPlugin (0.125.0):
72 | - FlipperKit/Core
73 | - FlipperKit/FlipperKitNetworkPlugin
74 | - fmt (6.2.1)
75 | - glog (0.3.5)
76 | - hermes-engine (0.71.7):
77 | - hermes-engine/Pre-built (= 0.71.7)
78 | - hermes-engine/Pre-built (0.71.7)
79 | - libevent (2.1.12)
80 | - OpenSSL-Universal (1.1.1100)
81 | - RCT-Folly (2021.07.22.00):
82 | - boost
83 | - DoubleConversion
84 | - fmt (~> 6.2.1)
85 | - glog
86 | - RCT-Folly/Default (= 2021.07.22.00)
87 | - RCT-Folly/Default (2021.07.22.00):
88 | - boost
89 | - DoubleConversion
90 | - fmt (~> 6.2.1)
91 | - glog
92 | - RCT-Folly/Futures (2021.07.22.00):
93 | - boost
94 | - DoubleConversion
95 | - fmt (~> 6.2.1)
96 | - glog
97 | - libevent
98 | - RCTRequired (0.71.7)
99 | - RCTTypeSafety (0.71.7):
100 | - FBLazyVector (= 0.71.7)
101 | - RCTRequired (= 0.71.7)
102 | - React-Core (= 0.71.7)
103 | - React (0.71.7):
104 | - React-Core (= 0.71.7)
105 | - React-Core/DevSupport (= 0.71.7)
106 | - React-Core/RCTWebSocket (= 0.71.7)
107 | - React-RCTActionSheet (= 0.71.7)
108 | - React-RCTAnimation (= 0.71.7)
109 | - React-RCTBlob (= 0.71.7)
110 | - React-RCTImage (= 0.71.7)
111 | - React-RCTLinking (= 0.71.7)
112 | - React-RCTNetwork (= 0.71.7)
113 | - React-RCTSettings (= 0.71.7)
114 | - React-RCTText (= 0.71.7)
115 | - React-RCTVibration (= 0.71.7)
116 | - React-callinvoker (0.71.7)
117 | - React-Codegen (0.71.7):
118 | - FBReactNativeSpec
119 | - hermes-engine
120 | - RCT-Folly
121 | - RCTRequired
122 | - RCTTypeSafety
123 | - React-Core
124 | - React-jsi
125 | - React-jsiexecutor
126 | - ReactCommon/turbomodule/bridging
127 | - ReactCommon/turbomodule/core
128 | - React-Core (0.71.7):
129 | - glog
130 | - hermes-engine
131 | - RCT-Folly (= 2021.07.22.00)
132 | - React-Core/Default (= 0.71.7)
133 | - React-cxxreact (= 0.71.7)
134 | - React-hermes
135 | - React-jsi (= 0.71.7)
136 | - React-jsiexecutor (= 0.71.7)
137 | - React-perflogger (= 0.71.7)
138 | - Yoga
139 | - React-Core/CoreModulesHeaders (0.71.7):
140 | - glog
141 | - hermes-engine
142 | - RCT-Folly (= 2021.07.22.00)
143 | - React-Core/Default
144 | - React-cxxreact (= 0.71.7)
145 | - React-hermes
146 | - React-jsi (= 0.71.7)
147 | - React-jsiexecutor (= 0.71.7)
148 | - React-perflogger (= 0.71.7)
149 | - Yoga
150 | - React-Core/Default (0.71.7):
151 | - glog
152 | - hermes-engine
153 | - RCT-Folly (= 2021.07.22.00)
154 | - React-cxxreact (= 0.71.7)
155 | - React-hermes
156 | - React-jsi (= 0.71.7)
157 | - React-jsiexecutor (= 0.71.7)
158 | - React-perflogger (= 0.71.7)
159 | - Yoga
160 | - React-Core/DevSupport (0.71.7):
161 | - glog
162 | - hermes-engine
163 | - RCT-Folly (= 2021.07.22.00)
164 | - React-Core/Default (= 0.71.7)
165 | - React-Core/RCTWebSocket (= 0.71.7)
166 | - React-cxxreact (= 0.71.7)
167 | - React-hermes
168 | - React-jsi (= 0.71.7)
169 | - React-jsiexecutor (= 0.71.7)
170 | - React-jsinspector (= 0.71.7)
171 | - React-perflogger (= 0.71.7)
172 | - Yoga
173 | - React-Core/RCTActionSheetHeaders (0.71.7):
174 | - glog
175 | - hermes-engine
176 | - RCT-Folly (= 2021.07.22.00)
177 | - React-Core/Default
178 | - React-cxxreact (= 0.71.7)
179 | - React-hermes
180 | - React-jsi (= 0.71.7)
181 | - React-jsiexecutor (= 0.71.7)
182 | - React-perflogger (= 0.71.7)
183 | - Yoga
184 | - React-Core/RCTAnimationHeaders (0.71.7):
185 | - glog
186 | - hermes-engine
187 | - RCT-Folly (= 2021.07.22.00)
188 | - React-Core/Default
189 | - React-cxxreact (= 0.71.7)
190 | - React-hermes
191 | - React-jsi (= 0.71.7)
192 | - React-jsiexecutor (= 0.71.7)
193 | - React-perflogger (= 0.71.7)
194 | - Yoga
195 | - React-Core/RCTBlobHeaders (0.71.7):
196 | - glog
197 | - hermes-engine
198 | - RCT-Folly (= 2021.07.22.00)
199 | - React-Core/Default
200 | - React-cxxreact (= 0.71.7)
201 | - React-hermes
202 | - React-jsi (= 0.71.7)
203 | - React-jsiexecutor (= 0.71.7)
204 | - React-perflogger (= 0.71.7)
205 | - Yoga
206 | - React-Core/RCTImageHeaders (0.71.7):
207 | - glog
208 | - hermes-engine
209 | - RCT-Folly (= 2021.07.22.00)
210 | - React-Core/Default
211 | - React-cxxreact (= 0.71.7)
212 | - React-hermes
213 | - React-jsi (= 0.71.7)
214 | - React-jsiexecutor (= 0.71.7)
215 | - React-perflogger (= 0.71.7)
216 | - Yoga
217 | - React-Core/RCTLinkingHeaders (0.71.7):
218 | - glog
219 | - hermes-engine
220 | - RCT-Folly (= 2021.07.22.00)
221 | - React-Core/Default
222 | - React-cxxreact (= 0.71.7)
223 | - React-hermes
224 | - React-jsi (= 0.71.7)
225 | - React-jsiexecutor (= 0.71.7)
226 | - React-perflogger (= 0.71.7)
227 | - Yoga
228 | - React-Core/RCTNetworkHeaders (0.71.7):
229 | - glog
230 | - hermes-engine
231 | - RCT-Folly (= 2021.07.22.00)
232 | - React-Core/Default
233 | - React-cxxreact (= 0.71.7)
234 | - React-hermes
235 | - React-jsi (= 0.71.7)
236 | - React-jsiexecutor (= 0.71.7)
237 | - React-perflogger (= 0.71.7)
238 | - Yoga
239 | - React-Core/RCTSettingsHeaders (0.71.7):
240 | - glog
241 | - hermes-engine
242 | - RCT-Folly (= 2021.07.22.00)
243 | - React-Core/Default
244 | - React-cxxreact (= 0.71.7)
245 | - React-hermes
246 | - React-jsi (= 0.71.7)
247 | - React-jsiexecutor (= 0.71.7)
248 | - React-perflogger (= 0.71.7)
249 | - Yoga
250 | - React-Core/RCTTextHeaders (0.71.7):
251 | - glog
252 | - hermes-engine
253 | - RCT-Folly (= 2021.07.22.00)
254 | - React-Core/Default
255 | - React-cxxreact (= 0.71.7)
256 | - React-hermes
257 | - React-jsi (= 0.71.7)
258 | - React-jsiexecutor (= 0.71.7)
259 | - React-perflogger (= 0.71.7)
260 | - Yoga
261 | - React-Core/RCTVibrationHeaders (0.71.7):
262 | - glog
263 | - hermes-engine
264 | - RCT-Folly (= 2021.07.22.00)
265 | - React-Core/Default
266 | - React-cxxreact (= 0.71.7)
267 | - React-hermes
268 | - React-jsi (= 0.71.7)
269 | - React-jsiexecutor (= 0.71.7)
270 | - React-perflogger (= 0.71.7)
271 | - Yoga
272 | - React-Core/RCTWebSocket (0.71.7):
273 | - glog
274 | - hermes-engine
275 | - RCT-Folly (= 2021.07.22.00)
276 | - React-Core/Default (= 0.71.7)
277 | - React-cxxreact (= 0.71.7)
278 | - React-hermes
279 | - React-jsi (= 0.71.7)
280 | - React-jsiexecutor (= 0.71.7)
281 | - React-perflogger (= 0.71.7)
282 | - Yoga
283 | - React-CoreModules (0.71.7):
284 | - RCT-Folly (= 2021.07.22.00)
285 | - RCTTypeSafety (= 0.71.7)
286 | - React-Codegen (= 0.71.7)
287 | - React-Core/CoreModulesHeaders (= 0.71.7)
288 | - React-jsi (= 0.71.7)
289 | - React-RCTBlob
290 | - React-RCTImage (= 0.71.7)
291 | - ReactCommon/turbomodule/core (= 0.71.7)
292 | - React-cxxreact (0.71.7):
293 | - boost (= 1.76.0)
294 | - DoubleConversion
295 | - glog
296 | - hermes-engine
297 | - RCT-Folly (= 2021.07.22.00)
298 | - React-callinvoker (= 0.71.7)
299 | - React-jsi (= 0.71.7)
300 | - React-jsinspector (= 0.71.7)
301 | - React-logger (= 0.71.7)
302 | - React-perflogger (= 0.71.7)
303 | - React-runtimeexecutor (= 0.71.7)
304 | - React-hermes (0.71.7):
305 | - DoubleConversion
306 | - glog
307 | - hermes-engine
308 | - RCT-Folly (= 2021.07.22.00)
309 | - RCT-Folly/Futures (= 2021.07.22.00)
310 | - React-cxxreact (= 0.71.7)
311 | - React-jsi
312 | - React-jsiexecutor (= 0.71.7)
313 | - React-jsinspector (= 0.71.7)
314 | - React-perflogger (= 0.71.7)
315 | - React-jsi (0.71.7):
316 | - boost (= 1.76.0)
317 | - DoubleConversion
318 | - glog
319 | - hermes-engine
320 | - RCT-Folly (= 2021.07.22.00)
321 | - React-jsiexecutor (0.71.7):
322 | - DoubleConversion
323 | - glog
324 | - hermes-engine
325 | - RCT-Folly (= 2021.07.22.00)
326 | - React-cxxreact (= 0.71.7)
327 | - React-jsi (= 0.71.7)
328 | - React-perflogger (= 0.71.7)
329 | - React-jsinspector (0.71.7)
330 | - React-logger (0.71.7):
331 | - glog
332 | - react-native-segmented-control (2.4.0):
333 | - React-Core
334 | - react-native-skia (0.1.188):
335 | - React
336 | - React-callinvoker
337 | - React-Core
338 | - React-perflogger (0.71.7)
339 | - React-RCTActionSheet (0.71.7):
340 | - React-Core/RCTActionSheetHeaders (= 0.71.7)
341 | - React-RCTAnimation (0.71.7):
342 | - RCT-Folly (= 2021.07.22.00)
343 | - RCTTypeSafety (= 0.71.7)
344 | - React-Codegen (= 0.71.7)
345 | - React-Core/RCTAnimationHeaders (= 0.71.7)
346 | - React-jsi (= 0.71.7)
347 | - ReactCommon/turbomodule/core (= 0.71.7)
348 | - React-RCTAppDelegate (0.71.7):
349 | - RCT-Folly
350 | - RCTRequired
351 | - RCTTypeSafety
352 | - React-Core
353 | - ReactCommon/turbomodule/core
354 | - React-RCTBlob (0.71.7):
355 | - hermes-engine
356 | - RCT-Folly (= 2021.07.22.00)
357 | - React-Codegen (= 0.71.7)
358 | - React-Core/RCTBlobHeaders (= 0.71.7)
359 | - React-Core/RCTWebSocket (= 0.71.7)
360 | - React-jsi (= 0.71.7)
361 | - React-RCTNetwork (= 0.71.7)
362 | - ReactCommon/turbomodule/core (= 0.71.7)
363 | - React-RCTImage (0.71.7):
364 | - RCT-Folly (= 2021.07.22.00)
365 | - RCTTypeSafety (= 0.71.7)
366 | - React-Codegen (= 0.71.7)
367 | - React-Core/RCTImageHeaders (= 0.71.7)
368 | - React-jsi (= 0.71.7)
369 | - React-RCTNetwork (= 0.71.7)
370 | - ReactCommon/turbomodule/core (= 0.71.7)
371 | - React-RCTLinking (0.71.7):
372 | - React-Codegen (= 0.71.7)
373 | - React-Core/RCTLinkingHeaders (= 0.71.7)
374 | - React-jsi (= 0.71.7)
375 | - ReactCommon/turbomodule/core (= 0.71.7)
376 | - React-RCTNetwork (0.71.7):
377 | - RCT-Folly (= 2021.07.22.00)
378 | - RCTTypeSafety (= 0.71.7)
379 | - React-Codegen (= 0.71.7)
380 | - React-Core/RCTNetworkHeaders (= 0.71.7)
381 | - React-jsi (= 0.71.7)
382 | - ReactCommon/turbomodule/core (= 0.71.7)
383 | - React-RCTSettings (0.71.7):
384 | - RCT-Folly (= 2021.07.22.00)
385 | - RCTTypeSafety (= 0.71.7)
386 | - React-Codegen (= 0.71.7)
387 | - React-Core/RCTSettingsHeaders (= 0.71.7)
388 | - React-jsi (= 0.71.7)
389 | - ReactCommon/turbomodule/core (= 0.71.7)
390 | - React-RCTText (0.71.7):
391 | - React-Core/RCTTextHeaders (= 0.71.7)
392 | - React-RCTVibration (0.71.7):
393 | - RCT-Folly (= 2021.07.22.00)
394 | - React-Codegen (= 0.71.7)
395 | - React-Core/RCTVibrationHeaders (= 0.71.7)
396 | - React-jsi (= 0.71.7)
397 | - ReactCommon/turbomodule/core (= 0.71.7)
398 | - React-runtimeexecutor (0.71.7):
399 | - React-jsi (= 0.71.7)
400 | - ReactCommon/turbomodule/bridging (0.71.7):
401 | - DoubleConversion
402 | - glog
403 | - hermes-engine
404 | - RCT-Folly (= 2021.07.22.00)
405 | - React-callinvoker (= 0.71.7)
406 | - React-Core (= 0.71.7)
407 | - React-cxxreact (= 0.71.7)
408 | - React-jsi (= 0.71.7)
409 | - React-logger (= 0.71.7)
410 | - React-perflogger (= 0.71.7)
411 | - ReactCommon/turbomodule/core (0.71.7):
412 | - DoubleConversion
413 | - glog
414 | - hermes-engine
415 | - RCT-Folly (= 2021.07.22.00)
416 | - React-callinvoker (= 0.71.7)
417 | - React-Core (= 0.71.7)
418 | - React-cxxreact (= 0.71.7)
419 | - React-jsi (= 0.71.7)
420 | - React-logger (= 0.71.7)
421 | - React-perflogger (= 0.71.7)
422 | - RNGestureHandler (2.9.0):
423 | - React-Core
424 | - RNReactNativeHapticFeedback (1.13.1):
425 | - React-Core
426 | - RNReanimated (3.1.0):
427 | - DoubleConversion
428 | - FBLazyVector
429 | - FBReactNativeSpec
430 | - glog
431 | - RCT-Folly
432 | - RCTRequired
433 | - RCTTypeSafety
434 | - React-callinvoker
435 | - React-Core
436 | - React-Core/DevSupport
437 | - React-Core/RCTWebSocket
438 | - React-CoreModules
439 | - React-cxxreact
440 | - React-jsi
441 | - React-jsiexecutor
442 | - React-jsinspector
443 | - React-RCTActionSheet
444 | - React-RCTAnimation
445 | - React-RCTBlob
446 | - React-RCTImage
447 | - React-RCTLinking
448 | - React-RCTNetwork
449 | - React-RCTSettings
450 | - React-RCTText
451 | - ReactCommon/turbomodule/core
452 | - Yoga
453 | - RNStaticSafeAreaInsets (2.1.1):
454 | - React
455 | - SocketRocket (0.6.0)
456 | - Yoga (1.14.0)
457 | - YogaKit (1.18.1):
458 | - Yoga (~> 1.14)
459 |
460 | DEPENDENCIES:
461 | - boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`)
462 | - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
463 | - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
464 | - FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
465 | - Flipper (= 0.125.0)
466 | - Flipper-Boost-iOSX (= 1.76.0.1.11)
467 | - Flipper-DoubleConversion (= 3.2.0.1)
468 | - Flipper-Fmt (= 7.1.7)
469 | - Flipper-Folly (= 2.6.10)
470 | - Flipper-Glog (= 0.5.0.5)
471 | - Flipper-PeerTalk (= 0.0.4)
472 | - Flipper-RSocket (= 1.4.3)
473 | - FlipperKit (= 0.125.0)
474 | - FlipperKit/Core (= 0.125.0)
475 | - FlipperKit/CppBridge (= 0.125.0)
476 | - FlipperKit/FBCxxFollyDynamicConvert (= 0.125.0)
477 | - FlipperKit/FBDefines (= 0.125.0)
478 | - FlipperKit/FKPortForwarding (= 0.125.0)
479 | - FlipperKit/FlipperKitHighlightOverlay (= 0.125.0)
480 | - FlipperKit/FlipperKitLayoutPlugin (= 0.125.0)
481 | - FlipperKit/FlipperKitLayoutTextSearchable (= 0.125.0)
482 | - FlipperKit/FlipperKitNetworkPlugin (= 0.125.0)
483 | - FlipperKit/FlipperKitReactPlugin (= 0.125.0)
484 | - FlipperKit/FlipperKitUserDefaultsPlugin (= 0.125.0)
485 | - FlipperKit/SKIOSNetworkPlugin (= 0.125.0)
486 | - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
487 | - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`)
488 | - libevent (~> 2.1.12)
489 | - OpenSSL-Universal (= 1.1.1100)
490 | - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
491 | - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
492 | - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
493 | - React (from `../node_modules/react-native/`)
494 | - React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`)
495 | - React-Codegen (from `build/generated/ios`)
496 | - React-Core (from `../node_modules/react-native/`)
497 | - React-Core/DevSupport (from `../node_modules/react-native/`)
498 | - React-Core/RCTWebSocket (from `../node_modules/react-native/`)
499 | - React-CoreModules (from `../node_modules/react-native/React/CoreModules`)
500 | - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`)
501 | - React-hermes (from `../node_modules/react-native/ReactCommon/hermes`)
502 | - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
503 | - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
504 | - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
505 | - React-logger (from `../node_modules/react-native/ReactCommon/logger`)
506 | - "react-native-segmented-control (from `../node_modules/@react-native-segmented-control/segmented-control`)"
507 | - "react-native-skia (from `../node_modules/@shopify/react-native-skia`)"
508 | - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
509 | - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
510 | - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`)
511 | - React-RCTAppDelegate (from `../node_modules/react-native/Libraries/AppDelegate`)
512 | - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`)
513 | - React-RCTImage (from `../node_modules/react-native/Libraries/Image`)
514 | - React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`)
515 | - React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`)
516 | - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`)
517 | - React-RCTText (from `../node_modules/react-native/Libraries/Text`)
518 | - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
519 | - React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`)
520 | - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
521 | - RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
522 | - RNReactNativeHapticFeedback (from `../node_modules/react-native-haptic-feedback`)
523 | - RNReanimated (from `../node_modules/react-native-reanimated`)
524 | - RNStaticSafeAreaInsets (from `../node_modules/react-native-static-safe-area-insets`)
525 | - Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
526 |
527 | SPEC REPOS:
528 | trunk:
529 | - CocoaAsyncSocket
530 | - Flipper
531 | - Flipper-Boost-iOSX
532 | - Flipper-DoubleConversion
533 | - Flipper-Fmt
534 | - Flipper-Folly
535 | - Flipper-Glog
536 | - Flipper-PeerTalk
537 | - Flipper-RSocket
538 | - FlipperKit
539 | - fmt
540 | - libevent
541 | - OpenSSL-Universal
542 | - SocketRocket
543 | - YogaKit
544 |
545 | EXTERNAL SOURCES:
546 | boost:
547 | :podspec: "../node_modules/react-native/third-party-podspecs/boost.podspec"
548 | DoubleConversion:
549 | :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
550 | FBLazyVector:
551 | :path: "../node_modules/react-native/Libraries/FBLazyVector"
552 | FBReactNativeSpec:
553 | :path: "../node_modules/react-native/React/FBReactNativeSpec"
554 | glog:
555 | :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
556 | hermes-engine:
557 | :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec"
558 | RCT-Folly:
559 | :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec"
560 | RCTRequired:
561 | :path: "../node_modules/react-native/Libraries/RCTRequired"
562 | RCTTypeSafety:
563 | :path: "../node_modules/react-native/Libraries/TypeSafety"
564 | React:
565 | :path: "../node_modules/react-native/"
566 | React-callinvoker:
567 | :path: "../node_modules/react-native/ReactCommon/callinvoker"
568 | React-Codegen:
569 | :path: build/generated/ios
570 | React-Core:
571 | :path: "../node_modules/react-native/"
572 | React-CoreModules:
573 | :path: "../node_modules/react-native/React/CoreModules"
574 | React-cxxreact:
575 | :path: "../node_modules/react-native/ReactCommon/cxxreact"
576 | React-hermes:
577 | :path: "../node_modules/react-native/ReactCommon/hermes"
578 | React-jsi:
579 | :path: "../node_modules/react-native/ReactCommon/jsi"
580 | React-jsiexecutor:
581 | :path: "../node_modules/react-native/ReactCommon/jsiexecutor"
582 | React-jsinspector:
583 | :path: "../node_modules/react-native/ReactCommon/jsinspector"
584 | React-logger:
585 | :path: "../node_modules/react-native/ReactCommon/logger"
586 | react-native-segmented-control:
587 | :path: "../node_modules/@react-native-segmented-control/segmented-control"
588 | react-native-skia:
589 | :path: "../node_modules/@shopify/react-native-skia"
590 | React-perflogger:
591 | :path: "../node_modules/react-native/ReactCommon/reactperflogger"
592 | React-RCTActionSheet:
593 | :path: "../node_modules/react-native/Libraries/ActionSheetIOS"
594 | React-RCTAnimation:
595 | :path: "../node_modules/react-native/Libraries/NativeAnimation"
596 | React-RCTAppDelegate:
597 | :path: "../node_modules/react-native/Libraries/AppDelegate"
598 | React-RCTBlob:
599 | :path: "../node_modules/react-native/Libraries/Blob"
600 | React-RCTImage:
601 | :path: "../node_modules/react-native/Libraries/Image"
602 | React-RCTLinking:
603 | :path: "../node_modules/react-native/Libraries/LinkingIOS"
604 | React-RCTNetwork:
605 | :path: "../node_modules/react-native/Libraries/Network"
606 | React-RCTSettings:
607 | :path: "../node_modules/react-native/Libraries/Settings"
608 | React-RCTText:
609 | :path: "../node_modules/react-native/Libraries/Text"
610 | React-RCTVibration:
611 | :path: "../node_modules/react-native/Libraries/Vibration"
612 | React-runtimeexecutor:
613 | :path: "../node_modules/react-native/ReactCommon/runtimeexecutor"
614 | ReactCommon:
615 | :path: "../node_modules/react-native/ReactCommon"
616 | RNGestureHandler:
617 | :path: "../node_modules/react-native-gesture-handler"
618 | RNReactNativeHapticFeedback:
619 | :path: "../node_modules/react-native-haptic-feedback"
620 | RNReanimated:
621 | :path: "../node_modules/react-native-reanimated"
622 | RNStaticSafeAreaInsets:
623 | :path: "../node_modules/react-native-static-safe-area-insets"
624 | Yoga:
625 | :path: "../node_modules/react-native/ReactCommon/yoga"
626 |
627 | SPEC CHECKSUMS:
628 | boost: 57d2868c099736d80fcd648bf211b4431e51a558
629 | CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
630 | DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
631 | FBLazyVector: a89a0525bc7ca174675045c2b492b5280d5a2470
632 | FBReactNativeSpec: 7714e6bc1e9ea23df6c4cb42f0b2fd9c6a3a559c
633 | Flipper: 26fc4b7382499f1281eb8cb921e5c3ad6de91fe0
634 | Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c
635 | Flipper-DoubleConversion: 2dc99b02f658daf147069aad9dbd29d8feb06d30
636 | Flipper-Fmt: 60cbdd92fc254826e61d669a5d87ef7015396a9b
637 | Flipper-Folly: 584845625005ff068a6ebf41f857f468decd26b3
638 | Flipper-Glog: 70c50ce58ddaf67dc35180db05f191692570f446
639 | Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9
640 | Flipper-RSocket: d9d9ade67cbecf6ac10730304bf5607266dd2541
641 | FlipperKit: cbdee19bdd4e7f05472a66ce290f1b729ba3cb86
642 | fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
643 | glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
644 | hermes-engine: 4438d2b8bf8bebaba1b1ac0451160bab59e491f8
645 | libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
646 | OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c
647 | RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1
648 | RCTRequired: 5a4a30ac20c86eeadd6844a9328f78d4168cf9b2
649 | RCTTypeSafety: 279fc5861a89f0f37db3a585f27f971485b4b734
650 | React: 88307a9be3bd0e71a6822271cf28b84a587fb97f
651 | React-callinvoker: 35fb980c454104ebe82f0afb9826830089248e08
652 | React-Codegen: a8dbde3b7476d5c19437d2adb9e8ea1b426b9595
653 | React-Core: 385cb6fa78762c6409ff39faeb0dd9ad664b6e84
654 | React-CoreModules: c2b7db313b04d9b71954ffd55d0c2e46bc40e9fb
655 | React-cxxreact: 845fefb889132e5d004ff818f7a599e32c52e7d6
656 | React-hermes: 86135f35e1dd2dfccfb97afe96d0c06f6a3970c4
657 | React-jsi: 39c116aa6c3d6f3d9874eff6998a670b47882a28
658 | React-jsiexecutor: eaa5f71eb8f6861cf0e57f1a0f52aeb020d9e18e
659 | React-jsinspector: 9885f6f94d231b95a739ef7bb50536fb87ce7539
660 | React-logger: 3f8ebad1be1bf3299d1ab6d7f971802d7395c7ef
661 | react-native-segmented-control: 06607462630512ff8eef652ec560e6235a30cc3e
662 | react-native-skia: 8c68c437707fd47b25420ca4c8563fe3cfc52ada
663 | React-perflogger: 2d505bbe298e3b7bacdd9e542b15535be07220f6
664 | React-RCTActionSheet: 0e96e4560bd733c9b37efbf68f5b1a47615892fb
665 | React-RCTAnimation: fd138e26f120371c87e406745a27535e2c8a04ef
666 | React-RCTAppDelegate: 4a9fd1230a98dc3d4382f8a934dc9f50834d8335
667 | React-RCTBlob: 38a7185f06a0ce8153a023e63b406a28d67b955d
668 | React-RCTImage: 92b0966e7c1cadda889e961c474397ad5180e194
669 | React-RCTLinking: b80f8d0c6e94c54294b0048def51f57eaa9a27af
670 | React-RCTNetwork: 491b0c65ac22edbd6695d12d084b4943103b009b
671 | React-RCTSettings: 97af3e8abe0023349ec015910df3bda1a0380117
672 | React-RCTText: 33c85753bd714d527d2ae538dc56ec24c6783d84
673 | React-RCTVibration: 08f132cad9896458776f37c112e71d60aef1c6ae
674 | React-runtimeexecutor: c5c89f8f543842dd864b63ded1b0bbb9c9445328
675 | ReactCommon: dbfbe2f7f3c5ce4ce44f43f2fd0d5950d1eb67c5
676 | RNGestureHandler: 071d7a9ad81e8b83fe7663b303d132406a7d8f39
677 | RNReactNativeHapticFeedback: 4085973f5a38b40d3c6793a3ee5724773eae045e
678 | RNReanimated: b1220a0e5168745283ff5d53bfc7d2144b2cee1b
679 | RNStaticSafeAreaInsets: 6103cf09647fa427186d30f67b0f5163c1ae8252
680 | SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608
681 | Yoga: d56980c8914db0b51692f55533409e844b66133c
682 | YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
683 |
684 | PODFILE CHECKSUM: 69e7f1fd189d8c9d5c72fa8e8c8692596d21099b
685 |
686 | COCOAPODS: 1.12.1
687 |
--------------------------------------------------------------------------------
/example/metro.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const exclusionList = require('metro-config/src/defaults/exclusionList')
3 | const escape = require('escape-string-regexp')
4 | const pak = require('../package.json')
5 |
6 | const root = path.resolve(__dirname, '..')
7 |
8 | const modules = Object.keys({
9 | ...pak.peerDependencies,
10 | })
11 |
12 | module.exports = {
13 | projectRoot: __dirname,
14 | watchFolders: [root],
15 |
16 | // We need to make sure that only one version is loaded for peerDependencies
17 | // So we blacklist them at the root, and alias them to the versions in example's node_modules
18 | resolver: {
19 | blacklistRE: exclusionList(
20 | modules.map(
21 | (m) =>
22 | new RegExp(`^${escape(path.join(root, 'node_modules', m))}\\/.*$`)
23 | )
24 | ),
25 |
26 | extraNodeModules: modules.reduce((acc, name) => {
27 | acc[name] = path.join(__dirname, 'node_modules', name)
28 | return acc
29 | }, {}),
30 | },
31 |
32 | transformer: {
33 | getTransformOptions: async () => ({
34 | transform: {
35 | experimentalImportSupport: false,
36 | inlineRequires: true,
37 | },
38 | }),
39 | },
40 | }
41 |
--------------------------------------------------------------------------------
/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-graph-example",
3 | "description": "Example app for react-native-graph",
4 | "version": "0.0.1",
5 | "private": true,
6 | "scripts": {
7 | "android": "react-native run-android",
8 | "ios": "react-native run-ios",
9 | "start": "react-native start"
10 | },
11 | "dependencies": {
12 | "@react-native-segmented-control/segmented-control": "^2.4.0",
13 | "@shopify/react-native-skia": "^0.1.233",
14 | "@types/gaussian": "^1.2.0",
15 | "gaussian": "^1.2.0",
16 | "react": "^18.2.0",
17 | "react-native": "^0.71.7",
18 | "react-native-gesture-handler": "^2.9.0",
19 | "react-native-haptic-feedback": "^1.13.1",
20 | "react-native-pressable-scale": "^1.0.6",
21 | "react-native-reanimated": "^3.1.0",
22 | "react-native-static-safe-area-insets": "^2.2.0"
23 | },
24 | "devDependencies": {
25 | "@babel/core": "^7.20.0",
26 | "@babel/runtime": "^7.20.0",
27 | "@types/react": "^18.0.24",
28 | "babel-plugin-module-resolver": "^4.0.0",
29 | "metro-react-native-babel-preset": "^0.73.9"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/example/src/App.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 | import { StyleSheet } from 'react-native'
3 | import { GestureHandlerRootView } from 'react-native-gesture-handler'
4 | import { GraphPage } from './screens/GraphPage'
5 |
6 | export default function App() {
7 | return (
8 |
9 |
10 |
11 | )
12 | }
13 |
14 | const styles = StyleSheet.create({
15 | container: {
16 | flex: 1,
17 | },
18 | })
19 |
--------------------------------------------------------------------------------
/example/src/Constants.ts:
--------------------------------------------------------------------------------
1 | import { Dimensions } from 'react-native'
2 |
3 | export const SCREEN_WIDTH = Dimensions.get('window').width
4 | export const GRAPH_DISPLAY_MODES = ['6h', '1d', '1w', '1m', '3m'] as const
5 |
6 | export type GraphDisplayMode = typeof GRAPH_DISPLAY_MODES[number]
7 |
--------------------------------------------------------------------------------
/example/src/components/CustomSelectionDot.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * An example for a custom SelectionDot component.
3 | *
4 | * Usage:
5 | *
6 | * ```jsx
7 | *
13 | * ```
14 | *
15 | * This example has removed the outer ring and light
16 | * shadow from the default one to make it more flat.
17 | */
18 | import React, { useCallback } from 'react'
19 | import {
20 | runOnJS,
21 | useAnimatedReaction,
22 | withSpring,
23 | useSharedValue,
24 | } from 'react-native-reanimated'
25 | import { Circle } from '@shopify/react-native-skia'
26 | import type { SelectionDotProps } from 'react-native-graph'
27 |
28 | export function SelectionDot({
29 | isActive,
30 | color,
31 | circleX,
32 | circleY,
33 | }: SelectionDotProps): React.ReactElement {
34 | const circleRadius = useSharedValue(0)
35 |
36 | const setIsActive = useCallback(
37 | (active: boolean) => {
38 | circleRadius.value = withSpring(active ? 5 : 0, {
39 | mass: 1,
40 | stiffness: 1000,
41 | damping: 50,
42 | velocity: 0,
43 | })
44 | },
45 | [circleRadius]
46 | )
47 |
48 | useAnimatedReaction(
49 | () => isActive.value,
50 | (active) => {
51 | runOnJS(setIsActive)(active)
52 | },
53 | [isActive, setIsActive]
54 | )
55 |
56 | return
57 | }
58 |
--------------------------------------------------------------------------------
/example/src/components/GraphDisplayModeSelector.tsx:
--------------------------------------------------------------------------------
1 | import { useColors } from '../hooks/useColors'
2 | import React, { useCallback, useState } from 'react'
3 | import {
4 | LayoutChangeEvent,
5 | StyleSheet,
6 | View,
7 | ViewProps,
8 | Text,
9 | } from 'react-native'
10 | import { PressableScale } from 'react-native-pressable-scale'
11 | import Reanimated, {
12 | Easing,
13 | useAnimatedStyle,
14 | withSpring,
15 | withTiming,
16 | } from 'react-native-reanimated'
17 | import {
18 | GraphDisplayMode,
19 | GRAPH_DISPLAY_MODES,
20 | SCREEN_WIDTH,
21 | } from '../Constants'
22 |
23 | interface Props extends ViewProps {
24 | graphDisplayMode: GraphDisplayMode
25 | setGraphDisplayMode: (graphDisplayMode: GraphDisplayMode) => void
26 | }
27 |
28 | export const SPACING = 5
29 | export const ESTIMATED_BUTTON_WIDTH =
30 | (SCREEN_WIDTH - 50) / GRAPH_DISPLAY_MODES.length
31 |
32 | export function GraphDisplayModeSelector({
33 | graphDisplayMode,
34 | setGraphDisplayMode,
35 | style,
36 | ...props
37 | }: Props): React.ReactElement {
38 | const colors = useColors()
39 |
40 | const [width, setWidth] = useState(ESTIMATED_BUTTON_WIDTH)
41 |
42 | const onLayout = useCallback(
43 | ({ nativeEvent: { layout } }: LayoutChangeEvent) => {
44 | setWidth(Math.round(layout.width))
45 | },
46 | []
47 | )
48 |
49 | const buttonWidth = width / GRAPH_DISPLAY_MODES.length - 2 * SPACING
50 |
51 | const selectedModeIndex = GRAPH_DISPLAY_MODES.indexOf(graphDisplayMode)
52 | const selectionBackgroundStyle = useAnimatedStyle(() => {
53 | return {
54 | width: buttonWidth,
55 | opacity: withTiming(selectedModeIndex === -1 ? 0 : 1, {
56 | easing: Easing.linear,
57 | duration: 150,
58 | }),
59 | transform: [
60 | {
61 | translateX: withSpring(
62 | buttonWidth * selectedModeIndex + 2 * SPACING * selectedModeIndex,
63 | {
64 | mass: 1,
65 | stiffness: 900,
66 | damping: 300,
67 | }
68 | ),
69 | },
70 | ],
71 | }
72 | }, [buttonWidth, selectedModeIndex])
73 |
74 | return (
75 |
76 |
83 | {GRAPH_DISPLAY_MODES.map((displayMode) => (
84 |
85 | setGraphDisplayMode(displayMode)}
88 | >
89 |
90 | {displayMode.toUpperCase()}
91 |
92 |
93 |
94 | ))}
95 |
96 | )
97 | }
98 |
99 | const styles = StyleSheet.create({
100 | container: {
101 | flexDirection: 'row',
102 | justifyContent: 'space-between',
103 | },
104 | selectionBackground: {
105 | position: 'absolute',
106 | height: '100%',
107 | marginLeft: SPACING,
108 | borderRadius: 7,
109 | },
110 | buttonContainer: {
111 | flex: 1,
112 | },
113 | button: {
114 | flex: 1,
115 | alignItems: 'center',
116 | marginHorizontal: SPACING,
117 | paddingVertical: 2.5,
118 | },
119 | })
120 |
--------------------------------------------------------------------------------
/example/src/components/Toggle.tsx:
--------------------------------------------------------------------------------
1 | import SegmentedControl from '@react-native-segmented-control/segmented-control'
2 | import React from 'react'
3 | import { StyleSheet, Text, View } from 'react-native'
4 | import { useColors } from '../hooks/useColors'
5 |
6 | interface Props {
7 | title: string
8 | isEnabled: boolean
9 | setIsEnabled: (isEnabled: boolean) => void
10 | }
11 |
12 | export function Toggle({ title, isEnabled, setIsEnabled }: Props) {
13 | const colors = useColors()
14 |
15 | return (
16 |
17 |
18 | {title}
19 |
20 |
21 |
22 |
23 | setIsEnabled(v === 'yes')}
28 | />
29 |
30 | )
31 | }
32 |
33 | const styles = StyleSheet.create({
34 | row: {
35 | flexDirection: 'row',
36 | alignItems: 'center',
37 | marginVertical: 5,
38 | },
39 | spacer: {
40 | flexGrow: 1,
41 | },
42 | toggleText: {
43 | fontSize: 18,
44 | fontWeight: '600',
45 | },
46 | segmentedControl: {
47 | marginLeft: 10,
48 | width: 140,
49 | },
50 | })
51 |
--------------------------------------------------------------------------------
/example/src/data/GraphData.ts:
--------------------------------------------------------------------------------
1 | import type { GraphPoint } from '../../../src/LineGraphProps'
2 | import gaussian from 'gaussian'
3 |
4 | function weightedRandom(mean: number, variance: number): number {
5 | var distribution = gaussian(mean, variance)
6 | // Take a random sample using inverse transform sampling method.
7 | return distribution.ppf(Math.random())
8 | }
9 |
10 | export function generateRandomGraphData(length: number): GraphPoint[] {
11 | return Array(length)
12 | .fill(0)
13 | .map((_, index) => ({
14 | date: new Date(
15 | new Date(2000, 0, 1).getTime() + 1000 * 60 * 60 * 24 * index
16 | ),
17 | value: weightedRandom(10, Math.pow(index + 1, 2)),
18 | }))
19 | }
20 |
21 | export function generateSinusGraphData(length: number): GraphPoint[] {
22 | return Array(length)
23 | .fill(0)
24 | .map((_, index) => ({
25 | date: new Date(index),
26 | value: Math.sin(index),
27 | }))
28 | }
29 |
--------------------------------------------------------------------------------
/example/src/hooks/useColors.ts:
--------------------------------------------------------------------------------
1 | import { useColorScheme } from 'react-native'
2 |
3 | interface Palette {
4 | background: string
5 | foreground: string
6 | }
7 |
8 | const dark: Palette = {
9 | background: '#333',
10 | foreground: '#eee',
11 | }
12 | const light: Palette = {
13 | background: '#fff',
14 | foreground: '#333',
15 | }
16 |
17 | export function useColors(): Palette {
18 | const isDarkMode = useColorScheme() === 'dark'
19 |
20 | return isDarkMode ? dark : light
21 | }
22 |
--------------------------------------------------------------------------------
/example/src/screens/GraphPage.tsx:
--------------------------------------------------------------------------------
1 | import React, { useCallback, useMemo, useState } from 'react'
2 | import { View, StyleSheet, Text, Button, ScrollView } from 'react-native'
3 | import { LineGraph } from 'react-native-graph'
4 | import StaticSafeAreaInsets from 'react-native-static-safe-area-insets'
5 | import type { GraphRange } from '../../../src/LineGraphProps'
6 | import { SelectionDot } from '../components/CustomSelectionDot'
7 | import { Toggle } from '../components/Toggle'
8 | import {
9 | generateRandomGraphData,
10 | generateSinusGraphData,
11 | } from '../data/GraphData'
12 | import { useColors } from '../hooks/useColors'
13 | import { hapticFeedback } from '../utils/HapticFeedback'
14 |
15 | const POINT_COUNT = 70
16 | const POINTS = generateRandomGraphData(POINT_COUNT)
17 | const COLOR = '#6a7ee7'
18 | const GRADIENT_FILL_COLORS = ['#7476df5D', '#7476df4D', '#7476df00']
19 | const SMALL_POINTS = generateSinusGraphData(9)
20 |
21 | export function GraphPage() {
22 | const colors = useColors()
23 |
24 | const [isAnimated, setIsAnimated] = useState(true)
25 | const [enablePanGesture, setEnablePanGesture] = useState(true)
26 | const [enableFadeInEffect, setEnableFadeInEffect] = useState(false)
27 | const [enableCustomSelectionDot, setEnableCustomSelectionDot] =
28 | useState(false)
29 | const [enableGradient, setEnableGradient] = useState(false)
30 | const [enableRange, setEnableRange] = useState(false)
31 | const [enableIndicator, setEnableIndicator] = useState(false)
32 | const [indicatorPulsating, setIndicatorPulsating] = useState(false)
33 |
34 | const [points, setPoints] = useState(POINTS)
35 |
36 | const refreshData = useCallback(() => {
37 | setPoints(generateRandomGraphData(POINT_COUNT))
38 | hapticFeedback('impactLight')
39 | }, [])
40 |
41 | const highestDate = useMemo(
42 | () =>
43 | points.length !== 0 && points[points.length - 1] != null
44 | ? points[points.length - 1]!.date
45 | : undefined,
46 | [points]
47 | )
48 | const range: GraphRange | undefined = useMemo(() => {
49 | // if range is disabled, default to infinite range (undefined)
50 | if (!enableRange) return undefined
51 |
52 | if (points.length !== 0 && highestDate != null) {
53 | return {
54 | x: {
55 | min: points[0]!.date,
56 | max: new Date(highestDate.getTime() + 50 * 1000 * 60 * 60 * 24),
57 | },
58 | y: {
59 | min: -200,
60 | max: 200,
61 | },
62 | }
63 | } else {
64 | return {
65 | y: {
66 | min: -200,
67 | max: 200,
68 | },
69 | }
70 | }
71 | }, [enableRange, highestDate, points])
72 |
73 | return (
74 |
75 |
76 |
77 | react-native-graph
78 |
79 |
85 |
86 |
87 |
88 |
89 | hapticFeedback('impactLight')}
98 | SelectionDot={enableCustomSelectionDot ? SelectionDot : undefined}
99 | range={range}
100 | enableIndicator={enableIndicator}
101 | horizontalPadding={enableIndicator ? 15 : 0}
102 | indicatorPulsating={indicatorPulsating}
103 | />
104 |
105 |
106 |
107 |
111 |
116 |
121 |
126 |
131 |
136 |
141 |
146 |
151 |
152 |
153 |
154 |
155 | )
156 | }
157 |
158 | const styles = StyleSheet.create({
159 | container: {
160 | flex: 1,
161 | paddingTop: StaticSafeAreaInsets.safeAreaInsetsTop + 15,
162 | paddingBottom: StaticSafeAreaInsets.safeAreaInsetsBottom + 15,
163 | },
164 | spacer: {
165 | flexGrow: 1,
166 | },
167 | row: {
168 | flexDirection: 'row',
169 | alignItems: 'center',
170 | },
171 | title: {
172 | fontSize: 30,
173 | fontWeight: '700',
174 | paddingHorizontal: 15,
175 | },
176 | graph: {
177 | alignSelf: 'center',
178 | width: '100%',
179 | aspectRatio: 1.4,
180 | marginVertical: 20,
181 | },
182 | miniGraph: {
183 | width: 40,
184 | height: 35,
185 | marginLeft: 5,
186 | },
187 | controlsScrollView: {
188 | flexGrow: 1,
189 | paddingHorizontal: 15,
190 | },
191 | controlsScrollViewContent: {
192 | justifyContent: 'center',
193 | },
194 | })
195 |
--------------------------------------------------------------------------------
/example/src/utils/HapticFeedback.ts:
--------------------------------------------------------------------------------
1 | import HapticFeedback, {
2 | HapticFeedbackTypes,
3 | } from 'react-native-haptic-feedback'
4 |
5 | export function hapticFeedback(
6 | type: HapticFeedbackTypes = 'impactLight',
7 | force = false
8 | ): void {
9 | HapticFeedback.trigger(type, {
10 | enableVibrateFallback: force,
11 | ignoreAndroidSystemSettings: force,
12 | })
13 | }
14 |
--------------------------------------------------------------------------------
/example/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig",
3 | "compilerOptions": {
4 | "paths": {
5 | "react-native-graph": ["../src/index"]
6 | },
7 | },
8 | "include": [
9 | "src",
10 | "index.js"
11 | ],
12 | "exclude": [
13 | "node_modules"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/img/change.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/margelo/react-native-graph/388b3e6bac7fc175fdb99f32defea0d3d271e8ac/img/change.gif
--------------------------------------------------------------------------------
/img/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/margelo/react-native-graph/388b3e6bac7fc175fdb99f32defea0d3d271e8ac/img/demo.gif
--------------------------------------------------------------------------------
/img/label.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/margelo/react-native-graph/388b3e6bac7fc175fdb99f32defea0d3d271e8ac/img/label.png
--------------------------------------------------------------------------------
/img/pan.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/margelo/react-native-graph/388b3e6bac7fc175fdb99f32defea0d3d271e8ac/img/pan.gif
--------------------------------------------------------------------------------
/img/pinkpanda.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/margelo/react-native-graph/388b3e6bac7fc175fdb99f32defea0d3d271e8ac/img/pinkpanda.png
--------------------------------------------------------------------------------
/img/range.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/margelo/react-native-graph/388b3e6bac7fc175fdb99f32defea0d3d271e8ac/img/range.png
--------------------------------------------------------------------------------
/img/selection-dot.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/margelo/react-native-graph/388b3e6bac7fc175fdb99f32defea0d3d271e8ac/img/selection-dot.jpeg
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-graph",
3 | "version": "1.1.0",
4 | "description": "📈 Beautiful, high-performance Graphs and Charts for React Native",
5 | "main": "lib/commonjs/index",
6 | "module": "lib/module/index",
7 | "types": "lib/typescript/index.d.ts",
8 | "react-native": "src/index",
9 | "source": "src/index",
10 | "files": [
11 | "src",
12 | "lib",
13 | "README.md"
14 | ],
15 | "scripts": {
16 | "test": "jest",
17 | "typescript": "tsc --noEmit",
18 | "lint": "eslint \"**/*.{js,ts,tsx}\"",
19 | "prepare": "bob build",
20 | "release": "release-it",
21 | "example": "yarn --cwd example",
22 | "pods": "cd example && pod-install --quiet",
23 | "bootstrap": "yarn example && yarn && yarn pods"
24 | },
25 | "keywords": [
26 | "react-native",
27 | "ios",
28 | "android",
29 | "react",
30 | "svg",
31 | "chart",
32 | "charts",
33 | "library",
34 | "performance",
35 | "react-native",
36 | "crypto",
37 | "graph",
38 | "animation",
39 | "graphs",
40 | "stock",
41 | "beautiful",
42 | "wallet",
43 | "animated",
44 | "skia",
45 | "linegraph"
46 | ],
47 | "repository": "https://github.com/margelo/react-native-graph",
48 | "author": "Marc Rousavy (https://github.com/mrousavy)",
49 | "license": "MIT",
50 | "bugs": {
51 | "url": "https://github.com/margelo/react-native-graph/issues"
52 | },
53 | "homepage": "https://github.com/margelo/react-native-graph#readme",
54 | "publishConfig": {
55 | "registry": "https://registry.npmjs.org/"
56 | },
57 | "devDependencies": {
58 | "@react-native-community/eslint-config": "^2.0.0",
59 | "@release-it/conventional-changelog": "^2.0.0",
60 | "@shopify/react-native-skia": "^0.1.233",
61 | "@types/react": "^17.0.42",
62 | "@types/react-native": "^0.67.4",
63 | "eslint": "^7.2.0",
64 | "eslint-config-prettier": "^7.0.0",
65 | "eslint-plugin-prettier": "^3.1.3",
66 | "pod-install": "^0.1.0",
67 | "prettier": "^2.0.5",
68 | "react": "^18.2.0",
69 | "react-native": "^0.71.7",
70 | "react-native-builder-bob": "^0.18.0",
71 | "react-native-gesture-handler": "^2.9.0",
72 | "react-native-reanimated": "^3.1.0",
73 | "release-it": "^14.2.2",
74 | "typescript": "^4.4.3"
75 | },
76 | "peerDependencies": {
77 | "@shopify/react-native-skia": ">=0.1.233",
78 | "react": ">=18",
79 | "react-native": ">=0.69",
80 | "react-native-gesture-handler": ">=2",
81 | "react-native-reanimated": ">=3.1.0"
82 | },
83 | "release-it": {
84 | "git": {
85 | "commitMessage": "chore: release ${version}",
86 | "tagName": "v${version}"
87 | },
88 | "npm": {
89 | "publish": true
90 | },
91 | "github": {
92 | "release": true
93 | },
94 | "plugins": {
95 | "@release-it/conventional-changelog": {
96 | "preset": "angular"
97 | }
98 | }
99 | },
100 | "eslintConfig": {
101 | "root": true,
102 | "extends": [
103 | "@react-native-community",
104 | "prettier"
105 | ],
106 | "rules": {
107 | "prettier/prettier": [
108 | "error",
109 | {
110 | "quoteProps": "consistent",
111 | "singleQuote": true,
112 | "tabWidth": 2,
113 | "semi": false,
114 | "trailingComma": "es5",
115 | "useTabs": false
116 | }
117 | ]
118 | }
119 | },
120 | "eslintIgnore": [
121 | "node_modules/",
122 | "lib/"
123 | ],
124 | "prettier": {
125 | "quoteProps": "consistent",
126 | "singleQuote": true,
127 | "tabWidth": 2,
128 | "trailingComma": "es5",
129 | "useTabs": false,
130 | "semi": false
131 | },
132 | "react-native-builder-bob": {
133 | "source": "src",
134 | "output": "lib",
135 | "targets": [
136 | "commonjs",
137 | "module",
138 | [
139 | "typescript",
140 | {
141 | "project": "tsconfig.json"
142 | }
143 | ]
144 | ]
145 | },
146 | "packageManager": "yarn@1.22.19+sha1.4ba7fc5c6e704fce2066ecbfb0b0d8976fe62447"
147 | }
148 |
--------------------------------------------------------------------------------
/src/AnimatedLineGraph.tsx:
--------------------------------------------------------------------------------
1 | import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
2 | import { View, StyleSheet, LayoutChangeEvent } from 'react-native'
3 | import Reanimated, {
4 | runOnJS,
5 | useAnimatedReaction,
6 | useSharedValue,
7 | useDerivedValue,
8 | cancelAnimation,
9 | withRepeat,
10 | withSequence,
11 | withTiming,
12 | withDelay,
13 | withSpring,
14 | } from 'react-native-reanimated'
15 | import { GestureDetector } from 'react-native-gesture-handler'
16 |
17 | import {
18 | Canvas,
19 | SkPath,
20 | LinearGradient,
21 | Path,
22 | Skia,
23 | vec,
24 | Group,
25 | PathCommand,
26 | mix,
27 | Circle,
28 | Shadow,
29 | } from '@shopify/react-native-skia'
30 |
31 | import type { AnimatedLineGraphProps } from './LineGraphProps'
32 | import { SelectionDot as DefaultSelectionDot } from './SelectionDot'
33 | import {
34 | createGraphPath,
35 | createGraphPathWithGradient,
36 | getGraphPathRange,
37 | GraphPathRange,
38 | getXInRange,
39 | getPointsInRange,
40 | } from './CreateGraphPath'
41 | import { getSixDigitHex } from './utils/getSixDigitHex'
42 | import { usePanGesture } from './hooks/usePanGesture'
43 | import { getYForX } from './GetYForX'
44 | import { hexToRgba } from './utils/hexToRgba'
45 |
46 | const INDICATOR_RADIUS = 7
47 | const INDICATOR_BORDER_MULTIPLIER = 1.3
48 | const INDICATOR_PULSE_BLUR_RADIUS_SMALL =
49 | INDICATOR_RADIUS * INDICATOR_BORDER_MULTIPLIER
50 | const INDICATOR_PULSE_BLUR_RADIUS_BIG =
51 | INDICATOR_RADIUS * INDICATOR_BORDER_MULTIPLIER + 20
52 |
53 | export function AnimatedLineGraph({
54 | points: allPoints,
55 | color,
56 | gradientFillColors,
57 | lineThickness = 3,
58 | range,
59 | enableFadeInMask,
60 | enablePanGesture = false,
61 | onPointSelected,
62 | onGestureStart,
63 | onGestureEnd,
64 | panGestureDelay = 300,
65 | SelectionDot = DefaultSelectionDot,
66 | enableIndicator = false,
67 | indicatorPulsating = false,
68 | horizontalPadding = enableIndicator
69 | ? Math.ceil(INDICATOR_RADIUS * INDICATOR_BORDER_MULTIPLIER)
70 | : 0,
71 | verticalPadding = lineThickness,
72 | TopAxisLabel,
73 | BottomAxisLabel,
74 | ...props
75 | }: AnimatedLineGraphProps): React.ReactElement {
76 | const [width, setWidth] = useState(0)
77 | const [height, setHeight] = useState(0)
78 | const interpolateProgress = useSharedValue(0)
79 |
80 | const { gesture, isActive, x } = usePanGesture({
81 | enabled: enablePanGesture,
82 | holdDuration: panGestureDelay,
83 | })
84 | const circleX = useSharedValue(0)
85 | const circleY = useSharedValue(0)
86 | const pathEnd = useSharedValue(0)
87 | const indicatorRadius = useSharedValue(enableIndicator ? INDICATOR_RADIUS : 0)
88 | const indicatorBorderRadius = useDerivedValue(
89 | () => indicatorRadius.value * INDICATOR_BORDER_MULTIPLIER
90 | )
91 |
92 | const pulseTrigger = useDerivedValue(() => (isActive.value ? 1 : 0))
93 | const indicatorPulseAnimation = useSharedValue(0)
94 | const indicatorPulseRadius = useDerivedValue(() => {
95 | if (pulseTrigger.value === 0) {
96 | return mix(
97 | indicatorPulseAnimation.value,
98 | INDICATOR_PULSE_BLUR_RADIUS_SMALL,
99 | INDICATOR_PULSE_BLUR_RADIUS_BIG
100 | )
101 | }
102 | return 0
103 | })
104 | const indicatorPulseOpacity = useDerivedValue(() => {
105 | if (pulseTrigger.value === 0) {
106 | return mix(indicatorPulseAnimation.value, 1, 0)
107 | }
108 | return 0
109 | })
110 |
111 | const positions = useDerivedValue(() => [
112 | 0,
113 | Math.min(0.15, pathEnd.value),
114 | pathEnd.value,
115 | pathEnd.value,
116 | 1,
117 | ])
118 |
119 | const onLayout = useCallback(
120 | ({ nativeEvent: { layout } }: LayoutChangeEvent) => {
121 | setWidth(Math.round(layout.width))
122 | setHeight(Math.round(layout.height))
123 | },
124 | []
125 | )
126 |
127 | const straightLine = useMemo(() => {
128 | const path = Skia.Path.Make()
129 | path.moveTo(0, height / 2)
130 | for (let i = 0; i < width - 1; i += 2) {
131 | const x = i
132 | const y = height / 2
133 | path.cubicTo(x, y, x, y, x, y)
134 | }
135 |
136 | return path
137 | }, [height, width])
138 |
139 | const paths = useSharedValue<{ from?: SkPath; to?: SkPath }>({})
140 | const gradientPaths = useSharedValue<{ from?: SkPath; to?: SkPath }>({})
141 | const commands = useSharedValue([])
142 | const [commandsChanged, setCommandsChanged] = useState(0)
143 | const pointSelectedIndex = useRef()
144 |
145 | const pathRange: GraphPathRange = useMemo(
146 | () => getGraphPathRange(allPoints, range),
147 | [allPoints, range]
148 | )
149 |
150 | const pointsInRange = useMemo(
151 | () => getPointsInRange(allPoints, pathRange),
152 | [allPoints, pathRange]
153 | )
154 |
155 | const drawingWidth = useMemo(
156 | () => width - 2 * horizontalPadding,
157 | [horizontalPadding, width]
158 | )
159 |
160 | const lineWidth = useMemo(() => {
161 | const lastPoint = pointsInRange[pointsInRange.length - 1]
162 |
163 | if (lastPoint == null) return drawingWidth
164 |
165 | return Math.max(getXInRange(drawingWidth, lastPoint.date, pathRange.x), 0)
166 | }, [drawingWidth, pathRange.x, pointsInRange])
167 |
168 | const indicatorX = useDerivedValue(
169 | () => Math.floor(lineWidth) + horizontalPadding
170 | )
171 | const indicatorY = useDerivedValue(
172 | () => getYForX(commands.value, indicatorX.value) || 0
173 | )
174 |
175 | const indicatorPulseColor = useMemo(() => hexToRgba(color, 0.4), [color])
176 |
177 | const shouldFillGradient = gradientFillColors != null
178 |
179 | useEffect(() => {
180 | if (height < 1 || width < 1) {
181 | // view is not yet measured!
182 | return
183 | }
184 | if (pointsInRange.length < 1) {
185 | // points are still empty!
186 | return
187 | }
188 |
189 | let path
190 | let gradientPath
191 |
192 | const createGraphPathProps = {
193 | pointsInRange,
194 | range: pathRange,
195 | horizontalPadding,
196 | verticalPadding,
197 | canvasHeight: height,
198 | canvasWidth: width,
199 | }
200 |
201 | if (shouldFillGradient) {
202 | const { path: pathNew, gradientPath: gradientPathNew } =
203 | createGraphPathWithGradient(createGraphPathProps)
204 |
205 | path = pathNew
206 | gradientPath = gradientPathNew
207 | } else {
208 | path = createGraphPath(createGraphPathProps)
209 | }
210 |
211 | commands.value = path.toCmds()
212 |
213 | if (gradientPath != null) {
214 | const previous = gradientPaths.value
215 | let from: SkPath = previous.to ?? straightLine
216 | if (previous.from != null && interpolateProgress.value < 1)
217 | from =
218 | from.interpolate(previous.from, interpolateProgress.value) ?? from
219 |
220 | if (gradientPath.isInterpolatable(from)) {
221 | gradientPaths.value = {
222 | from,
223 | to: gradientPath,
224 | }
225 | } else {
226 | gradientPaths.value = {
227 | from: gradientPath,
228 | to: gradientPath,
229 | }
230 | }
231 | }
232 |
233 | const previous = paths.value
234 | let from: SkPath = previous.to ?? straightLine
235 | if (previous.from != null && interpolateProgress.value < 1)
236 | from = from.interpolate(previous.from, interpolateProgress.value) ?? from
237 |
238 | if (path.isInterpolatable(from)) {
239 | paths.value = {
240 | from,
241 | to: path,
242 | }
243 | } else {
244 | paths.value = {
245 | from: path,
246 | to: path,
247 | }
248 | }
249 |
250 | setCommandsChanged(commandsChanged + 1)
251 |
252 | interpolateProgress.value = withSpring(1, {
253 | mass: 1,
254 | stiffness: 500,
255 | damping: 400,
256 | velocity: 0,
257 | })
258 | // eslint-disable-next-line react-hooks/exhaustive-deps
259 | }, [
260 | height,
261 | horizontalPadding,
262 | interpolateProgress,
263 | pathRange,
264 | paths,
265 | shouldFillGradient,
266 | gradientPaths,
267 | pointsInRange,
268 | range,
269 | straightLine,
270 | verticalPadding,
271 | width,
272 | ])
273 |
274 | const gradientColors = useMemo(() => {
275 | if (enableFadeInMask) {
276 | return [
277 | `${getSixDigitHex(color)}00`,
278 | `${getSixDigitHex(color)}ff`,
279 | `${getSixDigitHex(color)}ff`,
280 | `${getSixDigitHex(color)}33`,
281 | `${getSixDigitHex(color)}33`,
282 | ]
283 | }
284 | return [
285 | color,
286 | color,
287 | color,
288 | `${getSixDigitHex(color)}33`,
289 | `${getSixDigitHex(color)}33`,
290 | ]
291 | }, [color, enableFadeInMask])
292 |
293 | const path = useDerivedValue(
294 | () => {
295 | const from = paths.value.from ?? straightLine
296 | const to = paths.value.to ?? straightLine
297 |
298 | return to.interpolate(from, interpolateProgress.value)
299 | },
300 | // RN Skia deals with deps differently. They are actually the required SkiaValues that the derived value listens to, not react values.
301 | [interpolateProgress]
302 | )
303 |
304 | const gradientPath = useDerivedValue(
305 | () => {
306 | const from = gradientPaths.value.from ?? straightLine
307 | const to = gradientPaths.value.to ?? straightLine
308 |
309 | return to.interpolate(from, interpolateProgress.value)
310 | },
311 | // RN Skia deals with deps differently. They are actually the required SkiaValues that the derived value listens to, not react values.
312 | [interpolateProgress]
313 | )
314 |
315 | const stopPulsating = useCallback(() => {
316 | cancelAnimation(indicatorPulseAnimation)
317 | indicatorPulseAnimation.value = 0
318 | }, [indicatorPulseAnimation])
319 |
320 | const startPulsating = useCallback(() => {
321 | indicatorPulseAnimation.value = withRepeat(
322 | withDelay(
323 | 1000,
324 | withSequence(
325 | withTiming(1, { duration: 1100 }),
326 | withTiming(0, { duration: 0 }), // revert to 0
327 | withTiming(0, { duration: 1200 }), // delay between pulses
328 | withTiming(1, { duration: 1100 }),
329 | withTiming(1, { duration: 2000 }) // delay after both pulses
330 | )
331 | ),
332 | -1
333 | )
334 | }, [indicatorPulseAnimation])
335 |
336 | const setFingerPoint = useCallback(
337 | (fingerX: number) => {
338 | const fingerXInRange = Math.max(fingerX - horizontalPadding, 0)
339 |
340 | const index = Math.round(
341 | (fingerXInRange /
342 | getXInRange(
343 | drawingWidth,
344 | pointsInRange[pointsInRange.length - 1]!.date,
345 | pathRange.x
346 | )) *
347 | (pointsInRange.length - 1)
348 | )
349 | const pointIndex = Math.min(Math.max(index, 0), pointsInRange.length - 1)
350 |
351 | if (pointSelectedIndex.current !== pointIndex) {
352 | const dataPoint = pointsInRange[pointIndex]
353 | pointSelectedIndex.current = pointIndex
354 |
355 | if (dataPoint != null) {
356 | onPointSelected?.(dataPoint)
357 | }
358 | }
359 | },
360 | [
361 | drawingWidth,
362 | horizontalPadding,
363 | onPointSelected,
364 | pathRange.x,
365 | pointsInRange,
366 | ]
367 | )
368 |
369 | const setFingerX = useCallback(
370 | (fingerX: number) => {
371 | 'worklet'
372 |
373 | const y = getYForX(commands.value, fingerX)
374 |
375 | if (y != null) {
376 | circleX.value = fingerX
377 | circleY.value = y
378 | }
379 |
380 | if (isActive.value) pathEnd.value = fingerX / width
381 | },
382 | // pathRange.x must be extra included in deps otherwise onPointSelected doesn't work, IDK why
383 | // eslint-disable-next-line react-hooks/exhaustive-deps
384 | [circleX, circleY, isActive, pathEnd, pathRange.x, width, commands]
385 | )
386 |
387 | const setIsActive = useCallback(
388 | (active: boolean) => {
389 | indicatorRadius.value = withSpring(!active ? INDICATOR_RADIUS : 0, {
390 | mass: 1,
391 | stiffness: 1000,
392 | damping: 50,
393 | velocity: 0,
394 | })
395 |
396 | if (active) {
397 | onGestureStart?.()
398 | stopPulsating()
399 | } else {
400 | onGestureEnd?.()
401 | pointSelectedIndex.current = undefined
402 | pathEnd.value = 1
403 | startPulsating()
404 | }
405 | },
406 | [
407 | indicatorRadius,
408 | onGestureEnd,
409 | onGestureStart,
410 | pathEnd,
411 | startPulsating,
412 | stopPulsating,
413 | ]
414 | )
415 |
416 | useAnimatedReaction(
417 | () => x.value,
418 | (fingerX) => {
419 | if (isActive.value || fingerX) {
420 | setFingerX(fingerX)
421 | runOnJS(setFingerPoint)(fingerX)
422 | }
423 | },
424 | [isActive, setFingerX, width, x]
425 | )
426 |
427 | useAnimatedReaction(
428 | () => isActive.value,
429 | (active) => {
430 | runOnJS(setIsActive)(active)
431 | },
432 | [isActive, setIsActive]
433 | )
434 |
435 | useEffect(() => {
436 | if (pointsInRange.length !== 0 && commands.value.length !== 0)
437 | pathEnd.value = 1
438 | }, [commands, pathEnd, pointsInRange.length])
439 |
440 | useEffect(() => {
441 | if (indicatorPulsating) {
442 | startPulsating()
443 | }
444 | // eslint-disable-next-line react-hooks/exhaustive-deps
445 | }, [indicatorPulsating])
446 |
447 | const axisLabelContainerStyle = {
448 | paddingTop: TopAxisLabel != null ? 20 : 0,
449 | paddingBottom: BottomAxisLabel != null ? 20 : 0,
450 | }
451 |
452 | const indicatorVisible = enableIndicator && commandsChanged > 0
453 |
454 | return (
455 |
456 |
457 |
458 | {/* Top Label (max price) */}
459 | {TopAxisLabel != null && (
460 |
461 |
462 |
463 | )}
464 |
465 | {/* Actual Skia Graph */}
466 |
467 | {/* Fix for react-native-skia's incorrect type declarations */}
468 |
469 |
470 |
478 |
484 |
485 |
486 | {shouldFillGradient && (
487 |
491 |
496 |
497 | )}
498 |
499 |
500 | {SelectionDot != null && (
501 |
508 | )}
509 |
510 | {indicatorVisible && (
511 |
512 | {indicatorPulsating && (
513 |
521 | )}
522 |
523 |
529 |
530 |
531 |
537 |
538 | )}
539 |
540 |
541 |
542 | {/* Bottom Label (min price) */}
543 | {BottomAxisLabel != null && (
544 |
545 |
546 |
547 | )}
548 |
549 |
550 |
551 | )
552 | }
553 |
554 | const styles = StyleSheet.create({
555 | svg: {
556 | flex: 1,
557 | },
558 | container: {
559 | flex: 1,
560 | },
561 | axisRow: {
562 | height: 17,
563 | },
564 | })
565 |
--------------------------------------------------------------------------------
/src/CreateGraphPath.ts:
--------------------------------------------------------------------------------
1 | import { SkPath, Skia, SkPoint } from '@shopify/react-native-skia'
2 | import type { GraphPoint, GraphRange } from './LineGraphProps'
3 |
4 | const PIXEL_RATIO = 2
5 |
6 | export interface GraphXRange {
7 | min: Date
8 | max: Date
9 | }
10 |
11 | export interface GraphYRange {
12 | min: number
13 | max: number
14 | }
15 |
16 | export interface GraphPathRange {
17 | x: GraphXRange
18 | y: GraphYRange
19 | }
20 |
21 | type GraphPathConfig = {
22 | /**
23 | * Graph Points to use for the Path. Will be normalized and centered.
24 | */
25 | pointsInRange: GraphPoint[]
26 | /**
27 | * Optional Padding (left, right) for the Graph to correctly round the Path.
28 | */
29 | horizontalPadding: number
30 | /**
31 | * Optional Padding (top, bottom) for the Graph to correctly round the Path.
32 | */
33 | verticalPadding: number
34 | /**
35 | * Height of the Canvas (Measured with onLayout)
36 | */
37 | canvasHeight: number
38 | /**
39 | * Width of the Canvas (Measured with onLayout)
40 | */
41 | canvasWidth: number
42 | /**
43 | * Range of the graph's x and y-axis
44 | */
45 | range: GraphPathRange
46 | }
47 |
48 | type GraphPathConfigWithGradient = GraphPathConfig & {
49 | shouldFillGradient: true
50 | }
51 | type GraphPathConfigWithoutGradient = GraphPathConfig & {
52 | shouldFillGradient: false
53 | }
54 |
55 | export function getGraphPathRange(
56 | points: GraphPoint[],
57 | range?: GraphRange
58 | ): GraphPathRange {
59 | const minValueX = range?.x?.min ?? points[0]?.date ?? new Date()
60 | const maxValueX =
61 | range?.x?.max ?? points[points.length - 1]?.date ?? new Date()
62 |
63 | const minValueY =
64 | range?.y?.min ??
65 | points.reduce(
66 | (prev, curr) => (curr.value < prev ? curr.value : prev),
67 | Number.MAX_SAFE_INTEGER
68 | )
69 | const maxValueY =
70 | range?.y?.max ??
71 | points.reduce(
72 | (prev, curr) => (curr.value > prev ? curr.value : prev),
73 | Number.MIN_SAFE_INTEGER
74 | )
75 |
76 | return {
77 | x: { min: minValueX, max: maxValueX },
78 | y: { min: minValueY, max: maxValueY },
79 | }
80 | }
81 |
82 | export const getXPositionInRange = (
83 | date: Date,
84 | xRange: GraphXRange
85 | ): number => {
86 | const diff = xRange.max.getTime() - xRange.min.getTime()
87 | const x = date.getTime()
88 |
89 | return (x - xRange.min.getTime()) / diff
90 | }
91 |
92 | export const getXInRange = (
93 | width: number,
94 | date: Date,
95 | xRange: GraphXRange
96 | ): number => {
97 | return Math.floor(width * getXPositionInRange(date, xRange))
98 | }
99 |
100 | export const getYPositionInRange = (
101 | value: number,
102 | yRange: GraphYRange
103 | ): number => {
104 | const diff = yRange.max - yRange.min
105 | const y = value
106 |
107 | return (y - yRange.min) / diff
108 | }
109 |
110 | export const getYInRange = (
111 | height: number,
112 | value: number,
113 | yRange: GraphYRange
114 | ): number => {
115 | return Math.floor(height * getYPositionInRange(value, yRange))
116 | }
117 |
118 | export const getPointsInRange = (
119 | allPoints: GraphPoint[],
120 | range: GraphPathRange
121 | ) => {
122 | return allPoints.filter((point) => {
123 | const portionFactorX = getXPositionInRange(point.date, range.x)
124 | return portionFactorX <= 1 && portionFactorX >= 0
125 | })
126 | }
127 |
128 | type GraphPathWithGradient = { path: SkPath; gradientPath: SkPath }
129 |
130 | function createGraphPathBase(
131 | props: GraphPathConfigWithGradient
132 | ): GraphPathWithGradient
133 | function createGraphPathBase(props: GraphPathConfigWithoutGradient): SkPath
134 |
135 | function createGraphPathBase({
136 | pointsInRange: graphData,
137 | range,
138 | horizontalPadding,
139 | verticalPadding,
140 | canvasHeight: height,
141 | canvasWidth: width,
142 | shouldFillGradient,
143 | }: GraphPathConfigWithGradient | GraphPathConfigWithoutGradient):
144 | | SkPath
145 | | GraphPathWithGradient {
146 | const path = Skia.Path.Make()
147 |
148 | // Canvas width substracted by the horizontal padding => Actual drawing width
149 | const drawingWidth = width - 2 * horizontalPadding
150 | // Canvas height substracted by the vertical padding => Actual drawing height
151 | const drawingHeight = height - 2 * verticalPadding
152 |
153 | if (graphData[0] == null) return path
154 |
155 | const points: SkPoint[] = []
156 |
157 | const startX =
158 | getXInRange(drawingWidth, graphData[0]!.date, range.x) + horizontalPadding
159 | const endX =
160 | getXInRange(drawingWidth, graphData[graphData.length - 1]!.date, range.x) +
161 | horizontalPadding
162 |
163 | const getGraphDataIndex = (pixel: number) =>
164 | Math.round(((pixel - startX) / (endX - startX)) * (graphData.length - 1))
165 |
166 | const getNextPixelValue = (pixel: number) => {
167 | if (pixel === endX || pixel + PIXEL_RATIO < endX) return pixel + PIXEL_RATIO
168 | return endX
169 | }
170 |
171 | for (
172 | let pixel = startX;
173 | startX <= pixel && pixel <= endX;
174 | pixel = getNextPixelValue(pixel)
175 | ) {
176 | const index = getGraphDataIndex(pixel)
177 |
178 | // Draw first point only on the very first pixel
179 | if (index === 0 && pixel !== startX) continue
180 | // Draw last point only on the very last pixel
181 |
182 | if (index === graphData.length - 1 && pixel !== endX) continue
183 |
184 | if (index !== 0 && index !== graphData.length - 1) {
185 | // Only draw point, when the point is exact
186 | const exactPointX =
187 | getXInRange(drawingWidth, graphData[index]!.date, range.x) +
188 | horizontalPadding
189 |
190 | const isExactPointInsidePixelRatio = Array(PIXEL_RATIO)
191 | .fill(0)
192 | .some((_value, additionalPixel) => {
193 | return pixel + additionalPixel === exactPointX
194 | })
195 |
196 | if (!isExactPointInsidePixelRatio) continue
197 | }
198 |
199 | const value = graphData[index]!.value
200 | const y =
201 | drawingHeight -
202 | getYInRange(drawingHeight, value, range.y) +
203 | verticalPadding
204 |
205 | points.push({ x: pixel, y: y })
206 | }
207 |
208 | for (let i = 0; i < points.length; i++) {
209 | const point = points[i]!
210 |
211 | // first point needs to start the path
212 | if (i === 0) path.moveTo(point.x, point.y)
213 |
214 | const prev = points[i - 1]
215 | const prevPrev = points[i - 2]
216 |
217 | if (prev == null) continue
218 |
219 | const p0 = prevPrev ?? prev
220 | const p1 = prev
221 | const cp1x = (2 * p0.x + p1.x) / 3
222 | const cp1y = (2 * p0.y + p1.y) / 3
223 | const cp2x = (p0.x + 2 * p1.x) / 3
224 | const cp2y = (p0.y + 2 * p1.y) / 3
225 | const cp3x = (p0.x + 4 * p1.x + point.x) / 6
226 | const cp3y = (p0.y + 4 * p1.y + point.y) / 6
227 |
228 | path.cubicTo(cp1x, cp1y, cp2x, cp2y, cp3x, cp3y)
229 |
230 | if (i === points.length - 1) {
231 | path.cubicTo(point.x, point.y, point.x, point.y, point.x, point.y)
232 | }
233 | }
234 |
235 | if (!shouldFillGradient) return path
236 |
237 | const gradientPath = path.copy()
238 |
239 | gradientPath.lineTo(endX, height + verticalPadding)
240 | gradientPath.lineTo(0 + horizontalPadding, height + verticalPadding)
241 |
242 | return { path: path, gradientPath: gradientPath }
243 | }
244 |
245 | export function createGraphPath(props: GraphPathConfig): SkPath {
246 | return createGraphPathBase({ ...props, shouldFillGradient: false })
247 | }
248 |
249 | export function createGraphPathWithGradient(
250 | props: GraphPathConfig
251 | ): GraphPathWithGradient {
252 | return createGraphPathBase({
253 | ...props,
254 | shouldFillGradient: true,
255 | })
256 | }
257 |
--------------------------------------------------------------------------------
/src/GetYForX.ts:
--------------------------------------------------------------------------------
1 | import type { Vector, PathCommand } from '@shopify/react-native-skia'
2 | import { PathVerb, vec } from '@shopify/react-native-skia'
3 |
4 | // code from William Candillon
5 |
6 | const round = (value: number, precision = 0): number => {
7 | 'worklet'
8 |
9 | const p = Math.pow(10, precision)
10 | return Math.round(value * p) / p
11 | }
12 |
13 | // https://stackoverflow.com/questions/27176423/function-to-solve-cubic-equation-analytically
14 | const cuberoot = (x: number): number => {
15 | 'worklet'
16 |
17 | const y = Math.pow(Math.abs(x), 1 / 3)
18 | return x < 0 ? -y : y
19 | }
20 |
21 | const solveCubic = (a: number, b: number, c: number, d: number): number[] => {
22 | 'worklet'
23 |
24 | if (Math.abs(a) < 1e-8) {
25 | // Quadratic case, ax^2+bx+c=0
26 | a = b
27 | b = c
28 | c = d
29 | if (Math.abs(a) < 1e-8) {
30 | // Linear case, ax+b=0
31 | a = b
32 | b = c
33 | if (Math.abs(a) < 1e-8) {
34 | // Degenerate case
35 | return []
36 | }
37 | return [-b / a]
38 | }
39 |
40 | const D = b * b - 4 * a * c
41 | if (Math.abs(D) < 1e-8) return [-b / (2 * a)]
42 | if (D > 0)
43 | return [(-b + Math.sqrt(D)) / (2 * a), (-b - Math.sqrt(D)) / (2 * a)]
44 |
45 | return []
46 | }
47 |
48 | // Convert to depressed cubic t^3+pt+q = 0 (subst x = t - b/3a)
49 | const p = (3 * a * c - b * b) / (3 * a * a)
50 | const q = (2 * b * b * b - 9 * a * b * c + 27 * a * a * d) / (27 * a * a * a)
51 | let roots
52 |
53 | if (Math.abs(p) < 1e-8) {
54 | // p = 0 -> t^3 = -q -> t = -q^1/3
55 | roots = [cuberoot(-q)]
56 | } else if (Math.abs(q) < 1e-8) {
57 | // q = 0 -> t^3 + pt = 0 -> t(t^2+p)=0
58 | roots = [0].concat(p < 0 ? [Math.sqrt(-p), -Math.sqrt(-p)] : [])
59 | } else {
60 | const D = (q * q) / 4 + (p * p * p) / 27
61 | if (Math.abs(D) < 1e-8) {
62 | // D = 0 -> two roots
63 | roots = [(-1.5 * q) / p, (3 * q) / p]
64 | } else if (D > 0) {
65 | // Only one real root
66 | const u = cuberoot(-q / 2 - Math.sqrt(D))
67 | roots = [u - p / (3 * u)]
68 | } else {
69 | // D < 0, three roots, but needs to use complex numbers/trigonometric solution
70 | const u = 2 * Math.sqrt(-p / 3)
71 | const t = Math.acos((3 * q) / p / u) / 3 // D < 0 implies p < 0 and acos argument in [-1..1]
72 | const k = (2 * Math.PI) / 3
73 | roots = [u * Math.cos(t), u * Math.cos(t - k), u * Math.cos(t - 2 * k)]
74 | }
75 | }
76 |
77 | // Convert back from depressed cubic
78 | for (let i = 0; i < roots.length; i++) roots[i] -= b / (3 * a)
79 |
80 | return roots
81 | }
82 |
83 | const cubicBezier = (
84 | t: number,
85 | from: number,
86 | c1: number,
87 | c2: number,
88 | to: number
89 | ): number => {
90 | 'worklet'
91 |
92 | const term = 1 - t
93 | const a = 1 * term ** 3 * t ** 0 * from
94 | const b = 3 * term ** 2 * t ** 1 * c1
95 | const c = 3 * term ** 1 * t ** 2 * c2
96 | const d = 1 * term ** 0 * t ** 3 * to
97 | return a + b + c + d
98 | }
99 |
100 | export const cubicBezierYForX = (
101 | x: number,
102 | a: Vector,
103 | b: Vector,
104 | c: Vector,
105 | d: Vector,
106 | precision = 2
107 | ): number => {
108 | 'worklet'
109 |
110 | const pa = -a.x + 3 * b.x - 3 * c.x + d.x
111 | const pb = 3 * a.x - 6 * b.x + 3 * c.x
112 | const pc = -3 * a.x + 3 * b.x
113 | const pd = a.x - x
114 | const ts = solveCubic(pa, pb, pc, pd)
115 | .map((root) => round(root, precision))
116 | .filter((root) => root >= 0 && root <= 1)
117 | const t = ts[0]
118 | if (t == null) return 0
119 | return cubicBezier(t, a.y, b.y, c.y, d.y)
120 | }
121 |
122 | interface Cubic {
123 | from: Vector
124 | c1: Vector
125 | c2: Vector
126 | to: Vector
127 | }
128 |
129 | export const selectCurve = (
130 | cmds: PathCommand[],
131 | x: number
132 | ): Cubic | undefined => {
133 | 'worklet'
134 |
135 | let from: Vector = vec(0, 0)
136 | for (let i = 0; i < cmds.length; i++) {
137 | const cmd = cmds[i]
138 | if (cmd == null) return undefined
139 | if (cmd[0] === PathVerb.Move) {
140 | from = vec(cmd[1], cmd[2])
141 | } else if (cmd[0] === PathVerb.Cubic) {
142 | const c1 = vec(cmd[1], cmd[2])
143 | const c2 = vec(cmd[3], cmd[4])
144 | const to = vec(cmd[5], cmd[6])
145 | if (x >= from.x && x <= to.x) {
146 | return {
147 | from,
148 | c1,
149 | c2,
150 | to,
151 | }
152 | }
153 | from = to
154 | }
155 | }
156 | return undefined
157 | }
158 |
159 | export const getYForX = (
160 | cmds: PathCommand[],
161 | x: number,
162 | precision = 2
163 | ): number | undefined => {
164 | 'worklet'
165 |
166 | const c = selectCurve(cmds, x)
167 | if (c == null) return undefined
168 |
169 | return cubicBezierYForX(x, c.from, c.c1, c.c2, c.to, precision)
170 | }
171 |
--------------------------------------------------------------------------------
/src/LineGraph.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { AnimatedLineGraph } from './AnimatedLineGraph'
3 | import type { LineGraphProps } from './LineGraphProps'
4 | import { StaticLineGraph } from './StaticLineGraph'
5 |
6 | function LineGraphImpl(props: LineGraphProps): React.ReactElement {
7 | if (props.animated) return
8 | else return
9 | }
10 |
11 | export const LineGraph = React.memo(LineGraphImpl)
12 |
--------------------------------------------------------------------------------
/src/LineGraphProps.ts:
--------------------------------------------------------------------------------
1 | import type React from 'react'
2 | import type { ViewProps } from 'react-native'
3 | import type { GraphPathRange } from './CreateGraphPath'
4 | import type { SharedValue } from 'react-native-reanimated'
5 | import type { Color } from '@shopify/react-native-skia'
6 |
7 | export interface GraphPoint {
8 | value: number
9 | date: Date
10 | }
11 |
12 | export type GraphRange = Partial
13 |
14 | export interface SelectionDotProps {
15 | isActive: SharedValue
16 | color: BaseLineGraphProps['color']
17 | lineThickness: BaseLineGraphProps['lineThickness']
18 | circleX: SharedValue
19 | circleY: SharedValue
20 | }
21 |
22 | interface BaseLineGraphProps extends ViewProps {
23 | /**
24 | * All points to be marked in the graph. Coordinate system will adjust to scale automatically.
25 | */
26 | points: GraphPoint[]
27 | /**
28 | * Range of the graph's x and y-axis. The range must be greater
29 | * than the range given by the points.
30 | */
31 | range?: GraphRange
32 | /**
33 | * Color of the graph line (path)
34 | */
35 | color: string
36 | /**
37 | * (Optional) Colors for the fill gradient below the graph line
38 | */
39 | gradientFillColors?: Color[]
40 | /**
41 | * The width of the graph line (path)
42 | *
43 | * @default 3
44 | */
45 | lineThickness?: number
46 | /**
47 | * Enable the Fade-In Gradient Effect at the beginning of the Graph
48 | */
49 | enableFadeInMask?: boolean
50 | }
51 |
52 | export type StaticLineGraphProps = BaseLineGraphProps & {
53 | /* any static-only line graph props? */
54 | }
55 | export type AnimatedLineGraphProps = BaseLineGraphProps & {
56 | /**
57 | * Whether to enable Graph scrubbing/pan gesture.
58 | */
59 | enablePanGesture?: boolean
60 | /**
61 | * The color of the selection dot when the user is panning the graph.
62 | */
63 | selectionDotShadowColor?: string
64 | /**
65 | * Horizontal padding applied to graph, so the pan gesture dot doesn't get cut off horizontally
66 | */
67 | horizontalPadding?: number
68 | /**
69 | * Vertical padding applied to graph, so the pan gesture dot doesn't get cut off vertically
70 | */
71 | verticalPadding?: number
72 | /**
73 | * Enables an indicator which is displayed at the end of the graph
74 | */
75 | enableIndicator?: boolean
76 | /**
77 | * Let's the indicator pulsate
78 | */
79 | indicatorPulsating?: boolean
80 | /**
81 | * Delay after which the pan gesture starts
82 | */
83 | panGestureDelay?: number
84 |
85 | /**
86 | * Called for each point while the user is scrubbing/panning through the graph
87 | */
88 | onPointSelected?: (point: GraphPoint) => void
89 | /**
90 | * Called once the user starts scrubbing/panning through the graph
91 | */
92 | onGestureStart?: () => void
93 | /**
94 | * Called once the user stopped scrubbing/panning through the graph
95 | */
96 | onGestureEnd?: () => void
97 |
98 | /**
99 | * The element that renders the selection dot
100 | */
101 | SelectionDot?: React.ComponentType | null
102 |
103 | /**
104 | * The element that gets rendered above the Graph (usually the "max" point/value of the Graph)
105 | */
106 | TopAxisLabel?: () => React.ReactElement | null
107 |
108 | /**
109 | * The element that gets rendered below the Graph (usually the "min" point/value of the Graph)
110 | */
111 | BottomAxisLabel?: () => React.ReactElement | null
112 | }
113 |
114 | export type LineGraphProps =
115 | | ({ animated: true } & AnimatedLineGraphProps)
116 | | ({ animated: false } & StaticLineGraphProps)
117 |
--------------------------------------------------------------------------------
/src/SelectionDot.tsx:
--------------------------------------------------------------------------------
1 | import React, { useCallback } from 'react'
2 | import {
3 | runOnJS,
4 | useAnimatedReaction,
5 | useSharedValue,
6 | withSpring,
7 | useDerivedValue,
8 | } from 'react-native-reanimated'
9 | import { Circle, Group, Shadow } from '@shopify/react-native-skia'
10 | import type { SelectionDotProps } from './LineGraphProps'
11 |
12 | export const CIRCLE_RADIUS = 5
13 | export const CIRCLE_RADIUS_MULTIPLIER = 6
14 |
15 | export function SelectionDot({
16 | isActive,
17 | color,
18 | circleX,
19 | circleY,
20 | }: SelectionDotProps): React.ReactElement {
21 | const circleRadius = useSharedValue(0)
22 | const circleStrokeRadius = useDerivedValue(
23 | () => circleRadius.value * CIRCLE_RADIUS_MULTIPLIER,
24 | [circleRadius]
25 | )
26 |
27 | const setIsActive = useCallback(
28 | (active: boolean) => {
29 | circleRadius.value = withSpring(active ? CIRCLE_RADIUS : 0, {
30 | mass: 1,
31 | stiffness: 1000,
32 | damping: 50,
33 | velocity: 0,
34 | })
35 | },
36 | [circleRadius]
37 | )
38 |
39 | useAnimatedReaction(
40 | () => isActive.value,
41 | (active) => {
42 | runOnJS(setIsActive)(active)
43 | },
44 | [isActive, setIsActive]
45 | )
46 |
47 | return (
48 |
49 |
56 |
57 |
58 |
59 |
60 | )
61 | }
62 |
--------------------------------------------------------------------------------
/src/StaticLineGraph.tsx:
--------------------------------------------------------------------------------
1 | import { Canvas, LinearGradient, Path, vec } from '@shopify/react-native-skia'
2 | import { getSixDigitHex } from './utils/getSixDigitHex'
3 | import React, { useCallback, useMemo, useState } from 'react'
4 | import { View, StyleSheet, LayoutChangeEvent } from 'react-native'
5 | import {
6 | createGraphPath,
7 | getGraphPathRange,
8 | getPointsInRange,
9 | GraphPathRange,
10 | } from './CreateGraphPath'
11 | import type { StaticLineGraphProps } from './LineGraphProps'
12 |
13 | export function StaticLineGraph({
14 | points: allPoints,
15 | range,
16 | color,
17 | lineThickness = 3,
18 | enableFadeInMask,
19 | style,
20 | ...props
21 | }: StaticLineGraphProps): React.ReactElement {
22 | const [width, setWidth] = useState(0)
23 | const [height, setHeight] = useState(0)
24 |
25 | const onLayout = useCallback(
26 | ({ nativeEvent: { layout } }: LayoutChangeEvent) => {
27 | setWidth(Math.round(layout.width))
28 | setHeight(Math.round(layout.height))
29 | },
30 | []
31 | )
32 |
33 | const pathRange: GraphPathRange = useMemo(
34 | () => getGraphPathRange(allPoints, range),
35 | [allPoints, range]
36 | )
37 |
38 | const pointsInRange = useMemo(
39 | () => getPointsInRange(allPoints, pathRange),
40 | [allPoints, pathRange]
41 | )
42 |
43 | const path = useMemo(
44 | () =>
45 | createGraphPath({
46 | pointsInRange: pointsInRange,
47 | range: pathRange,
48 | canvasHeight: height,
49 | canvasWidth: width,
50 | horizontalPadding: lineThickness,
51 | verticalPadding: lineThickness,
52 | }),
53 | [height, lineThickness, pathRange, pointsInRange, width]
54 | )
55 |
56 | const gradientColors = useMemo(
57 | () => [`${getSixDigitHex(color)}00`, `${getSixDigitHex(color)}ff`],
58 | [color]
59 | )
60 | const gradientFrom = useMemo(() => vec(0, 0), [])
61 | const gradientTo = useMemo(() => vec(width * 0.15, 0), [width])
62 |
63 | return (
64 |
65 | {/* Fix for react-native-skia's incorrect type declarations */}
66 |
67 |
75 | {enableFadeInMask && (
76 |
81 | )}
82 |
83 |
84 |
85 | )
86 | }
87 |
88 | const styles = StyleSheet.create({
89 | svg: {
90 | flex: 1,
91 | },
92 | })
93 |
--------------------------------------------------------------------------------
/src/hooks/usePanGesture.ts:
--------------------------------------------------------------------------------
1 | import { useMemo } from 'react'
2 | import { Gesture, PanGesture } from 'react-native-gesture-handler'
3 | import Reanimated, { useSharedValue } from 'react-native-reanimated'
4 |
5 | interface Config {
6 | enabled: boolean
7 | holdDuration: number
8 | }
9 |
10 | interface Result {
11 | x: Reanimated.SharedValue
12 | y: Reanimated.SharedValue
13 | isActive: Reanimated.SharedValue
14 | gesture: PanGesture
15 | }
16 |
17 | export function usePanGesture({ enabled, holdDuration = 300 }: Config): Result {
18 | const x = useSharedValue(0)
19 | const y = useSharedValue(0)
20 | const isPanGestureActive = useSharedValue(false)
21 |
22 | const panGesture = useMemo(
23 | () =>
24 | Gesture.Pan()
25 | .enabled(enabled)
26 | .activateAfterLongPress(holdDuration)
27 | .onChange((e) => {
28 | x.value = e.x
29 | y.value = e.y
30 | })
31 | .onStart(() => {
32 | isPanGestureActive.value = true
33 | })
34 | .onEnd(() => {
35 | isPanGestureActive.value = false
36 | }),
37 | [enabled, holdDuration, isPanGestureActive, x, y]
38 | )
39 |
40 | return useMemo(
41 | () => ({
42 | gesture: panGesture,
43 | isActive: isPanGestureActive,
44 | x: x,
45 | y: y,
46 | }),
47 | [isPanGestureActive, panGesture, x, y]
48 | )
49 | }
50 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './SelectionDot'
2 | export * from './LineGraph'
3 | export type {
4 | GraphPoint,
5 | LineGraphProps,
6 | SelectionDotProps,
7 | } from './LineGraphProps'
8 |
--------------------------------------------------------------------------------
/src/utils/getSixDigitHex.ts:
--------------------------------------------------------------------------------
1 | export function getSixDigitHex(color: string): `#${string}` {
2 | if (!color.startsWith('#'))
3 | throw new Error(`react-native-graph: "${color}" is not a valid hex color!`)
4 | const hexColor = color.substring(1) // removes '#'
5 |
6 | switch (hexColor.length) {
7 | case 3: {
8 | const sixDigitHex = hexColor
9 | .split('')
10 | .map((hex) => hex + hex)
11 | .join('')
12 | return `#${sixDigitHex}`
13 | }
14 | case 6:
15 | return `#${hexColor}`
16 | case 8:
17 | return `#${hexColor.substring(0, 6)}`
18 | default:
19 | throw new Error(
20 | `react-native-graph: Cannot convert "${color}" to a six-digit hex color!`
21 | )
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/utils/hexToRgba.ts:
--------------------------------------------------------------------------------
1 | export function hexToRgba(hex: string, alpha: number) {
2 | const r = parseInt(hex.slice(1, 3), 16)
3 | const g = parseInt(hex.slice(3, 5), 16)
4 | const b = parseInt(hex.slice(5, 7), 16)
5 |
6 | if (alpha > 0) {
7 | return `rgba(${r}, ${g}, ${b}, ${alpha})`
8 | }
9 |
10 | return `rgb(${r}, ${g}, ${b})`
11 | }
12 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowJs": false,
4 | "allowUnreachableCode": false,
5 | "allowUnusedLabels": false,
6 | "esModuleInterop": true,
7 | "forceConsistentCasingInFileNames": true,
8 | "jsx": "react-native",
9 | "lib": [
10 | "esnext"
11 | ],
12 | "module": "esnext",
13 | "moduleResolution": "node",
14 | "noFallthroughCasesInSwitch": true,
15 | "noImplicitReturns": true,
16 | "noStrictGenericChecks": false,
17 | "noUnusedLocals": true,
18 | "noUnusedParameters": true,
19 | "noUncheckedIndexedAccess": true,
20 | "resolveJsonModule": true,
21 | "skipLibCheck": true,
22 | "strict": true,
23 | "target": "esnext",
24 | "outDir": "lib"
25 | },
26 | "include": [
27 | "src",
28 | ".eslintrc.js",
29 | "babel.config.js",
30 | ],
31 | "exclude": [
32 | "node_modules",
33 | "lib",
34 | "docs",
35 | "example"
36 | ]
37 | }
38 |
--------------------------------------------------------------------------------