I´m working with Angular (v 15) after update ApexChart from v 3.35 to v 3.45 and test the functions to export data to CSV File, I found a problem with the format. Note I update ApexChart to solve a problem that produce I can´t export a CSV in case of incompleted series of data. ** Before the update i get this format:
I try to change some options of export csv function and adjusting the formatter method on chartOption Object:
this.chartOptions = {
series: this.mapChartData(this.timelineData),
chart: {
height: this.height,
type: "rangeBar",
animations:{
enabled: false,
},
zoom: {
autoScaleYaxis: true
},
toolbar: {
show: true,
offsetX: 0,
offsetY: 0,
export: {
csv: {
filename: `timeline ${new Date().toLocaleString()}`,
columnDelimiter: ', ',
headerCategory: 'category',
headerValue: 'value',
dateFormatter(timestamp) {
return timestamp;
}
},
},
},
},
plotOptions: {
bar: {
horizontal: true,
barHeight: this.parameters.BarHeightPixels + 'px', //Alto de la barra dinamico
rangeBarGroupRows: true,
}
},
colors: this.mapChartColor(this.timelineData), //Agregado color dinamico
xaxis: {
type: 'datetime',
categories: [],
tickAmount: 60, //cantidad de ticks en el eje X 'dataPoints'
tickPlacement: 'between',
/* MIN PARA CUANDO ESTE DISPONIBLE EL CAMBIO EN EL ENDPOINT
min: this.timelineData.TimeAxisMin ? moment(this.datetimePipe.transform(this.timelineData.TimeAxisMin)).format('YYYY-MM-DD HH:mm:ss') : undefined, */
/* min: new Date('25 Aug 2022 00:00').getTime(), */
min: this.getFormattedMinMaxDateTimestamp(this.timelineData.TimeAxisMin, this.timelineData.TimeAxisFormat),
max: this.getFormattedMinMaxDateTimestamp(this.timelineData.TimeAxisMax, this.timelineData.TimeAxisFormat),
range: undefined,
floating: false,
decimalsInFloat: undefined,
overwriteCategories: undefined,
position: 'bottom',
labels: {
show: true,
rotate: -70,
rotateAlways: true,
hideOverlappingLabels: false,
showDuplicates: false,
trim: false,
minHeight: this.labelMinHeight,
maxHeight: this.labelMaxHeight,
style: {
colors: [],
fontSize: '11px',
fontFamily: 'Helvetica, Arial, sans-serif',
fontWeight: 400,
cssClass: 'apexcharts-xaxis-label',
},
offsetX: 0,
offsetY: 0,
format: this.timelineData.TimeAxisFormat,
formatter(timestamp, value, opts) {
let formatoFecha: any;
try {
formatoFecha = opts.w.config.xaxis.labels.format
} catch (error) {
formatoFecha =opts.config.xaxis.labels.format;
}
try {
opts.globals.seriesRangeStart.map(data => {
for (let i = 0; i < data.length; i++) {
data[i] = data[i] ? moment(new Date(data[i])).format('YYYY-MM-DD HH:mm:ss') : data[i];
}
});
opts.globals.seriesRangeEnd.map(data => {
for (let i = 0; i < data.length; i++) {
data[i] = data[i] ? moment(new Date(data[i])).format('YYYY-MM-DD HH:mm:ss') : data[i];
}
});
opts.globals.series.map(data => {
for (let i = 0; i < data.length; i++) {
data[i] = data[i] ? moment(new Date(data[i])).format('YYYY-MM-DD HH:mm:ss') : data[i];
}
});
return moment(new Date(timestamp)).format(formatoFecha);
} catch (error) {
return moment(new Date(timestamp)).format('DD/MM/YYYY HH:mm');
}
},
datetimeUTC: true,
datetimeFormatter: { },
},
axisBorder: {
show: true,
color: '#78909C',
offsetX: 0,
offsetY: 0
},
axisTicks: {
show: true,
borderType: 'solid',
color: '#78909C',
height: 0,
offsetX: 0,
offsetY: 0
},
title: {
text: undefined,
offsetX: 0,
offsetY: 0,
style: {
color: undefined,
fontSize: '12px',
fontFamily: 'Helvetica, Arial, sans-serif',
fontWeight: 600,
cssClass: 'apexcharts-xaxis-title',
},
},
crosshairs: {
show: true,
width: 1,
position: 'back',
opacity: 0.9,
stroke: {
color: '#b6b6b6',
width: 0,
dashArray: 0,
},
fill: {
type: 'solid',
color: '#B1B9C4',
gradient: {
colorFrom: '#D8E3F0',
colorTo: '#BED1E6',
stops: [0, 100],
opacityFrom: 0.4,
opacityTo: 0.5,
},
},
dropShadow: {
enabled: false,
top: 0,
left: 0,
blur: 1,
opacity: 0.4,
},
},
},
//MANEJA LA GRILLA INTERNA DEL GRAFICO//
grid: {
show: true,
borderColor: '#90A4AE',
strokeDashArray: 0,
position: 'back',
xaxis: {
lines: {
show: true
}
},
yaxis: {
lines: {
show: false
}
},
row: {
colors: undefined,
opacity: 0.5
},
column: {
colors: undefined,
opacity: 0.5
},
padding: {
top: 0,
right: 55,
bottom: 0,
left: 35
},
},
yaxis: {
labels: {
show: false,
offsetX: 0,
rotate: -90,
},
},
fill: {
type: "gradient",
gradient: {
shade: "light",
type: "vertical",
shadeIntensity: 0.25,
gradientToColors: undefined,
inverseColors: true,
opacityFrom: 1,
opacityTo: 1,
stops: [50, 0, 100, 100]
}
},
legend: {
show: true,
showForSingleSeries: true,
showForZeroSeries: true,
position: "top",
horizontalAlign: "left"
},
tooltip: {
custom: function (opts) {
const fromYear = moment(opts.y1).format('DD/MM HH:mm');
const toYear = moment(opts.y2).format('DD/MM HH:mm');
const values = opts.ctx.rangeBar.getTooltipValues(opts);
return (
'<div class="apexcharts-tooltip-rangebar" style="font-size:10px">' +
'<div> <span class="series-name">' +
values.ylabel+
"</span></div>" +
'<div> <span class="category" style="color:' + values.color + '">' +
(values.seriesName ? values.seriesName : "") +
' </span> </br> <strong> <span class="value start-value">' +
fromYear +
'</span> </br> <span class="value end-value">' +
toYear +
"</span> </strong></div>" +
"</div>"
);
}
},
}
}
after changes:
this.chartOptions = {
series: this.mapChartData(this.timelineData),
chart: {
height: this.height,
type: "rangeBar",
animations:{
enabled: false,
},
zoom: {
autoScaleYaxis: true
},
toolbar: {
show: true,
offsetX: 0,
offsetY: 0,
export: {
csv: {
filename: `timeline ${new Date().toLocaleString()}`,
columnDelimiter: ', ',
headerCategory: 'category',
headerValue: 'value',
dateFormatter(timestamp) {
console.log(timestamp);
return timestamp
}
},
},
},
},
plotOptions: {
bar: {
horizontal: true,
barHeight: this.parameters.BarHeightPixels + 'px', //Alto de la barra dinamico
rangeBarGroupRows: true,
}
},
colors: this.mapChartColor(this.timelineData), //Agregado color dinamico
xaxis: {
type: 'datetime',
categories: [],
tickAmount: 60, //cantidad de ticks en el eje X 'dataPoints'
tickPlacement: 'between',
/* MIN PARA CUANDO ESTE DISPONIBLE EL CAMBIO EN EL ENDPOINT
min: this.timelineData.TimeAxisMin ? moment(this.datetimePipe.transform(this.timelineData.TimeAxisMin)).format('YYYY-MM-DD HH:mm:ss') : undefined, */
/* min: new Date('25 Aug 2022 00:00').getTime(), */
min: this.getFormattedMinMaxDateTimestamp(this.timelineData.TimeAxisMin, this.timelineData.TimeAxisFormat),
max: this.getFormattedMinMaxDateTimestamp(this.timelineData.TimeAxisMax, this.timelineData.TimeAxisFormat),
range: undefined,
floating: false,
decimalsInFloat: undefined,
overwriteCategories: undefined,
position: 'bottom',
labels: {
show: true,
rotate: -70,
rotateAlways: true,
hideOverlappingLabels: false,
showDuplicates: false,
trim: false,
minHeight: this.labelMinHeight,
maxHeight: this.labelMaxHeight,
style: {
colors: [],
fontSize: '11px',
fontFamily: 'Helvetica, Arial, sans-serif',
fontWeight: 400,
cssClass: 'apexcharts-xaxis-label',
},
offsetX: 0,
offsetY: 0,
format: this.timelineData.TimeAxisFormat,
formatter(timestamp, value, opts) {
let formatoFecha: any;
try {
formatoFecha = opts.w.config.xaxis.labels.format
} catch (error) {
formatoFecha =opts.config.xaxis.labels.format;
}
try {
opts.w.globals.seriesRange.map(x => {
for (let i = 0; i < x.data.length; i++) {
x.data[i] = x.data[i] ? moment(new Date(x.data[i])).format('YYYY-MM-DD HH:mm:ss') : x.data[i];
}
});
opts.w.globals.seriesRangeStart.map(x => {
for (let i = 0; i < x.data.length; i++) {
x.data[i] = x.data[i] ? moment(new Date(x.data[i])).format('YYYY-MM-DD HH:mm:ss') : x.data[i];
}
});
opts.w.globals.seriesRangeEnd.map(x => {
for (let i = 0; i < x.data.length; i++) {
x.data[i] = x.data[i] ? moment(new Date(x.data[i])).format('YYYY-MM-DD HH:mm:ss') : x.data[i];
}
});
opts.w.globals.series.map(x => {
for (let i = 0; i < x.data.length; i++) {
x.data[i] = x.data[i] ? moment(new Date(x.data[i])).format('YYYY-MM-DD HH:mm:ss') : x.data[i];
}
});
opts.globals.seriesRange.map(x => {
for (let i = 0; i < x.data.length; i++) {
x.data[i] = x.data[i] ? moment(new Date(x.data[i])).format('YYYY-MM-DD HH:mm:ss') : x.data[i];
}
});
opts.globals.seriesRangeStart.map(x => {
for (let i = 0; i < x.data.length; i++) {
x.data[i] = x.data[i] ? moment(new Date(x.data[i])).format('YYYY-MM-DD HH:mm:ss') : x.data[i];
}
});
opts.globals.seriesRangeEnd.map(x => {
for (let i = 0; i < x.data.length; i++) {
x.data[i] = x.data[i] ? moment(new Date(x.data[i])).format('YYYY-MM-DD HH:mm:ss') : x.data[i];
}
});
opts.globals.series.map(x => {
for (let i = 0; i < x.data.length; i++) {
x.data[i] = x.data[i] ? moment(new Date(x.data[i])).format('YYYY-MM-DD HH:mm:ss') : x.data[i];
}
});
return moment(new Date(timestamp)).format(formatoFecha);
} catch (error) {
return moment(new Date(timestamp)).format('DD/MM/YYYY HH:mm');
}
},
datetimeUTC: true,
datetimeFormatter: { },
},
axisBorder: {
show: true,
color: '#78909C',
offsetX: 0,
offsetY: 0
},
axisTicks: {
show: true,
borderType: 'solid',
color: '#78909C',
height: 0,
offsetX: 0,
offsetY: 0
},
title: {
text: undefined,
offsetX: 0,
offsetY: 0,
style: {
color: undefined,
fontSize: '12px',
fontFamily: 'Helvetica, Arial, sans-serif',
fontWeight: 600,
cssClass: 'apexcharts-xaxis-title',
},
},
crosshairs: {
show: true,
width: 1,
position: 'back',
opacity: 0.9,
stroke: {
color: '#b6b6b6',
width: 0,
dashArray: 0,
},
fill: {
type: 'solid',
color: '#B1B9C4',
gradient: {
colorFrom: '#D8E3F0',
colorTo: '#BED1E6',
stops: [0, 100],
opacityFrom: 0.4,
opacityTo: 0.5,
},
},
dropShadow: {
enabled: false,
top: 0,
left: 0,
blur: 1,
opacity: 0.4,
},
},
},
//MANEJA LA GRILLA INTERNA DEL GRAFICO//
grid: {
show: true,
borderColor: '#90A4AE',
strokeDashArray: 0,
position: 'back',
xaxis: {
lines: {
show: true
}
},
yaxis: {
lines: {
show: false
}
},
row: {
colors: undefined,
opacity: 0.5
},
column: {
colors: undefined,
opacity: 0.5
},
padding: {
top: 0,
right: 55,
bottom: 0,
left: 35
},
},
yaxis: {
labels: {
show: false,
offsetX: 0,
rotate: -90,
},
},
fill: {
type: "gradient",
gradient: {
shade: "light",
type: "vertical",
shadeIntensity: 0.25,
gradientToColors: undefined,
inverseColors: true,
opacityFrom: 1,
opacityTo: 1,
stops: [50, 0, 100, 100]
}
},
legend: {
show: true,
showForSingleSeries: true,
showForZeroSeries: true,
position: "top",
horizontalAlign: "left"
},
tooltip: {
custom: ({ series, seriesIndex, dataPointIndex, w })=> {
var serie = w.globals.initialSeries[seriesIndex];
const fromYear = moment(serie.data[dataPointIndex].y[0]).format(this.timelineData.TimeAxisFormat);
const toYear = moment(serie.data[dataPointIndex].y[1]).format(this.timelineData.TimeAxisFormat);
return (
'<div class="apexcharts-tooltip-rangebar" style="font-size:10px">' +
'<div> <span class="series-name">' +
serie.data[dataPointIndex].x +
"</span></div>" +
'<div> <span class="category" style="color:' +serie.color +'">' +
(serie.name ? serie.name : "") +
' </span> </br> <strong> <span class="value start-value">' +
fromYear +
'</span> </br> <span class="value end-value">' +
toYear +
"</span> </strong></div>" +
"</div>"
);
}
},
}
Any suggestions?