UNPKG

pptx-automizer

Version:

A template based pptx generator

517 lines 18.8 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var _a; Object.defineProperty(exports, "__esModule", { value: true }); const modify_chart_1 = require("../modify/modify-chart"); const modify_xml_helper_1 = __importDefault(require("./modify-xml-helper")); const xml_helper_1 = require("./xml-helper"); const modify_color_helper_1 = __importDefault(require("./modify-color-helper")); class ModifyChartHelper { // Prevent a "null" from being written to the xml file. static parseCellValue(value) { if (value === null) return ''; return String(value); } } exports.default = ModifyChartHelper; _a = ModifyChartHelper; /** * Set chart data to modify default chart types. * See `__tests__/modify-existing-chart.test.js` */ ModifyChartHelper.setChartData = (data) => (element, chart, workbook) => { const slots = []; data.series.forEach((series, s) => { slots.push({ index: s, series: series, targetCol: s + 1, type: 'defaultSeries', }); }); new modify_chart_1.ModifyChart(chart, workbook, data, slots).modify(); // XmlHelper.dump(chart) // XmlHelper.dump(workbook.table) }; /** * Set chart data to modify vertical line charts. * See `__tests__/modify-chart-vertical-lines.test.js` */ ModifyChartHelper.setChartVerticalLines = (data) => (element, chart, workbook) => { const slots = []; slots.push({ label: `Y-Values`, mapData: (point, category) => category.y, targetCol: 1, }); data.series.forEach((series, s) => { slots.push({ index: s, series: series, targetCol: s + 2, type: 'xySeries', }); }); new modify_chart_1.ModifyChart(chart, workbook, data, slots).modify(); // ModifyChartHelper.setAxisRange({ // axisIndex: 0, // min: 0, // max: data.categories.length, // })(element, chart); }; /** * Set chart data to modify scatter charts. * See `__tests__/modify-chart-scatter.test.js` */ ModifyChartHelper.setChartScatter = (data) => (element, chart, workbook) => { const slots = []; data.series.forEach((series, s) => { const colId = s * 2; slots.push({ index: s, series: series, targetCol: colId + 1, type: 'customSeries', tag: 'c:xVal', mapData: (point) => point.x, }); slots.push({ label: `${series.label}-Y-Value`, index: s, series: series, targetCol: colId + 2, type: 'customSeries', tag: 'c:yVal', mapData: (point) => point.y, isStrRef: false, }); }); new modify_chart_1.ModifyChart(chart, workbook, data, slots).modify(); // XmlHelper.dump(chart) }; /** * Set chart data to modify combo charts. * This type is prepared for * first series: bar chart (e.g. total) * other series: vertical lines * See `__tests__/modify-chart-scatter.test.js` */ ModifyChartHelper.setChartCombo = (data) => (element, chart, workbook) => { const slots = []; slots.push({ index: 0, series: data.series[0], targetCol: 1, type: 'defaultSeries', }); slots.push({ index: 1, label: `Y-Values`, mapData: (point, category) => category.y, targetCol: 2, }); data.series.forEach((series, s) => { if (s > 0) slots.push({ index: s, series: series, targetCol: s + 2, targetYCol: 2, type: 'xySeries', }); }); new modify_chart_1.ModifyChart(chart, workbook, data, slots).modify(); ModifyChartHelper.setAxisRange({ axisIndex: 1, min: 0, max: data.categories.length, })(element, chart); }; /** * Set chart data to modify bubble charts. * See `__tests__/modify-chart-bubbles.test.js` */ ModifyChartHelper.setChartBubbles = (data) => (element, chart, workbook) => { const slots = []; data.series.forEach((series, s) => { const colId = s * 3; slots.push({ index: s, series: series, targetCol: colId + 1, type: 'customSeries', tag: 'c:xVal', mapData: (point) => point.x, }); slots.push({ label: `${series.label}-Y-Value`, index: s, series: series, targetCol: colId + 2, type: 'customSeries', tag: 'c:yVal', mapData: (point) => point.y, isStrRef: false, }); slots.push({ label: `${series.label}-Size`, index: s, series: series, targetCol: colId + 3, type: 'customSeries', tag: 'c:bubbleSize', mapData: (point) => point.size, isStrRef: false, }); }); new modify_chart_1.ModifyChart(chart, workbook, data, slots).modify(); // XmlHelper.dump(chart) }; /** * Set chart data to modify extended chart types. * See `__tests__/modify-existing-extended-chart.test.js` */ ModifyChartHelper.setExtendedChartData = (data) => (element, chart, workbook) => { const slots = []; data.series.forEach((series, s) => { slots.push({ index: s, series: series, targetCol: s + 1, type: 'extendedSeries', }); }); new modify_chart_1.ModifyChart(chart, workbook, data, slots).modifyExtended(); // XmlHelper.dump(chart); // XmlHelper.dump(workbook.table) }; /** * Read chart workbook data * See `__tests__/read-chart-data.test.js` */ ModifyChartHelper.readWorkbookData = (data) => (element, chart, workbook) => { const getSharedString = (index) => { var _b; return (_b = workbook.sharedStrings.getElementsByTagName('si').item(index)) === null || _b === void 0 ? void 0 : _b.textContent; }; const parseCell = (cell) => { const type = cell.getAttribute('t'); const cellValue = cell.getElementsByTagName('v').item(0).textContent; if (type === 's') { return getSharedString(Number(cellValue)); } else { return Number(cellValue); } }; const rows = workbook.sheet.getElementsByTagName('row'); for (let r = 0; r < rows.length; r++) { const row = rows.item(r); const columns = row.getElementsByTagName('c'); const rowData = []; for (let c = 0; c < columns.length; c++) { rowData.push(parseCell(columns.item(c))); } data.push(rowData); } }; /** * Read chart info * See `__tests__/read-chart-data.test.js` */ ModifyChartHelper.readChartInfo = (info) => (element, chart, workbook) => { const series = chart.getElementsByTagName('c:ser'); xml_helper_1.XmlHelper.modifyCollection(series, (tmpSeries, s) => { const solidFill = tmpSeries.getElementsByTagName('a:solidFill').item(0); if (!solidFill) { return; } const schemeClr = solidFill.getElementsByTagName('a:schemeClr').item(0); const srgbClr = solidFill.getElementsByTagName('a:srgbClr').item(0); const colorElement = schemeClr ? schemeClr : srgbClr; info.series.push({ seriesId: s, colorType: colorElement.tagName, colorValue: colorElement.getAttribute('val'), }); }); const chartTagName = series.item(0).parentNode.nodeName; info.chartType = chartTagName === null || chartTagName === void 0 ? void 0 : chartTagName.split(':')[1]; }; /** * Set range and format for chart axis. * Please notice: It will only work if the value to update is not set to * "Auto" in powerpoint. Only manually scaled min/max can be altered by this. * See `__tests__/modify-chart-axis.test.js` */ ModifyChartHelper.setAxisRange = (range) => (element, chart) => { const axis = chart.getElementsByTagName('c:valAx')[range.axisIndex || 0]; if (!axis) return; ModifyChartHelper.setAxisAttribute(axis, 'c:majorUnit', range.majorUnit); ModifyChartHelper.setAxisAttribute(axis, 'c:minorUnit', range.minorUnit); ModifyChartHelper.setAxisAttribute(axis, 'c:numFmt', range.formatCode, 'formatCode'); ModifyChartHelper.setAxisAttribute(axis, 'c:numFmt', range.sourceLinked, 'sourceLinked'); const scaling = axis.getElementsByTagName('c:scaling')[0]; ModifyChartHelper.setAxisAttribute(scaling, 'c:min', range.min); ModifyChartHelper.setAxisAttribute(scaling, 'c:max', range.max); }; ModifyChartHelper.setAxisAttribute = (element, tag, value, attribute) => { if (value === undefined || !element) return; const target = element.getElementsByTagName(tag); if (target.length > 0) { attribute = attribute || 'val'; if (typeof value === 'boolean') { modify_xml_helper_1.default.booleanAttribute(attribute, value)(target[0]); } else { modify_xml_helper_1.default.attribute(attribute, value)(target[0]); } } }; /** * Set legend coordinates to zero. Could be advantageous for pptx users to * be able to maximize a legend easily. Legend will still be selectible for * a user. */ ModifyChartHelper.minimizeChartLegend = () => (element, chart, workbook) => { _a.setLegendPosition({ w: 0.0, h: 0.0, x: 0.0, y: 0.0, })(element, chart, workbook); }; /** * Completely remove a chart legend. Please notice: This will trigger * PowerPoint to automatically maximize chart space. */ ModifyChartHelper.removeChartLegend = () => (element, chart) => { if (chart.getElementsByTagName('c:legend')) { xml_helper_1.XmlHelper.remove(chart.getElementsByTagName('c:legend')[0]); } }; /** * Update the coordinates of a chart legend. * legendArea coordinates are shares of chart coordinates, e.g. * "w: 0.5" means "half of chart width" * @param legendArea */ ModifyChartHelper.setLegendPosition = (legendArea) => (element, chart) => { const modifyXmlHelper = new modify_xml_helper_1.default(chart); modifyXmlHelper.modify({ 'c:legend': { children: { 'c:manualLayout': { children: { 'c:w': { modify: [modify_xml_helper_1.default.attribute('val', legendArea.w)], }, 'c:h': { modify: [modify_xml_helper_1.default.attribute('val', legendArea.h)], }, 'c:x': { modify: [modify_xml_helper_1.default.attribute('val', legendArea.x)], }, 'c:y': { modify: [modify_xml_helper_1.default.attribute('val', legendArea.y)], }, }, }, }, }, }); // XmlHelper.dump(chart.getElementsByTagName('c:legendPos')[0]); }; /** * Set the plot area coordinates of a chart. * * This modifier requires a 'c:manualLayout' element. It will only appear if * plot area coordinates are edited manually in ppt before. Recently fresh * created charts will not have a manualLayout by default. * * This is especially useful if you have problems with edgy elements on a * chart area that do not fit into the given space, e.g. when having a lot * of data labels. You can increase the chart and decrease the plot area * to create a margin. * * plotArea coordinates are shares of chart coordinates, e.g. * "w: 0.5" means "half of chart width" * * @param plotArea */ ModifyChartHelper.setPlotArea = (plotArea) => (element, chart) => { // Each chart has a separate chart xml file. It is required // to alter everything that's "inside" the chart, e.g. data, legend, // axis... and: plot area // ModifyXmlHelper class provides a lot of functions to access // and edit xml elements. const modifyXmlHelper = new modify_xml_helper_1.default(chart); // We need to locate the required xml elements and target them // with ModifyXmlHelper's help. // We can therefore log the entire chart.xml to console: // XmlHelper.dump(chart); // There needs to be a 'c:manualLayout' element. This will only appear if // a plot area was edited manually in ppt before. Recently fresh created // charts will not have a manualLayout by default. if (!chart .getElementsByTagName('c:plotArea')[0] .getElementsByTagName('c:manualLayout')[0]) { console.error("Can't update plot area. No c:manualLayout found."); return; } modifyXmlHelper.modify({ 'c:plotArea': { children: { 'c:manualLayout': { children: { 'c:w': { // Finally, we attach ModifyCallbacks to all // matching elements modify: [ modify_xml_helper_1.default.attribute('val', plotArea.w), // ... ], }, 'c:h': { modify: [modify_xml_helper_1.default.attribute('val', plotArea.h)], }, 'c:x': { modify: [modify_xml_helper_1.default.attribute('val', plotArea.x)], }, 'c:y': { modify: [modify_xml_helper_1.default.attribute('val', plotArea.y)], }, }, }, }, }, }); // We can dump the target node and see if our modification // took effect. // XmlHelper.dump( // chart // .getElementsByTagName('c:plotArea')[0] // .getElementsByTagName('c:manualLayout')[0], // ); // You can also take a look at element xml, which is a child node // of current slide. It holds general shape properties, but no // data or so. // XmlHelper.dump(chart); // Rough ones might also want to look inside the linked workbook. // It is located inside an extra xlsx file. We don't need this // for now. // XmlHelper.dump(workbook.table) // XmlHelper.dump(workbook.sheet) }; /** * Set a waterfall Total column to last * you may also optionally specify a different index. @param TotalColumnIDX * */ ModifyChartHelper.setWaterFallColumnTotalToLast = (TotalColumnIDX) => (element, chart) => { var _b, _c, _d, _e, _f; const plotArea = chart.getElementsByTagName('cx:plotArea')[0]; const subTotals = (_b = plotArea === null || plotArea === void 0 ? void 0 : plotArea.getElementsByTagName('cx:layoutPr')[0]) === null || _b === void 0 ? void 0 : _b.getElementsByTagName('cx:subtotals')[0]; if (subTotals) { if (!TotalColumnIDX) { const GetTotalPoints = (_f = (_e = (_d = (_c = chart .getElementsByTagName('cx:chartData')[0]) === null || _c === void 0 ? void 0 : _c.getElementsByTagName('cx:data')[0]) === null || _d === void 0 ? void 0 : _d.getElementsByTagName('cx:strDim')[0]) === null || _e === void 0 ? void 0 : _e.getElementsByTagName('cx:lvl')[0]) === null || _f === void 0 ? void 0 : _f.getAttribute('ptCount'); if (GetTotalPoints) { TotalColumnIDX = Number(GetTotalPoints) - 1; } } if (TotalColumnIDX !== undefined) { const stIndexes = Array.from(subTotals.getElementsByTagName('cx:idx')); stIndexes.forEach((sTValue, index) => { modify_xml_helper_1.default.attribute('val', TotalColumnIDX.toString())(sTValue); if (index > 0) { subTotals.removeChild(sTValue); } }); } } }; /** * Set the title of a chart. This requires an already existing, manually edited chart title. @param newTitle * */ ModifyChartHelper.setChartTitle = (newTitle) => (element, chart) => { const chartTitle = chart.getElementsByTagName('c:title').item(0); const chartTitleText = chartTitle === null || chartTitle === void 0 ? void 0 : chartTitle.getElementsByTagName('a:t').item(0); if (chartTitleText) { chartTitleText.textContent = newTitle; } }; /** * Specify a format for DataLabels @param dataLabel * */ ModifyChartHelper.setDataLabelAttributes = (dataLabel) => (element, chart) => { const modifyXmlHelper = new modify_xml_helper_1.default(chart); const applyToSeries = typeof dataLabel.applyToSeries === 'number' ? { index: dataLabel.applyToSeries, } : { all: true, }; modifyXmlHelper.modify({ 'c:ser': Object.assign(Object.assign({}, applyToSeries), { children: { 'c:dLbls': { children: ModifyChartHelper.setDataPointLabelAttributes(dataLabel), }, } }), }); }; ModifyChartHelper.setDataPointLabelAttributes = (dataLabel) => { return { 'c:spPr': { modify: [modify_color_helper_1.default.solidFill(dataLabel.solidFill)], }, 'c:dLblPos': { modify: [modify_xml_helper_1.default.attribute('val', dataLabel.dLblPos)], }, 'c:showLegendKey': { modify: [ modify_xml_helper_1.default.booleanAttribute('val', dataLabel.showLegendKey), ], }, 'c:showVal': { modify: [modify_xml_helper_1.default.booleanAttribute('val', dataLabel.showVal)], }, 'c:showCatName': { modify: [ modify_xml_helper_1.default.booleanAttribute('val', dataLabel.showCatName), ], }, 'c:showSerName': { modify: [ modify_xml_helper_1.default.booleanAttribute('val', dataLabel.showSerName), ], }, 'c:showPercent': { modify: [ modify_xml_helper_1.default.booleanAttribute('val', dataLabel.showPercent), ], }, 'c:showBubbleSize': { modify: [ modify_xml_helper_1.default.booleanAttribute('val', dataLabel.showBubbleSize), ], }, 'c:showLeaderLines': { modify: [ modify_xml_helper_1.default.booleanAttribute('val', dataLabel.showLeaderLines), ], }, }; }; //# sourceMappingURL=modify-chart-helper.js.map