Skip to content

Commit 7b1e08b

Browse files
committed
fix(chart): add chart subtype (WIP)
1 parent 08a1cbd commit 7b1e08b

File tree

7 files changed

+77
-46
lines changed

7 files changed

+77
-46
lines changed

src/classes/shape.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import JSZip from 'jszip';
22

33
import { XmlHelper } from '../helper/xml-helper';
4-
import { GeneralHelper } from '../helper/general-helper';
4+
import { GeneralHelper, vd } from '../helper/general-helper';
55
import {
66
ImportedElement,
77
ShapeModificationCallback,
@@ -10,6 +10,7 @@ import {
1010
import { RootPresTemplate } from '../interfaces/root-pres-template';
1111
import { HelperElement } from '../types/xml-types';
1212
import { ImageTypeMap } from '../enums/image-type-map';
13+
import { ElementSubtype } from '../enums/element-type';
1314

1415
export class Shape {
1516
mode: string;
@@ -42,6 +43,7 @@ export class Shape {
4243
callbacks: ShapeModificationCallback[];
4344
hasCreationId: boolean;
4445
contentTypeMap: typeof ImageTypeMap;
46+
subtype: ElementSubtype;
4547

4648
constructor(shape: ImportedElement) {
4749
this.mode = shape.mode;
@@ -55,9 +57,11 @@ export class Shape {
5557

5658
this.callbacks = GeneralHelper.arrayify(shape.callback);
5759
this.contentTypeMap = ImageTypeMap;
60+
5861
if (shape.target) {
5962
this.sourceNumber = shape.target.number;
6063
this.sourceRid = shape.target.rId;
64+
this.subtype = shape.target.subtype;
6165
}
6266
}
6367

src/classes/slide.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,8 +419,19 @@ export class Slide implements ISlide {
419419
sourceArchive: JSZip,
420420
slideNumber: number,
421421
): Promise<AnalyzedElementType> {
422+
vd('analyzeElement');
422423
const isChart = sourceElement.getElementsByTagName('c:chart');
423424
if (isChart.length) {
425+
vd({
426+
type: ElementType.Chart,
427+
target: await XmlHelper.getTargetByRelId(
428+
sourceArchive,
429+
slideNumber,
430+
sourceElement,
431+
'chart',
432+
),
433+
});
434+
424435
return {
425436
type: ElementType.Chart,
426437
target: await XmlHelper.getTargetByRelId(
@@ -688,6 +699,7 @@ export class Slide implements ISlide {
688699
*/
689700
async copyRelatedContent(): Promise<void> {
690701
const charts = await Chart.getAllOnSlide(this.sourceArchive, this.relsPath);
702+
691703
for (const chart of charts) {
692704
await new Chart({
693705
mode: 'append',

src/dev.ts

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,23 @@ const automizer = new Automizer({
1010
const run = async () => {
1111
const pres = automizer
1212
.loadRoot(`RootTemplate.pptx`)
13-
.load(`SlideWithCharts.pptx`, 'charts')
14-
.load(`SlideWithImages.pptx`, 'images');
13+
.load(`ChartWaterfall.pptx`, 'charts');
1514

1615
const result = await pres
17-
.addSlide('charts', 2, (slide) => {
18-
slide.removeElement('ColumnChart');
16+
.addSlide('charts', 1, (slide) => {
17+
slide.addElement('charts', 1, 'Waterfall 1', [
18+
modify.setChartData(<ChartData>{
19+
series: [{ label: 'series 1' }],
20+
categories: [
21+
{ label: 'cat 2-1', values: [50] },
22+
{ label: 'cat 2-2', values: [14] },
23+
{ label: 'cat 2-3', values: [15] },
24+
{ label: 'cat 2-4', values: [26] },
25+
],
26+
}),
27+
]);
1928
})
20-
.addSlide('images', 2, (slide) => {
21-
slide.removeElement('imageJPG');
22-
slide.removeElement('Textfeld 5');
23-
slide.addElement('images', 2, 'imageJPG');
24-
})
25-
.write(`remove-element.test.pptx`);
29+
.write(`modify-existing-waterfall-chart.test.pptx`);
2630
};
2731

2832
run().catch((error) => {

src/enums/element-type.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,8 @@ export enum ElementType {
33
Image = 'Image',
44
Shape = 'Generic',
55
}
6+
7+
export enum ElementSubtype {
8+
chart = 'chart',
9+
chartEx = 'chartEx',
10+
}

src/helper/xml-helper.ts

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,14 @@ import { DOMParser, XMLSerializer } from '@xmldom/xmldom';
44
import { FileHelper } from './file-helper';
55
import {
66
DefaultAttribute,
7+
HelperElement,
78
OverrideAttribute,
89
RelationshipAttribute,
9-
HelperElement,
1010
} from '../types/xml-types';
1111
import { TargetByRelIdMap } from '../constants/constants';
1212
import { XmlPrettyPrint } from './xml-pretty-print';
13-
import {
14-
GetRelationshipsCallback,
15-
SourceSlideIdentifier,
16-
Target,
17-
} from '../types/types';
18-
import { XmlTemplateHelper } from './xml-template-helper';
13+
import { GetRelationshipsCallback, Target } from '../types/types';
14+
import _ from 'lodash';
1915
import { vd } from './general-helper';
2016

2117
export class XmlHelper {
@@ -130,23 +126,30 @@ export class XmlHelper {
130126
static async getTargetsFromRelationships(
131127
archive: JSZip,
132128
path: string,
133-
prefix: string,
129+
prefix: string | string[],
134130
suffix?: string | RegExp,
135131
): Promise<Target[]> {
132+
const prefixes = typeof prefix === 'string' ? [prefix] : prefix;
136133
return XmlHelper.getRelationships(
137134
archive,
138135
path,
139136
(element: Element, rels: Target[]) => {
140137
const target = element.getAttribute('Target');
141-
if (target.indexOf(prefix) === 0) {
142-
rels.push({
143-
file: target,
144-
rId: element.getAttribute('Id'),
145-
number: Number(
146-
target.replace(prefix, '').replace(suffix || '.xml', ''),
147-
),
148-
} as Target);
149-
}
138+
prefixes.forEach((prefix) => {
139+
const stripNumber = target
140+
.replace(prefix, '')
141+
.replace(suffix || '.xml', '');
142+
143+
// vd(stripNumber);
144+
if (target.indexOf(prefix) === 0) {
145+
rels.push({
146+
file: target,
147+
rId: element.getAttribute('Id'),
148+
number: Number(stripNumber),
149+
subtype: _.last(prefix.split('/')),
150+
} as Target);
151+
}
152+
});
150153
},
151154
);
152155
}

src/shapes/chart.ts

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export class Chart extends Shape implements IChart {
9292
await this.setTarget(targetTemplate, targetSlideNumber);
9393

9494
this.targetNumber = this.targetTemplate.incrementCounter('charts');
95-
this.wbRelsPath = `ppt/charts/_rels/chart${this.sourceNumber}.xml.rels`;
95+
this.wbRelsPath = `ppt/charts/_rels/${this.subtype}${this.sourceNumber}.xml.rels`;
9696

9797
await this.copyFiles();
9898
await this.copyChartStyleFiles();
@@ -109,15 +109,16 @@ export class Chart extends Shape implements IChart {
109109
async modifyChartData(): Promise<void> {
110110
const chartXml = await XmlHelper.getXmlFromArchive(
111111
this.targetArchive,
112-
`ppt/charts/chart${this.targetNumber}.xml`,
112+
`ppt/charts/${this.subtype}${this.targetNumber}.xml`,
113113
);
114+
114115
const workbook = await this.readWorkbook();
115116

116117
this.applyCallbacks(this.callbacks, this.targetElement, chartXml, workbook);
117118

118119
await XmlHelper.writeXmlToArchive(
119120
this.targetArchive,
120-
`ppt/charts/chart${this.targetNumber}.xml`,
121+
`ppt/charts/${this.subtype}${this.targetNumber}.xml`,
121122
chartXml,
122123
);
123124
await this.writeWorkbook(workbook);
@@ -193,7 +194,7 @@ export class Chart extends Shape implements IChart {
193194
this.wbExtension,
194195
);
195196
const worksheet = worksheets[0];
196-
197+
vd(worksheet);
197198
this.sourceWorksheet = worksheet.number === 0 ? '' : worksheet.number;
198199
this.targetWorksheet = '-created-' + this.targetNumber;
199200

@@ -228,16 +229,16 @@ export class Chart extends Shape implements IChart {
228229
async copyChartFiles(): Promise<void> {
229230
await FileHelper.zipCopy(
230231
this.sourceArchive,
231-
`ppt/charts/chart${this.sourceNumber}.xml`,
232+
`ppt/charts/${this.subtype}${this.sourceNumber}.xml`,
232233
this.targetArchive,
233-
`ppt/charts/chart${this.targetNumber}.xml`,
234+
`ppt/charts/${this.subtype}${this.targetNumber}.xml`,
234235
);
235236

236237
await FileHelper.zipCopy(
237238
this.sourceArchive,
238-
`ppt/charts/_rels/chart${this.sourceNumber}.xml.rels`,
239+
`ppt/charts/_rels/${this.subtype}${this.sourceNumber}.xml.rels`,
239240
this.targetArchive,
240-
`ppt/charts/_rels/chart${this.targetNumber}.xml.rels`,
241+
`ppt/charts/_rels/${this.subtype}${this.targetNumber}.xml.rels`,
241242
);
242243
}
243244

@@ -265,7 +266,7 @@ export class Chart extends Shape implements IChart {
265266
if (this.styleRelationFiles.relTypeChartImage) {
266267
for (const relTypeChartImage of this.styleRelationFiles
267268
.relTypeChartImage) {
268-
const imageInfo = await this.getTargetChartImageUri(relTypeChartImage);
269+
const imageInfo = this.getTargetChartImageUri(relTypeChartImage);
269270
await this.appendImageExtensionToContentType(imageInfo.extension);
270271
await FileHelper.zipCopy(
271272
this.sourceArchive,
@@ -307,10 +308,11 @@ export class Chart extends Shape implements IChart {
307308
this.targetArchive,
308309
this.targetSlideRelFile,
309310
);
311+
310312
const attributes = {
311313
Id: this.createdRid,
312314
Type: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart',
313-
Target: `../charts/chart${this.targetNumber}.xml`,
315+
Target: `../charts/${this.subtype}${this.targetNumber}.xml`,
314316
} as RelationshipAttribute;
315317

316318
return XmlHelper.append(
@@ -323,7 +325,7 @@ export class Chart extends Shape implements IChart {
323325
}
324326

325327
async editTargetWorksheetRel(): Promise<void> {
326-
const targetRelFile = `ppt/charts/_rels/chart${this.targetNumber}.xml.rels`;
328+
const targetRelFile = `ppt/charts/_rels/${this.subtype}${this.targetNumber}.xml.rels`;
327329
const relXml = await XmlHelper.getXmlFromArchive(
328330
this.targetArchive,
329331
targetRelFile,
@@ -403,7 +405,7 @@ export class Chart extends Shape implements IChart {
403405
appendChartToContentType(): Promise<HelperElement> {
404406
return XmlHelper.append(
405407
XmlHelper.createContentTypeChild(this.targetArchive, {
406-
PartName: `/ppt/charts/chart${this.targetNumber}.xml`,
408+
PartName: `/ppt/charts/${this.subtype}${this.targetNumber}.xml`,
407409
ContentType: `application/vnd.openxmlformats-officedocument.drawingml.chart+xml`,
408410
}),
409411
);
@@ -431,10 +433,9 @@ export class Chart extends Shape implements IChart {
431433
archive: JSZip,
432434
relsPath: string,
433435
): Promise<Target[]> {
434-
return await XmlHelper.getTargetsFromRelationships(
435-
archive,
436-
relsPath,
437-
'../charts/chart',
438-
);
436+
return await XmlHelper.getTargetsFromRelationships(archive, relsPath, [
437+
'../charts/chartEx',
438+
// '../charts/chart',
439+
]);
439440
}
440441
}

src/types/types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import JSZip from 'jszip';
2-
import { ElementType } from '../enums/element-type';
2+
import { ElementSubtype, ElementType } from '../enums/element-type';
33

44
export type SourceSlideIdentifier = number | string;
55
export type SlideModificationCallback = (document: Document) => void;
@@ -65,6 +65,8 @@ export type Target = {
6565
file: string;
6666
number?: number;
6767
rId?: string;
68+
prefix?: string;
69+
subtype?: ElementSubtype;
6870
};
6971
export type ImportElement = {
7072
presName: string;

0 commit comments

Comments
 (0)