apexcharts / vue3-apexcharts

📊 Vue-3 component for ApexCharts
MIT License
314 stars 35 forks source link

Multi Y axis chart with vue3 - reactive problem #85

Open sumanadak opened 1 year ago

sumanadak commented 1 year ago

Hi, I am trying to develop an multi y axis charts . I can successfully add a series[] and add yaxis[] array. All charts are showing gr8. But When I try to remove the series, I just slice the series array as well as chartOptions yaxis[] array. When I completely removed all series, I see still an element in yaxis[] while series[] is successfully removed all element. Surprisingly I see the length of the Yaxis[] after slice is 0 but when I inspect vue tool in chrome , I see a default yaxis object element in yaxis[] inside chartOptions. One noticeable thing i observed, while series element and chartOptions is reactive( I declared them with ref), yaxis array and element is not reactive. I am sure I am doing some mess up or not updating chartOptions correctly or someting wrong with vue reactive update process. Please help me find the Issue. I am sharing code as well as vue dev tool info

   <template>
  <div class="chart-app">
    <div class="controls">
      <button @click="addSeries('Y1')">Add Y1 Series</button>
      <button @click="addSeries('Y2')">Add Y2 Series</button>
      <button @click="addSeries('Y3')">Add Y3 Series</button>
     </div>
    <div class="series-list">
      <p class="series-heading">Series Added:</p>
      <div
        v-for="(seriesName, index) in addedSeriesName"
        :key="index"
        class="series-item"
      >
        <span>{{ seriesName }}</span>
        <button @click="removeSeries(index)" class="remove-button">X</button>
      </div>
    </div>

    <h4 class="chart-title">Multi Y-Axis Charts</h4>
    <apexchart
      width="1000"
      height="350"
      type="line"
      :options="chartOptions"
      :series="series"
    />
  </div>
</template>
 <script>
  import { defineComponent, ref } from 'vue';  
  export default defineComponent({
    name: 'LineExample-CompositionApi',
    setup() {
      const chartOptions = ref({
        chart: {
          id: 'mychart',
        },
        animations: {
          initialAnimation: {
            enabled: true,
          },
        },
        xaxis: {
          type: 'datetime',
          categories: [],
        },
        yaxis: [],
        annotations: {
          points: [],
        },
        legend: {
          // Add legend configuration here
          show: true,
          showForSingleSeries: true,
        },
      });  
      function generateDayWiseTimeSeries(baseval, count, yrange, tagName) {
        let i = 0;
        const newSeries = [];
        while (i < count) {
          const x = baseval;
          const y =
            Math.floor(Math.random() * (yrange.max - yrange.min + 1)) +
            yrange.min;

          newSeries.push([x, y]);
          baseval += 86400;
          i++;
          if (y % 8 === 0) {
            //   addAlerts(x, y, tagName);
          }
        }
        return newSeries;
      }

      function generateSeriesName(length) {
        let result = '';
        const characters =
          'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
        const charactersLength = characters.length;
        let counter = 0;
        while (counter < length) {
          result += characters.charAt(
            Math.floor(Math.random() * charactersLength)
          );
          counter += 1;
        }
        return result;
      }

      const series = ref([]);
      const yAxisSeriesRangeStore = ref(new Map());
      let addedSeriesName = ref([]);

      function addSeries(yAxisName) {
        console.debug('Push new series');
        let yaxis = {};
        let seriesName = `${generateSeriesName(5)}:${yAxisName}`;
        addedSeriesName.value.push(seriesName);
        let yAxisMappedSeriesName = undefined;
        let [tagName, YaxisTagRange] = seriesName.split(':');
        if (yAxisSeriesRangeStore.value.get(YaxisTagRange) === undefined) {
          yAxisSeriesRangeStore.value.set(YaxisTagRange, seriesName);
          yAxisMappedSeriesName = seriesName;
          yaxis = {
            id: seriesName,
            seriesName: yAxisMappedSeriesName,
            showAlways: true,
            opposite: !(yAxisName === 'Y1'),
            axisTicks: {
              show: true,
            },
            axisBorder: {
              show: true,
            },
            title: {
              text: yAxisName,
            },
          };
        } else {
          yAxisMappedSeriesName = yAxisSeriesRangeStore.value.get(YaxisTagRange);
          yaxis = {
            id: seriesName,
            seriesName: yAxisMappedSeriesName,
            show: false,
          };
        }
        chartOptions.value.yaxis.push(yaxis);
        // added little delay to render legent
        /*   setTimeOut(() => 
         chartOptions.value = { ...chartOptions.value };
       ,1 ) */

        chartOptions.value = { ...chartOptions.value };

        let dataRange = yAxisName === 'Y1' ? 50 : yAxisName === 'Y2' ? 500 : 1000;
        series.value.push({
          name: seriesName,
          data: generateDayWiseTimeSeries(
            new Date('11 Feb 2017').getTime(),
            dataRange,
            {
              min: -10,
              max: Math.floor(Math.random() * (200 - 0 + 1)),
            },
            seriesName
          ),
        });
      }

      function removeSeries(index) {
        const removedSeries = series.value.splice(index, 1)[0]; // Remove the series from the series array
        addedSeriesName.value.splice(index, 1); // Remove the series name from addedSeriesName array
        console.log(removedSeries.name);
        const yAxisTagRange = removedSeries.name.split(':')[1];
        const yAxisIndex = chartOptions.value.yaxis.findIndex(
          (yAxis) => yAxis.id === removedSeries.name
        );

        if (yAxisIndex !== -1) {
          chartOptions.value.yaxis.splice(yAxisIndex, 1);
        }
      //  Vue.delete(chartOptions.value.yaxis, yAxisIndex);
        chartOptions.value = { ...chartOptions.value };
        const seriesName = removedSeries.name; // Get the seriesName (tagName)  

      }

      return {
        chartOptions,
        series,
        addSeries,
        addAlerts,
        deleteAlerts,
        addedSeriesName,
        removeSeries,
      };
    },
  });
</script>
</script>
<style scoped>
.chart-app {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20px;
}

.controls {
  margin-bottom: 20px;
}

.controls button {
  margin-right: 10px;
  background-color: #3498db;
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 4px;
  cursor: pointer;
}

.series-list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin-bottom: 20px;
}

.series-heading {
  font-weight: bold;
}

.series-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
  padding: 6px;
  border: 1px solid #ddd;
  border-radius: 4px;
  background-color: #f9f9f9;
}

.remove-button {
  background-color: #e74c3c;
  color: white;
  border: none;
  padding: 6px 12px;
  border-radius: 4px;
  cursor: pointer;
}

.chart-title {
  font-size: 18px;
  margin-bottom: 10px;
}
</style>

`

Vue dev tool

Once I insert one series the prop value is like height:"350" options:Reactive chart:Reactive animations:Reactive xaxis:Reactive yaxis:Array[1] 0:Object annotations:Reactive legend:Reactive series:Array[1] 0:Reactive type:"line" width:"1000"


after deleting the series
height:"350" options:Reactive chart:Reactive animations:Reactive xaxis:Reactive yaxis:Array[1] 0:Object axisBorder:Object axisTicks:Object crosshairs:Object decimalsInFloat:undefined floating:false forceNiceScale:false labels:Object logBase:10 logarithmic:false max:undefined min:undefined opposite:false reversed:false seriesName:undefined show:true showAlways:false showForNullSeries:true tickAmount:undefined title:Object tooltip:Object annotations:Reactive legend:Reactive series:Array[0] type:"line" width:"1000"

Object I found after delete all series in yaxis is

{"show":true,"showAlways":false,"showForNullSeries":true,"opposite":false,"reversed":false,"logarithmic":false,"logBase":10,"forceNiceScale":false,"floating":false,"labels":{"show":true,"minWidth":0,"maxWidth":160,"offsetX":0,"offsetY":0,"rotate":0,"padding":20,"style":{"colors":[null,null,null,null,null,null],"fontSize":"11px","fontWeight":400,"cssClass":""}},"axisBorder":{"show":false,"color":"#e0e0e0","width":1,"offsetX":0,"offsetY":0},"axisTicks":{"show":false,"color":"#e0e0e0","width":6,"offsetX":0,"offsetY":0},"title":{"rotate":-90,"offsetY":0,"offsetX":0,"style":{"fontSize":"11px","fontWeight":900,"cssClass":""}},"tooltip":{"enabled":false,"offsetX":0},"crosshairs":{"show":true,"position":"front","stroke":{"color":"#b6b6b6","width":1,"dashArray":0}}}

Which I didnt add. How does this element is added to yaxis ?

github-actions[bot] commented 3 months ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.