3

I am unable to reactively update ApexCharts using the Vue 3 Composition API. I have been going around in circles. I can update the options and they will write to the div in the example below when you click the button, but the ApexChart does not update. I have had success updating the series data, just not the options.

I tried many different ways of updating chartOptions (relacing whole object, deep property updating, using spreading, using Object.assign. I would expect the chart title to change here, but nothing happens. (div updates though). I must be missing something obvious. Grateful for pointers

Code:

<script setup>
  import {reactive} from "vue"
  import VueApexCharts from "vue3-apexcharts"
  
    let  chartOptions = reactive({
        
            chart: {
              type: 'candlestick',
              height: 350
            },
            title: {
              text: 'CandleStick Chart Title That Doesnt Update',
              align: 'left'
            },
            xaxis: {
              type: 'datetime'
            },
            yaxis: {
              tooltip: {
                enabled: true
              }
            }
        })

    const series = reactive([{
            data: [{
                x: new Date(1538778600000),
                y: [6629.81, 6650.5, 6623.04, 6633.33]
              },
              {
                x: new Date(1538780400000),
                y: [6632.01, 6643.59, 6620, 6630.11]
              },
              {
                x: new Date(1538782200000),
                y: [6630.71, 6648.95, 6623.34, 6635.65]
              },
              {
                x: new Date(1538784000000),
                y: [6635.65, 6651, 6629.67, 6638.24]
              },
              {
                x: new Date(1538785800000),
                y: [6638.24, 6640, 6620, 6624.47]
              },
             
            ]
          }])
    
    function updateChartOptions(){
      //This copies new title but does not update chart  
      chartOptions.title.text = "New Updated Title " + Date.now()
      
      //this doesnt work
      // chartOptions = { 
      //   ...chartOptions,
      //   title:{text:"New Updated Chart " + Date.now()},
        
      // }
      

    }
</script>


<template>
    <div class="example">
      <VueApexCharts width="500" height="350" type="candlestick" :options="chartOptions" :series="series"></VueApexCharts>
      <button v-on:click="updateChartOptions" class="btn btn-primary my-3">Click to Update Chart Options</button>
      <div>{{ chartOptions }}</div>
    </div>
</template>
  
aukinfo
  • 43
  • 4
  • You might find using [key](https://vuejs.org/api/built-in-special-attributes.html) as an acceptable workaround. Stringifying "chartOptions" as your key should force the rerender whenever chartOptions changes: ` – yoduh Mar 02 '23 at 22:34
  • Thanks @yoduh , so I did your suggestion and as I understand from the docs it redraws the whole chart but with the updated options. I then turned off the animations also, with the result that you cant see the redraw. I think that is an acceptable workaround, thank you! – aukinfo Mar 03 '23 at 07:59

1 Answers1

2

By setting chartOptions directly you replace your reactive property with a new object and lose the reactivity.

I would suggest you to use ref() instead of reactive().

chartOptions = { 
   ...chartOptions,
   title:{text:"New Updated Chart " + Date.now()},        
}


let chartOptions = ref({
  chart: {

And then

chartOptions.value = {
    ...chartOptions.value,
    title:{text:"New Updated Chart " + Date.now()},
}

It does work good. Here is the working Codesandbox

Tolbxela
  • 4,767
  • 3
  • 21
  • 42
  • That explains why the commented out code didn't work, but why did the attempt to directly mutate the property not work (`chartOptions.title.text = `)? I could only assume something internal to VueApexCharts breaking the reactivity, but it should normally work shouldn't it? – yoduh Mar 03 '23 at 14:09
  • 1
    Check the [`vue3-apexcharts` Docs: How do I update the chart?](https://github.com/apexcharts/vue3-apexcharts#how-do-i-update-the-chart): Important: While updating the options, make sure to update the outermost property even when you need to update the nested property. – Tolbxela Mar 03 '23 at 14:13
  • The library does not [`deep watch`](https://github.com/apexcharts/vue3-apexcharts/blob/main/src/vue3-apexcharts.js#L240) the `options`. That's why you need to update the whole `options` object. – Tolbxela Mar 03 '23 at 14:20
  • 1
    Hi yes @Tolbxela, but that approach only works with the ref rather than reactive. I tried many times to do the spread update, it only works when you do ref with chartOptions.value. I even read those docs and googled it to death , thanks so much for your help. If you look at those docs, they dont use .value – aukinfo Mar 03 '23 at 16:50