Multi Y axis chart with vue3 - reactive problem
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 ?
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.