diff --git a/dev-playground/public/samples/tables b/dev-playground/public/samples/tables index ae7ff965d..a88372282 100644 --- a/dev-playground/public/samples/tables +++ b/dev-playground/public/samples/tables @@ -275,8 +275,61 @@ content: [ ] }, layout: { - fillColor: function (i, node) { - return (i % 2 === 0) ? '#CCCCCC' : null; + fillColor: function (rowIndex, node, columnIndex) { + return (rowIndex % 2 === 0) ? '#CCCCCC' : null; + } + } + }, + {text: 'handling fill color opacity...', margin: [0, 20, 0, 8]}, + {text: '... just hardcoding values in the second row', margin: [0, 20, 0, 8]}, + { + style: 'tableExample', + table: { + body: [ + ['Sample value 1', 'Sample value 2', 'Sample value 3'], + [ + {text: 'Sample value 1',fillOpacity:0.15,fillColor:'blue'}, + {text: 'Sample value 2',fillOpacity:0.60,fillColor:'blue'}, + {text: 'Sample value 3',fillOpacity:0.85,fillColor:'blue'}, + ], + ['Sample value 1', 'Sample value 2', 'Sample value 3'] + ] + }, + }, + {text: '... using a custom styler and overriding it in the second row', margin: [0, 20, 0, 8]}, + { + style: 'tableOpacityExample', + table: { + body: [ + ['Sample value 1', 'Sample value 2', 'Sample value 3'], + [ + {text: 'Sample value 1',fillOpacity:0.15}, + {text: 'Sample value 2',fillOpacity:0.60}, + {text: 'Sample value 3',fillOpacity:0.85}, + ], + ['Sample value 1', 'Sample value 2', 'Sample value 3'] + ] + }, + }, + {text: '... with a function (opacity at 0 means fully transparent, i.e no color)', margin: [0, 20, 0, 8]}, + { + style: 'tableExample', + table: { + body: [ + ['Sample value 1', 'Sample value 2', 'Sample value 3'], + ['Sample value 1', 'Sample value 2', 'Sample value 3'], + ['Sample value 1', 'Sample value 2', 'Sample value 3'], + ['Sample value 1', 'Sample value 2', 'Sample value 3'], + ['Sample value 1', 'Sample value 2', 'Sample value 3'], + ['Sample value 1', 'Sample value 2', 'Sample value 3'], + ['Sample value 1', 'Sample value 2', 'Sample value 3'], + ['Sample value 1', 'Sample value 2', 'Sample value 3'], + ] + }, + layout: { + fillColor: 'blue', + fillOpacity: function (rowIndex, node, columnIndex) { + return (rowIndex/8+columnIndex/3); } } }, @@ -534,6 +587,11 @@ styles: { tableExample: { margin: [0, 5, 0, 15] }, + tableOpacityExample: { + margin: [0, 5, 0, 15], + fillColor: 'blue', + fillOpacity: 0.3 + }, tableHeader: { bold: true, fontSize: 13, diff --git a/examples/pdfs/tables.pdf b/examples/pdfs/tables.pdf index 60693d857..0351e5993 100644 Binary files a/examples/pdfs/tables.pdf and b/examples/pdfs/tables.pdf differ diff --git a/examples/tables.js b/examples/tables.js index d6899238e..dd0da6f94 100644 --- a/examples/tables.js +++ b/examples/tables.js @@ -295,6 +295,59 @@ var docDefinition = { } } }, + { text: 'handling fill color opacity...', margin: [0, 20, 0, 8] }, + { text: '... just hardcoding values in the second row', margin: [0, 20, 0, 8] }, + { + style: 'tableExample', + table: { + body: [ + ['Sample value 1', 'Sample value 2', 'Sample value 3'], + [ + {text: 'Sample value 1',fillOpacity:0.15,fillColor:'blue'}, + {text: 'Sample value 2',fillOpacity:0.60,fillColor:'blue'}, + {text: 'Sample value 3',fillOpacity:0.85,fillColor:'blue'}, + ], + ['Sample value 1', 'Sample value 2', 'Sample value 3'] + ] + }, + }, + { text: '... using a custom styler and overriding it in the second row', margin: [0, 20, 0, 8] }, + { + style: 'tableOpacityExample', + table: { + body: [ + ['Sample value 1', 'Sample value 2', 'Sample value 3'], + [ + {text: 'Sample value 1',fillOpacity:0.15}, + {text: 'Sample value 2',fillOpacity:0.60}, + {text: 'Sample value 3',fillOpacity:0.85}, + ], + ['Sample value 1', 'Sample value 2', 'Sample value 3'] + ] + }, + }, + { text: '... with a function (opacity at 0 means fully transparent, i.e no color)', margin: [0, 20, 0, 8] }, + { + style: 'tableExample', + table: { + body: [ + ['Sample value 1', 'Sample value 2', 'Sample value 3'], + ['Sample value 1', 'Sample value 2', 'Sample value 3'], + ['Sample value 1', 'Sample value 2', 'Sample value 3'], + ['Sample value 1', 'Sample value 2', 'Sample value 3'], + ['Sample value 1', 'Sample value 2', 'Sample value 3'], + ['Sample value 1', 'Sample value 2', 'Sample value 3'], + ['Sample value 1', 'Sample value 2', 'Sample value 3'], + ['Sample value 1', 'Sample value 2', 'Sample value 3'], + ] + }, + layout: { + fillColor: 'blue', + fillOpacity: function (rowIndex, node, columnIndex) { + return (rowIndex/8+columnIndex/3); + } + } + }, { text: 'and can be used dash border', margin: [0, 20, 0, 8] }, { style: 'tableExample', @@ -637,6 +690,11 @@ var docDefinition = { tableExample: { margin: [0, 5, 0, 15] }, + tableOpacityExample: { + margin: [0, 5, 0, 15], + fillColor: 'blue', + fillOpacity: 0.3 + }, tableHeader: { bold: true, fontSize: 13, diff --git a/src/docMeasure.js b/src/docMeasure.js index 0d80ff945..495521280 100644 --- a/src/docMeasure.js +++ b/src/docMeasure.js @@ -603,6 +603,7 @@ DocMeasure.prototype.measureTable = function (node) { return function () { if (isObject(data)) { data.fillColor = _this.styleStack.getProperty('fillColor'); + data.fillOpacity = _this.styleStack.getProperty('fillOpacity'); } return _this.measureNode(data); }; @@ -649,6 +650,9 @@ DocMeasure.prototype.measureTable = function (node) { fillColor: function (i, node) { return null; }, + fillOpacity: function (i, node) { + return 1; + }, defaultBorder: true }; @@ -731,7 +735,8 @@ DocMeasure.prototype.measureTable = function (node) { _span: true, _minWidth: 0, _maxWidth: 0, - fillColor: table.body[row][col].fillColor + fillColor: table.body[row][col].fillColor, + fillOpacity: table.body[row][col].fillOpacity }; } } diff --git a/src/styleContextStack.js b/src/styleContextStack.js index 8a332b541..0d93d88c5 100644 --- a/src/styleContextStack.js +++ b/src/styleContextStack.js @@ -94,6 +94,7 @@ StyleContextStack.prototype.autopush = function (item) { 'color', 'columnGap', 'fillColor', + 'fillOpacity', 'decoration', 'decorationStyle', 'decorationColor', diff --git a/src/tableProcessor.js b/src/tableProcessor.js index f59a81acc..1e7e127c0 100644 --- a/src/tableProcessor.js +++ b/src/tableProcessor.js @@ -2,6 +2,7 @@ var ColumnCalculator = require('./columnCalculator'); var isFunction = require('./helpers').isFunction; +var isNumber = require('./helpers').isNumber; function TableProcessor(tableNode) { this.tableNode = tableNode; @@ -419,9 +420,13 @@ TableProcessor.prototype.endRow = function (rowIndex, writer, pageBreaks) { if (i < l - 1) { var fillColor = body[rowIndex][colIndex].fillColor; + var fillOpacity = body[rowIndex][colIndex].fillOpacity; if (!fillColor) { fillColor = isFunction(this.layout.fillColor) ? this.layout.fillColor(rowIndex, this.tableNode, colIndex) : this.layout.fillColor; } + if (!isNumber(fillOpacity)) { + fillOpacity = isFunction(this.layout.fillOpacity) ? this.layout.fillOpacity(rowIndex, this.tableNode, colIndex) : this.layout.fillOpacity; + } if (fillColor) { var widthLeftBorder = leftCellBorder ? this.layout.vLineWidth(colIndex, this.tableNode) : 0; var widthRightBorder; @@ -444,7 +449,8 @@ TableProcessor.prototype.endRow = function (rowIndex, writer, pageBreaks) { w: x2f - x1f, h: y2f - y1f, lineWidth: 0, - color: fillColor + color: fillColor, + fillOpacity: fillOpacity }, false, true, writer.context().backgroundLength[writer.context().page]); } } diff --git a/tests/tableProcessor.js b/tests/tableProcessor.js index 7408a8dcb..81a64fca0 100644 --- a/tests/tableProcessor.js +++ b/tests/tableProcessor.js @@ -43,6 +43,9 @@ describe('TableProcessor', function () { fillColor: function (i, node) { return null; }, + fillOpacity: function (i, node) { + return 1; + }, defaultBorder: true }; @@ -154,7 +157,8 @@ describe('TableProcessor', function () { paddingTop: function () { }, vLineWidth: function () { }, hLineWidth: function () { }, - fillColor: function () { } + fillColor: function () { }, + fillOpacity: function () { } } }; };