From 03ac4e3a0671f69d64e68dad07eeee33fbd19ee2 Mon Sep 17 00:00:00 2001 From: Marius Munteanu Date: Tue, 9 Apr 2024 10:30:33 +0200 Subject: [PATCH 1/3] Fix multi lvl categories in embedded .xlsx --- src/gen-charts.ts | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/gen-charts.ts b/src/gen-charts.ts index efe0c95e..65c7dab4 100644 --- a/src/gen-charts.ts +++ b/src/gen-charts.ts @@ -135,6 +135,9 @@ export async function createExcelWorksheet (chartObject: ISlideRelChart, zip: JS ) } + // dictionary of shared strings mapped to indexes + const sharedStrings: Record = {} + // sharedStrings.xml { // A: Start XML @@ -148,6 +151,7 @@ export async function createExcelWorksheet (chartObject: ISlideRelChart, zip: JS data[0].labels.forEach(arrLabel => (totCount += arrLabel.filter(label => label && label !== '').length)) strSharedStrings += `` strSharedStrings += '' + sharedStrings[''] = 0 } else { // series names + all labels of one series + number of label groups (data.labels.length) of one series (i.e. how many times the blank string is used) const totCount = data.length + data[0].labels.length * data[0].labels[0].length + data[0].labels.length @@ -157,20 +161,29 @@ export async function createExcelWorksheet (chartObject: ISlideRelChart, zip: JS strSharedStrings += `` // B: Add 'blank' for A1, B1, ..., of every label group inside data[n].labels strSharedStrings += '' + sharedStrings[''] = 0 } // C: Add `name`/Series if (chartObject.opts._type === CHART_TYPE.BUBBLE || chartObject.opts._type === CHART_TYPE.BUBBLE3D) { data.forEach((objData, idx) => { - if (idx === 0) strSharedStrings += 'X-Axis' - else { - strSharedStrings += `${encodeXmlEntities(objData.name || `Y-Axis${idx}`)}` - strSharedStrings += `${encodeXmlEntities(`Size${idx}`)}` + if (idx === 0) { + const xAxisSharedString = 'X-Axis' + strSharedStrings += `${xAxisSharedString}` + } else { + const yAxisSharedString = encodeXmlEntities(objData.name || `Y-Axis${idx}`) + strSharedStrings += `${yAxisSharedString}` + sharedStrings[yAxisSharedString] = Object.keys(yAxisSharedString).length + const sizeSharedString = encodeXmlEntities(`Size${idx}`) + strSharedStrings += `${sizeSharedString}` + sharedStrings[sizeSharedString] = Object.keys(sizeSharedString).length } }) } else { data.forEach(objData => { - strSharedStrings += `${encodeXmlEntities((objData.name || ' ').replace('X-Axis', 'X-Values'))}` + const sharedString = encodeXmlEntities((objData.name || ' ').replace('X-Axis', 'X-Values')) + strSharedStrings += `${sharedString}` + sharedStrings[sharedString] = Object.keys(sharedStrings).length }) } @@ -185,6 +198,7 @@ export async function createExcelWorksheet (chartObject: ISlideRelChart, zip: JS .filter(label => label && label !== '') .forEach(label => { strSharedStrings += `${encodeXmlEntities(label)}` + sharedStrings[encodeXmlEntities(label)] = Object.keys(sharedStrings).length }) }) } @@ -460,7 +474,6 @@ export async function createExcelWorksheet (chartObject: ISlideRelChart, zip: JS // WIP: FIXME: // B: add a col for each label/cat - let totLabels = TOT_SER const revLabelGroups = data[0].labels.slice().reverse() revLabelGroups.forEach((labelsGroup, idy) => { /** @@ -471,9 +484,7 @@ export async function createExcelWorksheet (chartObject: ISlideRelChart, zip: JS */ const colLabel = labelsGroup[idx] if (colLabel) { - const totGrpLbls = idy === 0 ? 1 : revLabelGroups[idy - 1].filter(label => label && label !== '').length // get unique label so we can add to get proper shared-string # - totLabels += totGrpLbls - strSheetXml += `${totLabels}` + strSheetXml += `${sharedStrings[colLabel]}` } }) From ec485ade01331dff0a6784ce910fce275cfa2e37 Mon Sep 17 00:00:00 2001 From: Marius Munteanu Date: Tue, 7 May 2024 10:44:36 +0200 Subject: [PATCH 2/3] Fixed duplicated shared strings --- src/gen-charts.ts | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/gen-charts.ts b/src/gen-charts.ts index 65c7dab4..d8ac22bc 100644 --- a/src/gen-charts.ts +++ b/src/gen-charts.ts @@ -172,8 +172,11 @@ export async function createExcelWorksheet (chartObject: ISlideRelChart, zip: JS strSharedStrings += `${xAxisSharedString}` } else { const yAxisSharedString = encodeXmlEntities(objData.name || `Y-Axis${idx}`) - strSharedStrings += `${yAxisSharedString}` - sharedStrings[yAxisSharedString] = Object.keys(yAxisSharedString).length + if (!sharedStrings[yAxisSharedString]) { + strSharedStrings += `${yAxisSharedString}` + sharedStrings[yAxisSharedString] = Object.keys(yAxisSharedString).length + } + const sizeSharedString = encodeXmlEntities(`Size${idx}`) strSharedStrings += `${sizeSharedString}` sharedStrings[sizeSharedString] = Object.keys(sizeSharedString).length @@ -182,8 +185,10 @@ export async function createExcelWorksheet (chartObject: ISlideRelChart, zip: JS } else { data.forEach(objData => { const sharedString = encodeXmlEntities((objData.name || ' ').replace('X-Axis', 'X-Values')) - strSharedStrings += `${sharedString}` - sharedStrings[sharedString] = Object.keys(sharedStrings).length + if (!sharedStrings[sharedString]) { + strSharedStrings += `${sharedString}` + sharedStrings[sharedString] = Object.keys(sharedStrings).length + } }) } @@ -197,8 +202,11 @@ export async function createExcelWorksheet (chartObject: ISlideRelChart, zip: JS labelsGroup .filter(label => label && label !== '') .forEach(label => { - strSharedStrings += `${encodeXmlEntities(label)}` - sharedStrings[encodeXmlEntities(label)] = Object.keys(sharedStrings).length + const sharedString = encodeXmlEntities(label) + if (!sharedStrings[sharedString]) { + strSharedStrings += `${sharedString}` + sharedStrings[sharedString] = Object.keys(sharedStrings).length + } }) }) } @@ -484,7 +492,7 @@ export async function createExcelWorksheet (chartObject: ISlideRelChart, zip: JS */ const colLabel = labelsGroup[idx] if (colLabel) { - strSheetXml += `${sharedStrings[colLabel]}` + strSheetXml += `${sharedStrings[colLabel]}` } }) From 40804ae5ac4b12f92d4719561a8297bf9e9c68e9 Mon Sep 17 00:00:00 2001 From: Marius Munteanu Date: Mon, 13 May 2024 13:23:34 +0200 Subject: [PATCH 3/3] Minor refactoring and fixed some oversights --- src/gen-charts.ts | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/gen-charts.ts b/src/gen-charts.ts index d8ac22bc..dce5b11b 100644 --- a/src/gen-charts.ts +++ b/src/gen-charts.ts @@ -135,8 +135,8 @@ export async function createExcelWorksheet (chartObject: ISlideRelChart, zip: JS ) } - // dictionary of shared strings mapped to indexes - const sharedStrings: Record = {} + // dictionary of shared strings mapped to their indexes indexes + const sharedStringsObject: Record = {} // sharedStrings.xml { @@ -151,7 +151,7 @@ export async function createExcelWorksheet (chartObject: ISlideRelChart, zip: JS data[0].labels.forEach(arrLabel => (totCount += arrLabel.filter(label => label && label !== '').length)) strSharedStrings += `` strSharedStrings += '' - sharedStrings[''] = 0 + sharedStringsObject[''] = 0 } else { // series names + all labels of one series + number of label groups (data.labels.length) of one series (i.e. how many times the blank string is used) const totCount = data.length + data[0].labels.length * data[0].labels[0].length + data[0].labels.length @@ -161,33 +161,36 @@ export async function createExcelWorksheet (chartObject: ISlideRelChart, zip: JS strSharedStrings += `` // B: Add 'blank' for A1, B1, ..., of every label group inside data[n].labels strSharedStrings += '' - sharedStrings[''] = 0 + sharedStringsObject[''] = 0 } // C: Add `name`/Series if (chartObject.opts._type === CHART_TYPE.BUBBLE || chartObject.opts._type === CHART_TYPE.BUBBLE3D) { data.forEach((objData, idx) => { if (idx === 0) { - const xAxisSharedString = 'X-Axis' - strSharedStrings += `${xAxisSharedString}` + const sharedString = 'X-Axis' + if (!sharedStringsObject[sharedString]) { + strSharedStrings += `${sharedString}` + sharedStringsObject[sharedString] = Object.keys(sharedStringsObject).length + } } else { - const yAxisSharedString = encodeXmlEntities(objData.name || `Y-Axis${idx}`) - if (!sharedStrings[yAxisSharedString]) { - strSharedStrings += `${yAxisSharedString}` - sharedStrings[yAxisSharedString] = Object.keys(yAxisSharedString).length + const sharedString = encodeXmlEntities(objData.name || `Y-Axis${idx}`) + if (!sharedStringsObject[sharedString]) { + strSharedStrings += `${sharedString}` + sharedStringsObject[sharedString] = Object.keys(sharedStringsObject).length } const sizeSharedString = encodeXmlEntities(`Size${idx}`) strSharedStrings += `${sizeSharedString}` - sharedStrings[sizeSharedString] = Object.keys(sizeSharedString).length + sharedStringsObject[sizeSharedString] = Object.keys(sharedStringsObject).length } }) } else { data.forEach(objData => { const sharedString = encodeXmlEntities((objData.name || ' ').replace('X-Axis', 'X-Values')) - if (!sharedStrings[sharedString]) { + if (!sharedStringsObject[sharedString]) { strSharedStrings += `${sharedString}` - sharedStrings[sharedString] = Object.keys(sharedStrings).length + sharedStringsObject[sharedString] = Object.keys(sharedStringsObject).length } }) } @@ -203,9 +206,9 @@ export async function createExcelWorksheet (chartObject: ISlideRelChart, zip: JS .filter(label => label && label !== '') .forEach(label => { const sharedString = encodeXmlEntities(label) - if (!sharedStrings[sharedString]) { + if (!sharedStringsObject[sharedString]) { strSharedStrings += `${sharedString}` - sharedStrings[sharedString] = Object.keys(sharedStrings).length + sharedStringsObject[sharedString] = Object.keys(sharedStringsObject).length } }) }) @@ -492,7 +495,7 @@ export async function createExcelWorksheet (chartObject: ISlideRelChart, zip: JS */ const colLabel = labelsGroup[idx] if (colLabel) { - strSheetXml += `${sharedStrings[colLabel]}` + strSheetXml += `${sharedStringsObject[colLabel]}` } })