modify-chart.jsā¢21.9 kB
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ModifyChart = void 0;
const xml_helper_1 = require("../helper/xml-helper");
const cell_id_helper_1 = __importDefault(require("../helper/cell-id-helper"));
const modify_xml_helper_1 = __importDefault(require("../helper/modify-xml-helper"));
const modify_text_helper_1 = __importDefault(require("../helper/modify-text-helper"));
const modify_color_helper_1 = __importDefault(require("../helper/modify-color-helper"));
class ModifyChart {
constructor(chart, workbook, data, slot) {
this.setSeriesDataLabels = () => {
this.data.series.forEach((series, s) => {
var _a;
this.chart.modify(this.series(s, this.seriesDataLabel(s, (_a = series.style) === null || _a === void 0 ? void 0 : _a.label)));
this.data.categories.forEach((category, c) => {
this.chart.modify(this.series(s, this.seriesDataLabelsRange(c, category.label)));
});
});
};
this.series = (index, children) => {
return {
'c:ser': {
index: index,
children: children,
},
};
};
this.chartPoint = (index, idx, style) => {
if (!(style === null || style === void 0 ? void 0 : style.color) && !(style === null || style === void 0 ? void 0 : style.border) && !(style === null || style === void 0 ? void 0 : style.marker))
return;
return {
'c:dPt': {
index: index,
children: Object.assign(Object.assign(Object.assign({ 'c:idx': {
modify: modify_xml_helper_1.default.attribute('val', idx),
} }, this.chartPointFill(style === null || style === void 0 ? void 0 : style.color)), this.chartPointBorder(style === null || style === void 0 ? void 0 : style.border)), this.chartPointMarker(style === null || style === void 0 ? void 0 : style.marker)),
},
};
};
this.chartPointFill = (color) => {
if (!(color === null || color === void 0 ? void 0 : color.type))
return;
return {
'c:spPr': {
modify: modify_color_helper_1.default.solidFill(color),
},
};
};
this.chartPointMarker = (markerStyle) => {
if (!markerStyle)
return;
return {
'c:marker': {
isRequired: false,
children: {
'c:spPr': {
modify: modify_color_helper_1.default.solidFill(markerStyle.color),
},
},
},
};
};
this.chartPointBorder = (style) => {
if (!style)
return;
const modify = [];
if (style.color) {
modify.push(modify_color_helper_1.default.solidFill(style.color));
modify.push(modify_color_helper_1.default.removeNoFill());
}
if (style.weight) {
modify.push(modify_xml_helper_1.default.attribute('w', style.weight));
}
return {
'a:ln': {
modify: modify,
},
};
};
this.chartPointLabel = (index, idx, labelStyle) => {
if (!labelStyle)
return;
return {
'c:dLbls': {
children: {
'c:dLbl': {
index: index,
children: {
'c:idx': {
modify: modify_xml_helper_1.default.attribute('val', String(idx)),
},
'a:pPr': {
modify: modify_color_helper_1.default.solidFill(labelStyle === null || labelStyle === void 0 ? void 0 : labelStyle.color),
children: {
'a:defRPr': {
isRequired: false,
modify: modify_text_helper_1.default.style(labelStyle),
},
},
},
},
},
},
},
};
};
this.seriesId = (series) => {
return {
'c:idx': {
modify: modify_xml_helper_1.default.attribute('val', series),
},
'c:order': {
modify: modify_xml_helper_1.default.attribute('val', series + 1),
},
};
};
this.seriesLabel = (label, series) => {
return {
'c:f': {
modify: modify_xml_helper_1.default.range(series + 1),
},
'c:v': {
modify: modify_text_helper_1.default.content(label),
},
};
};
this.extSeriesLabel = (label, series) => {
return {
'cx:f': {
modify: modify_xml_helper_1.default.range(series + 1),
},
'cx:v': {
modify: modify_text_helper_1.default.content(label),
},
};
};
this.seriesStyle = (series) => {
var _a;
if (!(series === null || series === void 0 ? void 0 : series.style))
return;
return {
'c:spPr': {
modify: modify_color_helper_1.default.solidFill(series.style.color),
},
'c:marker': {
isRequired: false,
children: {
'c:spPr': {
isRequired: false,
modify: modify_color_helper_1.default.solidFill((_a = series.style.marker) === null || _a === void 0 ? void 0 : _a.color),
},
},
},
};
};
this.seriesDataLabelsRange = (r, value) => {
return {
'c15:datalabelsRange': {
isRequired: false,
children: {
'c:pt': {
index: r,
modify: modify_xml_helper_1.default.value(value, r),
},
'c15:f': {
modify: modify_xml_helper_1.default.range(0, this.height),
},
'c:ptCount': {
modify: modify_xml_helper_1.default.attribute('val', this.height),
},
},
},
};
};
this.seriesDataLabel = (s, style) => {
return {
'c:dLbls': {
isRequired: false,
children: {
'a:pPr': {
modify: modify_color_helper_1.default.solidFill(style === null || style === void 0 ? void 0 : style.color),
children: {
'a:defRPr': {
modify: modify_text_helper_1.default.style(style),
},
},
},
},
},
};
};
this.extPoint = (r, c, value) => {
return {
children: {
'cx:pt': {
index: r,
modify: [
modify_xml_helper_1.default.attribute('idx', r),
modify_xml_helper_1.default.textContent(value),
],
},
'cx:f': {
modify: modify_xml_helper_1.default.range(c, this.height),
},
'cx:lvl': {
modify: modify_xml_helper_1.default.attribute('ptCount', this.height),
},
},
};
};
this.extSeries = (index, children) => {
return {
'cx:series': {
index: index,
children: children,
},
};
};
this.point = (r, c, value) => {
return {
children: {
'c:pt': {
index: r,
modify: modify_xml_helper_1.default.value(value, r),
},
'c:f': {
modify: modify_xml_helper_1.default.range(c, this.height),
},
'c:ptCount': {
modify: modify_xml_helper_1.default.attribute('val', this.height),
},
},
};
};
this.data = data;
// XmlHelper.dump(chart)
this.chart = new modify_xml_helper_1.default(chart);
this.workbook = new modify_xml_helper_1.default(workbook.sheet);
this.workbookTable = workbook.table
? new modify_xml_helper_1.default(workbook.table)
: null;
this.sharedStrings = workbook.sharedStrings;
this.columns = this.setColumns(slot);
this.height = this.data.categories.length;
this.width = this.columns.length;
}
modify() {
this.setValues();
this.setSeries();
this.setSeriesDataLabels();
this.setPointStyles();
this.sliceChartSpace();
this.modifyWorkbook();
// XmlHelper.dump(this.chart.root as XmlDocument)
}
modifyExtended() {
this.setExtData();
this.setExtSeries();
this.sliceExtChartSpace();
this.modifyWorkbook();
}
modifyWorkbook() {
this.prepareWorkbook();
this.setWorkbook();
this.sliceWorkbook();
if (this.workbookTable) {
this.setWorkbookTable();
this.sliceWorkbookTable();
}
}
setColumns(slots) {
const columns = [];
slots.forEach((slot) => {
const series = slot.series;
const index = slot.index;
const targetCol = slot.targetCol;
const targetYCol = slot.targetYCol || 1;
const label = slot.label ? slot.label : series.label;
const mapData = slot.mapData !== undefined ? slot.mapData : (point) => point;
const isStrRef = slot.isStrRef !== undefined ? slot.isStrRef : true;
const worksheetCb = (point, r, category) => {
return this.workbook.modify(this.rowValues(r, targetCol, mapData(point, category)));
};
const chartCb = slot.type !== undefined &&
this[slot.type] !== undefined &&
typeof this[slot.type] === 'function'
? (point, r, category) => {
return this[slot.type](r, targetCol, point, category, slot.tag, mapData, targetYCol);
}
: null;
const column = {
series: index,
label: label,
worksheet: worksheetCb,
chart: chartCb,
isStrRef: isStrRef,
};
columns.push(column);
});
return columns;
}
setValues() {
this.setValuesByCategory((col) => {
return this.series(col.series, col.modTags);
});
}
setExtData() {
this.setValuesByCategory((col) => {
return {
'cx:data': {
children: col.modTags,
},
};
});
}
setValuesByCategory(cb) {
this.data.categories.forEach((category, c) => {
this.columns
.filter((col) => col.chart)
.forEach((col, s) => {
if (category.values[col.series] === undefined) {
throw new Error(`No value for category "${category.label}" at series "${col.label}".`);
}
col.modTags = col.chart(category.values[col.series], c, category);
this.chart.modify(cb(col));
});
});
}
setPointStyles() {
const count = {};
this.data.categories.forEach((category, c) => {
if (category.styles) {
category.styles.forEach((style, s) => {
if (style === null || !Object.values(style).length)
return;
count[s] = !count[s] ? 0 : count[s];
this.chart.modify(this.series(s, this.chartPoint(count[s], c, style)));
if (style.label) {
this.chart.modify(this.series(s, this.chartPointLabel(count[s], c, style.label)));
}
count[s]++;
});
}
});
}
setSeries() {
this.columns.forEach((column, colId) => {
if (column.isStrRef === true) {
this.chart.modify(this.series(column.series, Object.assign(Object.assign(Object.assign({}, this.seriesId(column.series)), this.seriesLabel(column.label, colId)), this.seriesStyle(this.data.series[column.series]))));
}
});
}
setExtSeries() {
this.columns.forEach((column, colId) => {
if (column.isStrRef === true) {
this.chart.modify(this.extSeries(column.series, Object.assign({}, this.extSeriesLabel(column.label, colId))));
}
});
}
sliceChartSpace() {
this.chart.modify({
'c:plotArea': this.slice('c:ser', this.data.series.length),
});
this.columns
.filter((column) => column.modTags)
.forEach((column) => {
const sliceMod = {};
Object.keys(column.modTags).forEach((tag) => {
sliceMod[tag] = this.slice('c:pt', this.height);
});
this.chart.modify(this.series(column.series, sliceMod));
});
}
sliceExtChartSpace() {
this.chart.modify({
'cx:plotArea': this.slice('cx:series', this.data.series.length),
});
this.columns
.filter((column) => column.modTags)
.forEach((column) => {
const sliceMod = {};
Object.keys(column.modTags).forEach((tag) => {
sliceMod[tag] = this.slice('cx:pt', this.height);
});
this.chart.modify({
'cx:data': { index: column.series, children: sliceMod },
});
});
}
/*
There might be rows in an excel workbook that appear to be empty, but
contain either no cells or none with a "v"-tag. These rows are removed
by prepareWorkbook(). See https://github.com/singerla/pptx-automizer/issues/11
*/
prepareWorkbook() {
const rows = this.workbook.root.getElementsByTagName('row');
for (const r in rows) {
if (!rows[r].getElementsByTagName)
continue;
const values = rows[r].getElementsByTagName('v');
if (values.length === 0) {
const toRemove = rows[r];
toRemove.parentNode.removeChild(toRemove);
}
}
}
setWorkbook() {
this.workbook.modify(this.spanString());
this.workbook.modify(this.rowAttributes(0, 1));
this.data.categories.forEach((category, c) => {
const r = c + 1;
this.workbook.modify(this.rowLabels(r, category.label));
this.workbook.modify(this.rowAttributes(r, r + 1));
this.columns.forEach((addCol) => addCol.worksheet(category.values[addCol.series], r, category));
});
this.columns.forEach((addCol, s) => {
this.workbook.modify(this.colLabel(s + 1, addCol.label));
});
}
sliceWorkbook() {
this.data.categories.forEach((category, c) => {
const r = c + 1;
this.workbook.modify({
row: Object.assign({ index: r }, this.slice('c', this.width + 1)),
});
});
this.workbook.modify({
row: Object.assign({}, this.slice('c', this.width + 1)),
});
this.workbook.modify({
sheetData: this.slice('row', this.height + 1),
});
}
defaultSeries(r, targetCol, point, category) {
return {
'c:val': this.point(r, targetCol, point),
'c:cat': this.point(r, 0, category.label),
};
}
xySeries(r, targetCol, point, category, tag, mapData, targetYCol) {
return {
'c:xVal': this.point(r, targetCol, point),
'c:yVal': this.point(r, targetYCol, category.y),
};
}
customSeries(r, targetCol, point, category, tag, mapData) {
return {
[tag]: this.point(r, targetCol, mapData(point, category)),
};
}
extendedSeries(r, targetCol, point, category) {
return {
'cx:strDim': this.extPoint(r, 0, category.label),
'cx:numDim': this.extPoint(r, targetCol, point),
};
}
colLabel(c, label) {
return {
row: {
modify: modify_xml_helper_1.default.attribute('spans', `1:${this.width}`),
children: {
c: {
index: c,
modify: modify_xml_helper_1.default.attribute('r', cell_id_helper_1.default.getCellAddressString(c, 0)),
children: this.sharedString(label),
},
},
},
};
}
rowAttributes(r, rowId) {
return {
row: {
index: r,
fromPrevious: true,
modify: [
modify_xml_helper_1.default.attribute('spans', `1:${this.width}`),
modify_xml_helper_1.default.attribute('r', String(rowId)),
],
},
};
}
rowLabels(r, label) {
return {
row: {
index: r,
fromPrevious: true,
children: {
c: {
modify: modify_xml_helper_1.default.attribute('r', cell_id_helper_1.default.getCellAddressString(0, r)),
children: this.sharedString(label),
},
},
},
};
}
rowValues(r, c, value) {
return {
row: {
index: r,
fromPrevious: true,
children: {
c: {
index: c,
fromPrevious: true,
modify: modify_xml_helper_1.default.attribute('r', cell_id_helper_1.default.getCellAddressString(c, r)),
children: this.cellValue(value),
},
},
},
};
}
slice(tag, length) {
return {
children: {
[tag]: {
collection: (collection) => {
xml_helper_1.XmlHelper.sliceCollection(collection, length);
},
},
},
};
}
spanString() {
return {
dimension: {
modify: modify_xml_helper_1.default.attribute('ref', cell_id_helper_1.default.getSpanString(0, 1, this.width, this.height)),
},
};
}
cellValue(value) {
return {
v: {
modify: modify_text_helper_1.default.content(value),
},
};
}
sharedString(label) {
return this.cellValue(xml_helper_1.XmlHelper.appendSharedString(this.sharedStrings, label));
}
setWorkbookTable() {
this.workbookTable.modify({
table: {
modify: modify_xml_helper_1.default.attribute('ref', cell_id_helper_1.default.getSpanString(0, 1, this.width, this.height)),
},
tableColumns: {
modify: modify_xml_helper_1.default.attribute('count', this.width + 1),
},
});
this.setWorkbookTableFirstColumn();
this.columns.forEach((addCol, s) => {
this.setWorkbookTableColumn(s + 1, addCol.label);
});
}
setWorkbookTableFirstColumn() {
this.workbookTable.modify({
tableColumn: {
index: 0,
modify: modify_xml_helper_1.default.attribute('id', 1),
},
});
}
setWorkbookTableColumn(c, label) {
this.workbookTable.modify({
tableColumn: {
index: c,
fromPrevious: true,
modify: [
modify_xml_helper_1.default.attribute('id', c + 1),
modify_xml_helper_1.default.attribute('name', label),
],
},
});
}
sliceWorkbookTable() {
this.workbookTable.modify({
table: this.slice('tableColumn', this.width + 1),
});
}
}
exports.ModifyChart = ModifyChart;
//# sourceMappingURL=modify-chart.js.map