Fork me on GitHub
#reagent
<
2020-06-25
>
lepistane13:06:06

oke what am i doing wrong i am trying to adopt this example to cljsrn (react native app) https://github.com/wuxudong/react-native-charts-wrapper/blob/master/Example/app/LiveUpdateChartScreen.js i tried it with

(defn line-chart []
  (let [values (rf/subscribe [:graph/data :line])]
    [:> rn/View {:flex 7}
     [:> charts/LineChart {:style {:flex 1
                                   :background-color :red}
                           :data (clj->js {:dataSets [{:values @values,
                                                       :label "A"
                                                       :config {:lineWidth 2
                                                                :dashedLine {:lineLength 10
                                                                             :spaceLength 10
                                                                             :phase 0}
                                                                :color (rn/processColor "white")}}]})
                           :border-color (rn/processColor "red")
                           :border-width 2
                           ;; :draw-borders true
                           :touch-enabled true
                           :drag-enabled true
                           :scale-enabled true
                           :scale-x-enabled true
                           :scale-y-enabled true
                           :pinch-zoom true
                           :double-tap-to-zoom-enabled true
                           :highlightPerTapEnabled true
                           :highlightPerDragEnabled true
                           :dragDecelerationEnabled true
                           :legend {:enabled false}
                           :chartDescription {:text ""}
                           :xAxis {:valueFormatter "date"
                                   :valueFormatterPattern "HH:mm"}

                           }]]))
Chart doesn't update everytime change to graph/data :line happens. Chart gets updated every 4-5 updates. So i get 4 pieces of data and on 5th update it renders everything. then i thought ok maybe i need to create wrapper and manage state myself so i did

lepistane13:06:06

(defn line-chart []
  (let [chart-ref (atom nil)


        update  (fn [comp]
                  (let [{:keys [values]} (r/props comp)]
                    (prn "update: ")
                    (.setState ^js @chart-ref (clj->js {:values values}))
                    (prn (goog-obj/get @chart-ref "state"))
                    ))]
    (r/create-class {:reagent-render (fn []
                                       [:> rn/View {:flex 6}
                                        [:> charts/LineChart {:ref #(reset! chart-ref %)
                                                              :style {:flex 1
                                                                      :background-color :red}
                                                              :data {:dataSets [{:values [{:x 1
                                                                                           :y 2}]
                                                                                 :label "A"
                                                                                 :config {:lineWidth 2
                                                                                          :drawValues false
                                                                                          :dashedLine {:lineLength 10
                                                                                                       :spaceLength 10
                                                                                                       :phase 0}
                                                                                          :color (rn/processColor "white")}}]}
                                                              :border-color (rn/processColor "red")
                                                              :border-width 2
                                                              ;; :draw-borders true
                                                              :touch-enabled true
                                                              :drag-enabled true
                                                              :scale-enabled true
                                                              :scale-x-enabled true
                                                              :scale-y-enabled true
                                                              :pinch-zoom true
                                                              :double-tap-to-zoom-enabled true
                                                              :highlightPerTapEnabled true
                                                              :highlightPerDragEnabled true
                                                              :dragDecelerationEnabled true
                                                              :legend {:enabled false}
                                                              :chartDescription {:text ""}
                                                              :xAxis {:valueFormatter "date"
                                                                      :valueFormatterPattern "HH:mm"}

                                                                      }]])

                     :component-did-mount (fn [comp]
                                            (.setState ^js @chart-ref (clj->js {:values [{:x 1
                                                                                          :y 2}
                                                                                         {:x 2
                                                                                          :y 4}]}))
                                            (update comp))

                     :component-did-update #(update %)}))
  )
and i see that state is updated BUT chart is not updated at all with this approach. i feel like i am missing something could anyone help? thank you in advance

lepistane17:06:22

should i be using this https://github.com/reagent-project/reagent/blob/master/examples/react-sortable-hoc/src/example/core.cljs to solve the issue i described above? am i even looking at the right place? Why would props be updated but component wouldn't be rendered? i even simplified it

(defn line-chart []
  (let [values (rf/subscribe [:graph/data :line])
        colors [(rn/processColor "red") (rn/processColor "blue") (rn/processColor "green") (rn/processColor "yellow") (rn/processColor "purple") (rn/processColor "pink")]]
    [:> rn/View {:flex 7}
     (prn @values)
     [:> charts/LineChart {:style {:flex 1
                                   :background-color :red}
                           :data (clj->js {:dataSets [{:values @values
                                                       :label "A"
                                                       :config {:lineWidth 2
                                                                :drawValues false
                                                                :dashedLine {:lineLength 10
                                                                             :spaceLength 10
                                                                             :phase 0}
                                                                :color (get colors (rand-int 6))}
                                                       }]})
                           }]])
  )
funnily enough color does change as it should but data still doesn't

p-himik07:06:34

Can you create a public minimal reproducible example? Preferably one that doesn't require React Native.

lepistane07:06:55

@U2FRKM4TW that would be tough as the library in question is react native one. https://github.com/wuxudong/react-native-charts-wrapper would react native minimal example suffice ? i tried other RN libs like https://github.com/JesperLekland/react-native-svg-charts and those work properly but lack functionality charts-wrapper offer

p-himik07:06:51

> would react native minimal example suffice ? Maybe, but only if other people decide to look into it. I have 0 experience with React Native.

David Pham08:06:35

Can you wrap the body of the let in a (fn [] body)

lepistane09:06:08

@UEQGQ6XH7 i did try that - same behavior

David Pham09:06:15

Can you make a minimal example with reagent+reframe without RN?

David Pham09:06:18

Also what you could do is have a key metadata to destroy the chart on update

lepistane10:06:47

I can't have minimal example without react native as it's react native lib. It's not lib that i can use on the web. mini update from me. The issue lies with config of the graph. I changed the values i receive from date/timestamp to just index and live updates started happening. so i excluded the formatting. i will dig further into this and report my findings but at the moment it seems that lib won't render newest data points until enough time has passed for it to make sense to redraw graph it could be optimization on their side but i need to dig further @UEQGQ6XH7 i am very curious what you mean by that could you elaborate or link example? thank you very much for taking time to answer and for your help

David Pham10:06:04

My pleasure! We are a welcoming and helpful community after all. So the concept of key for react JS can be read here: https://reactjs.org/docs/lists-and-keys.html

David Pham10:06:28

Finally here at the chapter “providing entity” you can see how the key can be used with component http://day8.github.io/re-frame/reusable-components/

David Pham10:06:45

So the quick summary is the following: the latest resort for forcing an update of a component is to destroy it and rerender all its children. How can you do this? On way to notify react is to say that the key (or the identifier) of the component changed. You achieve this in reagent as ^{:key @update-counter} [some-component].

David Pham10:06:29

This is a nuclear solution as it will rerender all the children. It useful for navigation with multimethods for example where you certain that you do want to rerender everything.

David Pham10:06:46

it is a “hack”, with clear performance considerations, and probably other might have between solutions. But when I am giving up for knowing why a component does not rerender, this is the ultimate weapon :). I hope it helps!

lepistane14:06:38

that's a neat little trick thanks!!