Skip to content

Commit

Permalink
Feat: Add support for Expo web (#330)
Browse files Browse the repository at this point in the history
  • Loading branch information
robwalkerco authored Aug 15, 2024
1 parent ea4a2b8 commit 34bc324
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 28 deletions.
6 changes: 6 additions & 0 deletions .changeset/fair-bees-rush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"example": minor
"victory-native": minor
---

Added support for Expo web as a platform
1 change: 1 addition & 0 deletions example/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"assetBundlePatterns": [
"**/*"
],
"platforms": ["android", "ios", "web"],
"ios": {
"supportsTablet": true,
"userInterfaceStyle": "automatic",
Expand Down
18 changes: 9 additions & 9 deletions example/app/pie-and-donut-charts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ const PieChartMultipleDataPoints = () => {
</PolarChart>
<View style={styles.legend}>
{data.map((d, i) => (
<View key={i} style={[styles.legendItemContainer]}>
<Canvas style={[styles.legendItemCanvas]}>
<View key={i} style={styles.legendItemContainer}>
<Canvas style={styles.legendItemCanvas}>
<Circle
c={vec(
styles.legendItemCanvas.height / 2,
Expand All @@ -147,7 +147,7 @@ const PieChartMultipleDataPoints = () => {
color={d.color}
/>
</Canvas>
<Text style={[]}>{d.label}</Text>
<Text>{d.label}</Text>
</View>
))}
</View>
Expand Down Expand Up @@ -275,13 +275,13 @@ const PieChartSimpleCustomLegend = () => {
alignItems: "center",
}}
>
<Canvas style={[{ height: 12, width: 12, marginRight: 4 }]}>
<Canvas style={{ height: 12, width: 12, marginRight: 4 }}>
<Rect
rect={{ x: 0, y: 0, width: 12, height: 12 }}
color={d.color}
/>
</Canvas>
<Text style={{}}>{d.label}</Text>
<Text>{d.label}</Text>
</View>
);
})}
Expand Down Expand Up @@ -344,20 +344,20 @@ export default function PieAndDonutCharts(props: { segment: string }) {
<Text style={styles.title}>Pie Chart with Single Data Point</Text>
<PieChartSingleDataPoint />
</View>
<View style={[styles.chartContainer]}>
<View style={styles.chartContainer}>
<Text style={styles.title}>Pie Chart with Multiple Data Points</Text>
<PieChartMultipleDataPoints />
</View>

<View style={[styles.chartContainer]}>
<View style={styles.chartContainer}>
<Text style={styles.title}>Pie Chart with Insets</Text>
<PieChartWithInsets />
</View>
<View style={[styles.chartContainer]}>
<View style={styles.chartContainer}>
<Text style={styles.title}>Pie Chart with Custom Legend</Text>
<PieChartSimpleCustomLegend />
</View>
<View style={[styles.chartContainer]}>
<View style={styles.chartContainer}>
<Text style={styles.title}>Half Donut Chart</Text>
<HalfDonutChart />
</View>
Expand Down
5 changes: 4 additions & 1 deletion example/app/stock-price.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,10 @@ const ActiveValueIndicator = ({
() => "$" + activeValue.value.toFixed(2),
);
const activeValueWidth = useDerivedValue(
() => font?.measureText(activeValueDisplay.value).width || 0,
() =>
font
?.getGlyphWidths?.(font.getGlyphIDs(activeValueDisplay.value))
.reduce((sum, value) => sum + value, 0) || 0,
);
const activeValueX = useDerivedValue(
() => xPosition.value - activeValueWidth.value / 2,
Expand Down
18 changes: 18 additions & 0 deletions example/index.web.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import "@expo/metro-runtime";
import { App } from "expo-router/build/qualified-entry";
import { renderRootComponent } from "expo-router/build/renderRootComponent";

// eslint-disable-next-line import/no-unresolved
import { version } from "canvaskit-wasm/package.json";

import { LoadSkiaWeb } from "@shopify/react-native-skia/lib/module/web";

// When used on the web, we need to load the CanvasKit WASM file before rendering content
// For simplicity, we are using a CDN to load the file, but it can be hosted on your own server as well
// See https://shopify.github.io/react-native-skia/docs/getting-started/web for more details
LoadSkiaWeb({
locateFile: (file) =>
`https://cdn.jsdelivr.net/npm/canvaskit-wasm@${version}/bin/full/${file}`,
}).then(async () => {
renderRootComponent(App);
});
11 changes: 8 additions & 3 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@
"main": "index.js",
"scripts": {
"start": "expo start -c",
"android": "expo run:android",
"ios": "expo run:ios"
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web"
},
"dependencies": {
"@expo/metro-runtime": "~3.2.1",
"@expo/vector-icons": "^14.0.0",
"@gorhom/bottom-sheet": "^4",
"@react-native-community/slider": "4.5.2",
"@react-native-community/slider": "4.4.2",
"@react-native-segmented-control/segmented-control": "2.5.2",
"@shopify/react-native-skia": "1.2.3",
"canvaskit-wasm": "^0.39.1",
"date-fns": "^2.30.0",
"expo": "^51.0.0",
"expo-asset": "~10.0.6",
Expand All @@ -24,13 +27,15 @@
"expo-splash-screen": "~0.27.4",
"expo-status-bar": "~1.12.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-fast-compare": "^3.2.2",
"react-native": "0.74.1",
"react-native-dark": "^0.1.4",
"react-native-gesture-handler": "~2.16.0",
"react-native-reanimated": "3.10.0",
"react-native-safe-area-context": "4.10.1",
"react-native-screens": "3.31.1",
"react-native-web": "~0.19.10",
"react-native-wheel-color-picker": "^1.2.0"
},
"devDependencies": {
Expand Down
10 changes: 8 additions & 2 deletions lib/src/cartesian/components/CartesianAxis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,10 @@ export const CartesianAxis = <

const yAxisNodes = yTicksNormalized.map((tick) => {
const contentY = formatYLabel(tick as never);
const labelWidth = font?.measureText?.(contentY).width ?? 0;
const labelWidth =
font
?.getGlyphWidths?.(font.getGlyphIDs(contentY))
.reduce((sum, value) => sum + value, 0) ?? 0;
const labelY = yScale(tick) + fontSize / 3;
const labelX = (() => {
// left, outset
Expand Down Expand Up @@ -166,7 +169,10 @@ export const CartesianAxis = <
const xAxisNodes = xTicksNormalized.map((tick) => {
const val = isNumericalData ? tick : ix[tick];
const contentX = formatXLabel(val as never);
const labelWidth = font?.measureText?.(contentX).width ?? 0;
const labelWidth =
font
?.getGlyphWidths?.(font.getGlyphIDs(contentX))
.reduce((sum, value) => sum + value, 0) ?? 0;
const labelX = xScale(tick) - (labelWidth ?? 0) / 2;
const canFitLabelContent =
yAxisPosition === "left" ? labelX + labelWidth < x2r : x1r < labelX;
Expand Down
11 changes: 8 additions & 3 deletions lib/src/cartesian/utils/transformInputData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,14 @@ export const transformInputData = <
const maxYLabel = Math.max(
...yTicksNormalized.map(
(yTick) =>
axisOptions?.font?.measureText(
axisOptions?.formatYLabel?.(yTick as RawData[YK]) || String(yTick),
).width ?? 0,
axisOptions?.font
?.getGlyphWidths?.(
axisOptions.font.getGlyphIDs(
axisOptions?.formatYLabel?.(yTick as RawData[YK]) ||
String(yTick),
),
)
.reduce((sum, value) => sum + value, 0) ?? 0,
),
);

Expand Down
6 changes: 3 additions & 3 deletions lib/src/polar/PolarChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ const PolarChartBase = (
const ctx = usePolarChartContext();

return (
<View style={[styles.baseContainer, {}, containerStyle]}>
<View style={[styles.baseContainer, containerStyle]}>
<Canvas
onLayout={onLayout}
style={[
style={StyleSheet.flatten([
styles.canvasContainer,
hasMeasuredLayoutSize ? { width, height } : null,
canvasStyle,
]}
])}
>
{/* https://shopify.github.io/react-native-skia/docs/canvas/contexts/
we have to re-inject our context to make it available in the skia renderer
Expand Down
Loading

0 comments on commit 34bc324

Please sign in to comment.