Skip to content

Commit

Permalink
Merge pull request #4128 from hrynko/feature/unequal-datetime-series-…
Browse files Browse the repository at this point in the history
…csv-export

Handle CSV export of the datetime multi-series with variable X-axes
  • Loading branch information
junedchhipa committed Dec 3, 2023
2 parents 2c0fb38 + 33351ec commit 5a69ce2
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 11 deletions.
73 changes: 63 additions & 10 deletions src/modules/Exports.js
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,48 @@ class Exports {
}
}

const handleUnequalDatetimeSeries = () => {
const categories = new Set()
const data = {}

series.forEach((s, sI) => {
s?.data.forEach((dataItem) => {
let cat, value
if (dataFormat.isFormatXY()) {
cat = dataItem.x
value = dataItem.y
} else if (dataFormat.isFormat2DArray()) {
cat = dataItem[0]
value = dataItem[1]
} else {
return
}
if (!data[cat]) {
data[cat] = Array(series.length).fill('')
}
data[cat][sI] = value
categories.add(cat)
})
})

if (columns.length) {
rows.push(columns.join(columnDelimiter))
}

Array.from(categories)
.sort()
.forEach((cat) => {
rows.push([
isTimeStamp(cat)
? w.config.chart.toolbar.export.csv.dateFormatter(cat)
: Utils.isNumber(cat)
? cat
: cat.split(columnDelimiter).join(''),
data[cat].join(columnDelimiter),
])
})
}

columns.push(w.config.chart.toolbar.export.csv.headerCategory)

if (w.config.chart.type === 'boxPlot') {
Expand Down Expand Up @@ -378,17 +420,28 @@ class Exports {
columns.push(w.config.chart.toolbar.export.csv.headerValue)
rows.push(columns.join(columnDelimiter))
}
series.map((s, sI) => {
if (w.globals.axisCharts) {
handleAxisRowsColumns(s, sI)
} else {
columns = []

columns.push(w.globals.labels[sI].split(columnDelimiter).join(''))
columns.push(gSeries[sI])
rows.push(columns.join(columnDelimiter))
}
})
if (
!w.globals.allSeriesHasEqualX &&
w.globals.axisCharts &&
w.config.xaxis.type === 'datetime' &&
!w.config.xaxis.categories.length &&
!w.config.labels.length
) {
handleUnequalDatetimeSeries()
} else {
series.map((s, sI) => {
if (w.globals.axisCharts) {
handleAxisRowsColumns(s, sI)
} else {
columns = []

columns.push(w.globals.labels[sI].split(columnDelimiter).join(''))
columns.push(gSeries[sI])
rows.push(columns.join(columnDelimiter))
}
})
}

result += rows.join(lineDelimiter)

Expand Down
11 changes: 10 additions & 1 deletion src/modules/Toolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,17 @@ export default class Toolbar {
},
]

if (!this.w.globals.allSeriesHasEqualX) {
if (
!this.w.globals.allSeriesHasEqualX &&
!(
this.w.globals.axisCharts &&
this.w.config.xaxis.type === 'datetime' &&
!this.w.config.xaxis.categories.length &&
!this.w.config.labels.length
)
) {
// if it is a multi series, and all series have variable x values, export CSV won't work
// unless it is a simple datetime chart
menuItems.splice(2, 1)
}
for (let i = 0; i < menuItems.length; i++) {
Expand Down
66 changes: 66 additions & 0 deletions tests/unit/download-csv.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,72 @@ describe('Export Csv', () => {
expect.stringContaining('.csv')
)
})
it("export csv from simple line chart with two unequal datetime series should call triggerDownload with csv encoded file data", () => {
var options = {
chart: {
type: "line"
},
series: [{
name: 'series1',
data: [["2000-01-01T00:00:00.000", 1]]
}, {
name: 'series2',
data: [["2000-01-02T00:00:00.000", 1]]
}],
xaxis: {
type: 'datetime',
},
};
const csvData = "category,series1,series2\n" +
"Sat Jan 01 2000,1,\n" +
"Sun Jan 02 2000,,1"
const chart = createChartWithOptions(options)
const exports = new Exports(chart.ctx)
jest.spyOn(Exports.prototype,'triggerDownload')
exports.exportToCSV(chart.w.config.series,'fileName')
expect(Exports.prototype.triggerDownload).toHaveBeenCalledTimes(1)
expect(Exports.prototype.triggerDownload).toHaveBeenCalledWith(
expect.stringContaining(encodeURIComponent(csvData)),
expect.toBeUndefined,
expect.stringContaining('.csv')
)
})
it("export csv from simple line chart with two unequal datetime x y series should call triggerDownload with csv encoded file data", () => {
var options = {
chart: {
type: "line"
},
series: [{
name: 'series1',
data: [{
x: "2000-01-01T00:00:00.000",
y: 1
}]
}, {
name: 'series2',
data: [{
x: "2000-01-02T00:00:00.000",
y: 1
}]
}],
xaxis: {
type: 'datetime',
},
};
const csvData = "category,series1,series2\n" +
"Sat Jan 01 2000,1,\n" +
"Sun Jan 02 2000,,1"
const chart = createChartWithOptions(options)
const exports = new Exports(chart.ctx)
jest.spyOn(Exports.prototype,'triggerDownload')
exports.exportToCSV(chart.w.config.series,'fileName')
expect(Exports.prototype.triggerDownload).toHaveBeenCalledTimes(1)
expect(Exports.prototype.triggerDownload).toHaveBeenCalledWith(
expect.stringContaining(encodeURIComponent(csvData)),
expect.toBeUndefined,
expect.stringContaining('.csv')
)
})
it("export csv from simple spline area chart with two series should call triggerDownload with csv encoded file data", () => {
var options = {
series: [{
Expand Down

0 comments on commit 5a69ce2

Please sign in to comment.