Skip to content

Commit d8395ba

Browse files
committed
chore(chart): support custom image based textures for line markers
1 parent 7749b8f commit d8395ba

File tree

3 files changed

+70
-28
lines changed

3 files changed

+70
-28
lines changed

src/classes/shape.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import {
88
Workbook,
99
} from '../types/types';
1010
import { RootPresTemplate } from '../interfaces/root-pres-template';
11+
import { HelperElement } from '../types/xml-types';
12+
import { ImageTypeMap } from '../enums/image-type-map';
1113

1214
export class Shape {
1315
mode: string;
@@ -39,6 +41,7 @@ export class Shape {
3941

4042
callbacks: ShapeModificationCallback[];
4143
hasCreationId: boolean;
44+
contentTypeMap: typeof ImageTypeMap;
4245

4346
constructor(shape: ImportedElement) {
4447
this.mode = shape.mode;
@@ -51,7 +54,7 @@ export class Shape {
5154
this.hasCreationId = shape.hasCreationId;
5255

5356
this.callbacks = GeneralHelper.arrayify(shape.callback);
54-
57+
this.contentTypeMap = ImageTypeMap;
5558
if (shape.target) {
5659
this.sourceNumber = shape.target.number;
5760
this.sourceRid = shape.target.rId;
@@ -170,4 +173,22 @@ export class Shape {
170173
}
171174
});
172175
}
176+
177+
appendImageExtensionToContentType(
178+
extension,
179+
): Promise<HelperElement | boolean> {
180+
const contentType = this.contentTypeMap[extension]
181+
? this.contentTypeMap[extension]
182+
: 'image/' + extension;
183+
184+
return XmlHelper.appendIf({
185+
...XmlHelper.createContentTypeChild(this.targetArchive, {
186+
Extension: extension,
187+
ContentType: contentType,
188+
}),
189+
tag: 'Default',
190+
clause: (xml: XMLDocument) =>
191+
!XmlHelper.findByAttribute(xml, 'Default', 'Extension', extension),
192+
});
193+
}
173194
}

src/shapes/chart.ts

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import JSZip from 'jszip';
22
import { FileHelper } from '../helper/file-helper';
33
import { XmlHelper } from '../helper/xml-helper';
44
import { Shape } from '../classes/shape';
5+
import path from 'path';
56

67
import { RelationshipAttribute, HelperElement } from '../types/xml-types';
78
import { ImportedElement, Target, Workbook } from '../types/types';
@@ -17,6 +18,7 @@ export class Chart extends Shape implements IChart {
1718
wbExtension: string;
1819
relTypeChartColorStyle: string;
1920
relTypeChartStyle: string;
21+
relTypeChartImage: string;
2022
wbRelsPath: string;
2123
styleRelationFiles: {
2224
[key: string]: string;
@@ -36,6 +38,8 @@ export class Chart extends Shape implements IChart {
3638
'http://schemas.microsoft.com/office/2011/relationships/chartColorStyle';
3739
this.relTypeChartStyle =
3840
'http://schemas.microsoft.com/office/2011/relationships/chartStyle';
41+
this.relTypeChartImage =
42+
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image';
3943
this.styleRelationFiles = {};
4044
}
4145

@@ -116,7 +120,7 @@ export class Chart extends Shape implements IChart {
116120
'nodebuffer',
117121
);
118122
const archive = await FileHelper.extractFileContent(
119-
(worksheet as unknown) as Buffer,
123+
worksheet as unknown as Buffer,
120124
);
121125
const sheet = await XmlHelper.getXmlFromArchive(
122126
archive,
@@ -247,10 +251,43 @@ export class Chart extends Shape implements IChart {
247251
`ppt/charts/colors${this.targetNumber}.xml`,
248252
);
249253
}
254+
255+
if (this.styleRelationFiles.relTypeChartImage) {
256+
const imageInfo = await this.getTargetChartImageUri(
257+
this.styleRelationFiles.relTypeChartImage,
258+
);
259+
await this.appendImageExtensionToContentType(imageInfo.extension);
260+
await FileHelper.zipCopy(
261+
this.sourceArchive,
262+
imageInfo.source,
263+
this.targetArchive,
264+
imageInfo.target,
265+
);
266+
}
267+
}
268+
269+
getTargetChartImageUri(origin: string): {
270+
source: string;
271+
target: string;
272+
rel: string;
273+
extension: string;
274+
} {
275+
const file = origin.replace('../media/', '');
276+
const extension = path.extname(file).replace('.', '');
277+
return {
278+
source: `ppt/media/${file}`,
279+
target: `ppt/media/${file}-chart-${this.targetNumber}.${extension}`,
280+
rel: `../media/${file}-chart-${this.targetNumber}.${extension}`,
281+
extension: extension,
282+
};
250283
}
251284

252285
async getChartStyles(): Promise<void> {
253-
const styleTypes = ['relTypeChartStyle', 'relTypeChartColorStyle'];
286+
const styleTypes = [
287+
'relTypeChartStyle',
288+
'relTypeChartColorStyle',
289+
'relTypeChartImage',
290+
];
254291

255292
for (const i in styleTypes) {
256293
const styleType = styleTypes[i];
@@ -273,8 +310,7 @@ export class Chart extends Shape implements IChart {
273310
);
274311
const attributes = {
275312
Id: this.createdRid,
276-
Type:
277-
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart',
313+
Type: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart',
278314
Target: `../charts/chart${this.targetNumber}.xml`,
279315
} as RelationshipAttribute;
280316

@@ -313,6 +349,12 @@ export class Chart extends Shape implements IChart {
313349
case this.relTypeChartStyle:
314350
element.setAttribute('Target', `style${this.targetNumber}.xml`);
315351
break;
352+
case this.relTypeChartImage:
353+
const target = element.getAttribute('Target');
354+
const imageInfo = this.getTargetChartImageUri(target);
355+
vd(imageInfo);
356+
element.setAttribute('Target', imageInfo.rel);
357+
break;
316358
}
317359
});
318360

src/shapes/image.ts

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { ElementType } from '../enums/element-type';
1212

1313
export class Image extends Shape implements IImage {
1414
extension: string;
15-
contentTypeMap: typeof ImageTypeMap;
1615

1716
constructor(shape: ImportedElement) {
1817
super(shape);
@@ -32,8 +31,6 @@ export class Image extends Shape implements IImage {
3231
element.parentNode.parentNode as Element;
3332
break;
3433
}
35-
36-
this.contentTypeMap = ImageTypeMap;
3734
}
3835

3936
async modify(
@@ -111,7 +108,7 @@ export class Image extends Shape implements IImage {
111108
}
112109

113110
async appendTypes(): Promise<void> {
114-
await this.appendImageExtensionToContentType();
111+
await this.appendImageExtensionToContentType(this.extension);
115112
}
116113

117114
async appendToSlideRels(): Promise<HelperElement> {
@@ -123,8 +120,7 @@ export class Image extends Shape implements IImage {
123120

124121
const attributes = {
125122
Id: this.createdRid,
126-
Type:
127-
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',
123+
Type: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',
128124
Target: `../media/image${this.targetNumber}.${this.extension}`,
129125
} as RelationshipAttribute;
130126

@@ -137,23 +133,6 @@ export class Image extends Shape implements IImage {
137133
);
138134
}
139135

140-
appendImageExtensionToContentType(): Promise<HelperElement | boolean> {
141-
const extension = this.extension;
142-
const contentType = this.contentTypeMap[extension]
143-
? this.contentTypeMap[extension]
144-
: 'image/' + extension;
145-
146-
return XmlHelper.appendIf({
147-
...XmlHelper.createContentTypeChild(this.targetArchive, {
148-
Extension: extension,
149-
ContentType: contentType,
150-
}),
151-
tag: 'Default',
152-
clause: (xml: XMLDocument) =>
153-
!XmlHelper.findByAttribute(xml, 'Default', 'Extension', extension),
154-
});
155-
}
156-
157136
hasSvgRelation(): boolean {
158137
return this.targetElement.getElementsByTagName('asvg:svgBlip').length > 0;
159138
}

0 commit comments

Comments
 (0)