# 📈 Passing data to view
### Navigation
- [🏡 Native modules made easy with Expo](/gYH9xz-oR2ai0Yih8if50w)
- [👶 First Steps](/ANE6NSUlTSimTIrN-gMsBw)
- [👉 ⚙️ Native Module](/mAIt0ctDTvSL5xV4uE9nWQ)
- [📈 Passing data to view](/_gWWp8uoQwGkqKcEyfk8Tg)
- [📚 View Props](/96IjlLNDRvydILdkbfaA5A)
- [🔥 View Events](/PQWXYmxLRCebmLfx3Fh_gg)
- [🏞️ View Functions](/DcjStCFdT6euzWqnJqCL6w)
- [👷♂️ Classes and Shared Objects](/__42gVw8RqiIgfSbVseIvw)
- [📊 Views and shared object](/IgHyIAHQQPCbeBD74Ri4BA)
---
### Task 1
Export from the `LinearChartModule` view with an empty line chart inside.
:::spoiler :robot_face: Android
:open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/LinearChartModule.kt`
```kotlin
View(LinearChartView::class) {
}
```
:open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/LinearChartView.kt`
```kotlin
// ...
class LinearChartView(
context: Context,
appContext: AppContext
) : ExpoView(context, appContext) {
private val chartView = LineChart(context)
init {
chartView.applyDefaultSettings()
addView(chartView, ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT
))
}
}
```
:::
:::spoiler :apple: iOS
:open_file_folder: File `ios/LinearChartModule.swift`
```swift
View(LinearChartView.self) {
}
```
:open_file_folder: File `ios/LinearChartView.swift`
```swift
import ExpoModulesCore
import Charts
class LinearChartView: ExpoView {
let chartView = LineChartView(frame: .zero)
public required init(appContext: AppContext? = nil) {
super.init(appContext: appContext)
chartView.applyDefaultSettings()
addSubview(chartView)
}
}
```
:::
<br />
📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/3f552d0bf7ecf507f9389cd35ac6c629bfb1edfb)
---
### Task 2
To represent chart data, we will create records: `DataEntry` and `LinearDataSeries`. The `DataEntry` record should include an `x` and `y` value, while the `LinearDataSeries` record should (for now) have a single property called `values` that contains a list of `DataEntry`.
:::spoiler :robot_face: Android
:open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/LinearChartModule.kt`
```kotlin
data class DataEntry(
@Field val x: Float,
@Field val y: Float
) : Record
class LinearDataSeries : Record {
@Field
val values: List<DataEntry> = emptyList()
}
```
:::
:::spoiler :apple: iOS
:open_file_folder: File `ios/LinearChartModule.swift`
```swift
struct DataEntry : Record {
@Field
var x: Double
@Field
var y: Double
}
struct LinearDataSeries : Record {
@Field
var values: [DataEntry]
}
```
:::
<br />
📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/5a42c26323d61a44c7e0753704d789f1db709d18)
---
### Task 3
Export a prop called `data` that receives the `LinearDataSeries` class. After that, attach provided data to view using the `LineChart.applyNewData` function.
:::spoiler result

:::
:::spoiler :robot_face: Android
:open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/LinearChartModule.kt`
```kotlin
Prop("data") { view: LinearChartView, series: LinearDataSeries? ->
if (series != null) {
view.setSeries(series)
}
}
```
```kotlin
fun setSeries(series: LinearDataSeries) {
val dataSet = LineDataSet(
series.values.map { Entry(it.x, it.y) },
"label"
)
dataSet.apply {
applyDefaultSettings()
}
chartView.applyNewData(dataSet)
}
```
:::
:::spoiler :apple: iOS
:open_file_folder: File `ios/LinearChartModule.swift`
```swift
Prop("data") { (view: LinearChartView, series: LinearDataSeries?) in
if let series = series {
view.setSeries(series)
}
}
```
```swift
func setSeries(_ series: LinearDataSeries) {
let dataSet = LineChartDataSet(
entries: series.values.map { ChartDataEntry(x: $0.x, y: $0.y) },
label: "label"
)
dataSet.applyDefaultSettings()
chartView.applyNewData(dataSet: dataSet)
}
```
:::
<br />
📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/d273cb05cfaa792cc99be9c791642d2f10ac3c4e)
---
### Task 4
Extend the existing `LinearDataSeries` class to contain fields:
- `label`
- `lineWidth`
- `textSize`
:::spoiler :robot_face: Android
:open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/LinearChartModule.kt`
```kotlin
class LinearDataSeries : Record {
@Field
@Required
val values: List<DataEntry> = emptyList()
@Field
@Required
val label: String = ""
@Field
val lineWidth: Float = 5f
@Field
val textSize: Float = 10f
}
```
```kotlin
fun setSeries(series: LinearDataSeries) {
val dataSet = LineDataSet(
series.values.map { Entry(it.x, it.y) },
series.label
)
dataSet.apply {
applyDefaultSettings()
valueTextSize = series.textSize
lineWidth = series.lineWidth
}
chartView.applyNewData(dataSet)
}
```
:::
:::spoiler :apple: iOS
:open_file_folder: File `ios/LinearChartModule.swift`
```swift
struct LinearDataSeries : Record {
@Field
var values: [DataEntry]
@Field
var label: String
@Field
var lineWidth = 5.0
@Field
var textSize = 10.0
}
```
```swift
func setSeries(_ series: LinearDataSeries) {
let dataSet = LineChartDataSet(
entries: series.values.map { ChartDataEntry(x: $0.x, y: $0.y) },
label: "label"
)
dataSet.applyDefaultSettings()
dataSet.valueFont = dataSet.valueFont.withSize(series.textSize) // <-
dataSet.lineWidth = series.lineWidth // <-
chartView.applyNewData(dataSet: dataSet)
}
```
:::
<br />
📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/25a02b69d06c79ee9fbf6e79a88051c6892293c8)
---
### Task 5
Create an enum representing a chart mode and integrate it with the `LinearDataSeries` class.
Chart mode is an enum provided by the `MPAndroidChart`/`Chart` library. You should write a wrapper that operates on integers and can be converted to library representation.
TypeScript representation of the `DataMode`:
```typescript
export enum DataMode {
LINEAR = 0,
STEPPED = 1,
CUBIC_BEZIER = 2,
HORIZONTAL_BEZIER = 3,
}
```
:::spoiler :robot_face: Android
:open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/LinearChartModule.kt`
```kotlin
enum class DataMode(val value: Int) : Enumerable {
LINEAR(0),
STEPPED(1),
CUBIC_BEZIER(2),
HORIZONTAL_BEZIER(3);
fun toLineDataSetMode(): Mode {
return when (this) {
LINEAR -> Mode.LINEAR
STEPPED -> Mode.STEPPED
CUBIC_BEZIER -> Mode.CUBIC_BEZIER
HORIZONTAL_BEZIER -> Mode.HORIZONTAL_BEZIER
}
}
}
```
```kotlin
class LinearDataSeries : Record {
// ...
@Field
val mode: DataMode = DataMode.LINEAR
}
```
```kotlin
fun setSeries(series: LinearDataSeries) {
val dataSet = LineDataSet(
series.values.map { Entry(it.x, it.y) },
series.label
)
dataSet.apply {
applyDefaultSettings()
mode = series.mode.toLineDataSetMode() // <-
valueTextSize = series.textSize
lineWidth = series.lineWidth
}
chartView.applyNewData(dataSet)
}
```
:::
:::spoiler :apple: iOS
:open_file_folder: File `ios/LinearChartModule.swift`
```swift
enum DataMode : Int, Enumerable {
case LINEAR = 0, STEPPED, CUBIC_BEZIER, HORIZONTAL_BEZIER
func toLineDataSetMode() -> LineChartDataSet.Mode {
switch self {
case .LINEAR: return .linear
case .CUBIC_BEZIER: return .cubicBezier
case .HORIZONTAL_BEZIER: return .horizontalBezier
case .STEPPED: return .stepped
}
}
}
```
```swift
struct LinearDataSeries : Record {
// ...
@Field
var mode: DataMode = DataMode.LINEAR
}
```
```swift
func setSeries(_ series: LinearDataSeries) {
let dataSet = LineChartDataSet(
entries: series.values.map { ChartDataEntry(x: $0.x, y: $0.y) },
label: "label"
)
dataSet.applyDefaultSettings()
dataSet.mode = series.mode.toLineDataSetMode() // <-
dataSet.valueFont = dataSet.valueFont.withSize(series.textSize)
dataSet.lineWidth = series.lineWidth
chartView.applyNewData(dataSet: dataSet)
}
```
:::
<br />
📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/96a7f56cea2addb762158f3ac46dfc088dbfdbd7)
---
### [📚 View Props](/96IjlLNDRvydILdkbfaA5A)