tvjsx / trading-vue-js

💹 Hackable charting lib for traders. You can draw literally ANYTHING on top of candlestick charts. [Not Maintained]
https://tvjsx.github.io/trading-vue-demo/
MIT License
2.07k stars 629 forks source link

Correct way to use DataCube when trading-vue component is not immediately created in DOM? #250

Open jleskovar-tyro opened 3 years ago

jleskovar-tyro commented 3 years ago

Hi there - hopefully a straightforward q. I'm using the trading-vue with the Vuetify UI library, and specifically I'm trying to embed an instance of the <trading-view> component nested inside of a <v-tab-item>, like so:

          <v-tab-item value="tab-chart">
            <v-card>
              <v-card-text>
                <trading-vue
                  ref="tvjs"
                  :titleTxt="currency[0].toUpperCase() + currency[1].toUpperCase()"
                  :data="chart"/>
              </v-card-text>
            </v-card>
          </v-tab-item>

where "chart" is a new DataCube({chart: {}, onchart: [], offchart: []})

When setting candle data - this.chart.set('chart.data', candles) - unless I've navigated to the tab, I'll get an "undefined" error message within the library:

TypeError: Cannot read properties of undefined (reading '$set')

If I try use :eager="true" on the v-tab-item component, I don't get the undefined error, but the chart itself does not get updated, even when setting the DataCube with valid data, so I end up with a blank chart.

Any help would be greatly appreciated.

jleskovar-tyro commented 3 years ago

Here's my workaround for now - for anyone who's hitting similar issues. Here, I'm wrapping the <trading-vue> component with my own, and simply passing in the ohlcv data as props. The key to making it all work is the watch on the data:

import Vue from 'vue'
import { TradingVue, DataCube } from 'trading-vue-js'

export default Vue.extend({
  components: {
    TradingVue,
  },
  props: {
    title: {
      type: String,
      required: true
    },
    candles: {
      type: Array,
      default: []
    },
  },
  data () {
    return {
      chart: new DataCube({chart: { data: this.candles }, onchart: [], offchart: []}),
      timezoneOffsetHours: -(new Date().getTimezoneOffset() / 60.0)
    }
  },
  watch: {
    candles (val: number[][]): void {
      this.chart.set('chart.data', val)
    }
  }
})

...and then usage:

          <v-tab-item value="tab-chart">
            <v-card>
              <v-card-text>
                <trading-chart
                  ref="tradingChart"
                  :title="currency[0].toUpperCase() + currency[1].toUpperCase()" 
                  :candles="candles"
                />
              </v-card-text>
            </v-card>
          </v-tab-item>