|
1 | 1 | /***************************************************************** |
2 | | -** Author: Asvin Goel, [email protected] |
3 | | -** Fixed for Reveal4: [email protected] |
4 | | -** |
5 | | -** A plugin for reveal.js allowing to integrate Chart.js |
6 | | -** |
7 | | -** Version: 1.3.1 |
8 | | -** |
9 | | -** License: MIT license (see LICENSE.md) |
10 | | -** |
11 | | -******************************************************************/ |
| 2 | + ** Author: Asvin Goel, [email protected] |
| 3 | + ** Fixed for Reveal4: [email protected] |
| 4 | + ** |
| 5 | + ** A plugin for reveal.js allowing to integrate Chart.js |
| 6 | + ** |
| 7 | + ** Version: 1.3.1 |
| 8 | + ** |
| 9 | + ** License: MIT license (see LICENSE.md) |
| 10 | + ** |
| 11 | + ******************************************************************/ |
12 | 12 |
|
13 | 13 | /** |
14 | 14 | * Reveal Plugin |
15 | 15 | * https://revealjs.com/creating-plugins/ |
16 | 16 | */ |
17 | 17 | window.RevealChart = window.RevealChart || { |
18 | | - id: 'RevealChart', |
| 18 | + id: "RevealChart", |
19 | 19 | init: function(deck) { |
20 | | - initChart(deck); |
| 20 | + initChart(deck); |
| 21 | + }, |
| 22 | + update: function(canvas, idx, data) { |
| 23 | + update(canvas, idx, data); |
21 | 24 | }, |
22 | | - update: function(canvas, idx, data) { update(canvas, idx, data); }, |
23 | 25 | }; |
24 | 26 |
|
25 | | -const initChart = function(Reveal){ |
26 | | -function parseJSON(str) { |
| 27 | +const initChart = function(Reveal) { |
| 28 | + function parseJSON(str) { |
27 | 29 | var json; |
28 | 30 | try { |
29 | | - json = JSON.parse(str); |
| 31 | + json = JSON.parse(str); |
30 | 32 | } catch (e) { |
31 | | - return null; |
32 | | - } |
33 | | - return json; |
34 | | -} |
35 | | - |
36 | | -/* |
37 | | -* Recursively merge properties of two objects |
38 | | -*/ |
39 | | -function mergeRecursive(obj1, obj2) { |
| 33 | + return null; |
| 34 | + } |
| 35 | + return json; |
| 36 | + } |
40 | 37 |
|
41 | | - for (var p in obj2) { |
42 | | - try { |
43 | | - // Property in destination object set; update its value. |
44 | | - if ( obj1[p] !== null && typeof obj1[p] === 'object' && typeof obj2[p] === 'object' ) { |
45 | | - obj1[p] = mergeRecursive(obj1[p], obj2[p]); |
46 | | - } |
47 | | - else { |
| 38 | + /* |
| 39 | + * Recursively merge properties of two objects |
| 40 | + */ |
| 41 | + function mergeRecursive(obj1, obj2) { |
| 42 | + for (var p in obj2) { |
| 43 | + try { |
| 44 | + // Property in destination object set; update its value. |
| 45 | + if (obj1[p] !== null && typeof obj1[p] === "object" && typeof obj2[p] === "object") { |
| 46 | + obj1[p] = mergeRecursive(obj1[p], obj2[p]); |
| 47 | + } else { |
| 48 | + obj1[p] = obj2[p]; |
| 49 | + } |
| 50 | + } catch (e) { |
| 51 | + // Property in destination object not set; create it and set its value. |
48 | 52 | obj1[p] = obj2[p]; |
49 | 53 | } |
50 | | - } catch(e) { |
51 | | - // Property in destination object not set; create it and set its value. |
52 | | - obj1[p] = obj2[p]; |
53 | 54 | } |
| 55 | + |
| 56 | + return obj1; |
54 | 57 | } |
55 | 58 |
|
56 | | - return obj1; |
57 | | -} |
58 | | - |
59 | | - |
60 | | -function createChart(canvas, CSV, comments) { |
61 | | - canvas.chart = null; |
62 | | - var ctx = canvas.getContext("2d"); |
63 | | - var chartOptions = { responsive: true, maintainAspectRatio: false }; |
64 | | - var chartData = { labels: null, datasets: []}; |
65 | | - if ( comments !== null ) for (var j = 0; j < comments.length; j++ ){ |
66 | | - comments[j] = comments[j].replace(/<!--/,''); |
67 | | - comments[j] = comments[j].replace(/-->/,''); |
68 | | - var config = parseJSON(comments[j]); |
69 | | - if ( config ) { |
70 | | - if ( config.data ) { |
71 | | - mergeRecursive( chartData, config.data); |
72 | | - } |
73 | | - if ( config.options ) { |
74 | | - mergeRecursive( chartOptions, config.options); |
| 59 | + function createChart(canvas, CSV, comments) { |
| 60 | + canvas.chart = null; |
| 61 | + var ctx = canvas.getContext("2d"); |
| 62 | + var chartOptions = { responsive: true, maintainAspectRatio: false }; |
| 63 | + var chartData = { labels: null, datasets: [] }; |
| 64 | + if (comments !== null) { |
| 65 | + for (var j = 0; j < comments.length; j++) { |
| 66 | + comments[j] = comments[j].replace(/<!--/, ""); |
| 67 | + comments[j] = comments[j].replace(/-->/, ""); |
| 68 | + var config = parseJSON(comments[j]); |
| 69 | + if (config) { |
| 70 | + if (config.data) { |
| 71 | + mergeRecursive(chartData, config.data); |
| 72 | + } |
| 73 | + if (config.options) { |
| 74 | + mergeRecursive(chartOptions, config.options); |
| 75 | + } |
| 76 | + } |
75 | 77 | } |
76 | 78 | } |
77 | | - } |
78 | 79 |
|
79 | | - var lines = CSV.split('\n').filter(function(v){return v!==''}); |
80 | | - // if labels are not defined, get them from first line |
81 | | - if ( chartData.labels === null && lines.length > 0 ) { |
82 | | - chartData.labels = lines[0].split(','); |
83 | | - chartData.labels.shift(); |
84 | | - lines.shift(); |
85 | | - } |
86 | | - // get data values |
87 | | - for (var j = 0; j < lines.length; j++ ){ |
88 | | - if (chartData.datasets.length <= j) chartData.datasets[j] = {}; |
89 | | - chartData.datasets[j].data = lines[j].split(','); //.filter(function(v){return v!==''}); |
90 | | - chartData.datasets[j].label = chartData.datasets[j].data[0]; |
91 | | - chartData.datasets[j].data.shift(); |
92 | | - for (var k = 0; k < chartData.datasets[j].data.length; k++ ){ |
93 | | - chartData.datasets[j].data[k] = Number(chartData.datasets[j].data[k]); |
| 80 | + var lines = CSV.split("\n").filter(function(v) { |
| 81 | + return v !== ""; |
| 82 | + }); |
| 83 | + // if labels are not defined, get them from first line |
| 84 | + if (chartData.labels === null && lines.length > 0) { |
| 85 | + chartData.labels = lines[0].split(","); |
| 86 | + chartData.labels.shift(); |
| 87 | + lines.shift(); |
| 88 | + } |
| 89 | + // get data values |
| 90 | + for (var j = 0; j < lines.length; j++) { |
| 91 | + if (chartData.datasets.length <= j) chartData.datasets[j] = {}; |
| 92 | + chartData.datasets[j].data = lines[j].split(","); // .filter(function(v){return v!==''}); |
| 93 | + chartData.datasets[j].label = chartData.datasets[j].data[0]; |
| 94 | + chartData.datasets[j].data.shift(); |
| 95 | + for (var k = 0; k < chartData.datasets[j].data.length; k++) { |
| 96 | + chartData.datasets[j].data[k] = Number(chartData.datasets[j].data[k]); |
| 97 | + } |
94 | 98 | } |
95 | | - } |
96 | 99 |
|
97 | | - // add chart options |
98 | | - var config = chartConfig[canvas.getAttribute("data-chart")]; |
99 | | - if ( config ) { |
100 | | - for (var j = 0; j < chartData.datasets.length; j++ ){ |
101 | | - for (var attrname in config) { |
102 | | - if ( !chartData.datasets[j][attrname] ) { |
103 | | - chartData.datasets[j][attrname] = config[attrname][j%config[attrname].length]; |
| 100 | + // add chart options |
| 101 | + var config = chartConfig[canvas.getAttribute("data-chart")]; |
| 102 | + if (config) { |
| 103 | + for (var j = 0; j < chartData.datasets.length; j++) { |
| 104 | + for (var attrname in config) { |
| 105 | + if (!chartData.datasets[j][attrname]) { |
| 106 | + chartData.datasets[j][attrname] = config[attrname][j % config[attrname].length]; |
| 107 | + } |
104 | 108 | } |
105 | 109 | } |
106 | 110 | } |
| 111 | + |
| 112 | + canvas.chart = new Chart(ctx, { type: canvas.getAttribute("data-chart"), data: chartData, options: chartOptions }); |
107 | 113 | } |
108 | 114 |
|
109 | | - canvas.chart = new Chart(ctx, { type: canvas.getAttribute("data-chart"), data: chartData, options: chartOptions }); |
110 | | - |
111 | | -} |
112 | | - |
113 | | -function updateChart(canvas, idx, data) { |
114 | | - canvas.chart.data.datasets[idx].data = data; |
115 | | - recreateChart( canvas ); |
116 | | -} |
117 | | - |
118 | | -var initializeCharts = function(){ |
119 | | - // Get all canvases |
120 | | - var canvases = document.querySelectorAll("canvas"); |
121 | | - for (var i = 0; i < canvases.length; i++ ){ |
122 | | - // check if canvas has data-chart attribute |
123 | | - if ( canvases[i].hasAttribute("data-chart") ){ |
124 | | - var CSV = canvases[i].innerHTML.trim(); |
125 | | - var comments = CSV.match(/<!--[\s\S]*?-->/g); |
126 | | - CSV = CSV.replace(/<!--[\s\S]*?-->/g,'').replace(/^\s*\n/gm, "") |
127 | | - if ( ! canvases[i].hasAttribute("data-chart-src") ) { |
128 | | - createChart(canvases[i], CSV, comments); |
129 | | - } |
130 | | - else { |
131 | | - var canvas = canvases[i]; |
132 | | - var xhr = new XMLHttpRequest(); |
133 | | - xhr.onload = function() { |
134 | | - if (xhr.readyState === 4) { |
135 | | - createChart(canvas, xhr.responseText, comments); |
136 | | - } |
137 | | - else { |
138 | | - console.warn( 'Failed to get file ' + canvas.getAttribute("data-chart-src") +". ReadyState: " + xhr.readyState + ", Status: " + xhr.status); |
139 | | - } |
140 | | - }; |
| 115 | + function updateChart(canvas, idx, data) { |
| 116 | + canvas.chart.data.datasets[idx].data = data; |
| 117 | + recreateChart(canvas); |
| 118 | + } |
141 | 119 |
|
142 | | - xhr.open( 'GET', canvas.getAttribute("data-chart-src"), false ); |
143 | | - try { |
144 | | - xhr.send(); |
145 | | - } |
146 | | - catch ( error ) { |
147 | | - console.warn( 'Failed to get file ' + canvas.getAttribute("data-chart-src") + '. Make sure that the presentation and the file are served by a HTTP server and the file can be found there. ' + error ); |
| 120 | + var initializeCharts = function() { |
| 121 | + // Get all canvases |
| 122 | + var canvases = document.querySelectorAll("canvas"); |
| 123 | + for (var i = 0; i < canvases.length; i++) { |
| 124 | + // check if canvas has data-chart attribute |
| 125 | + if (canvases[i].hasAttribute("data-chart")) { |
| 126 | + var CSV = canvases[i].innerHTML.trim(); |
| 127 | + var comments = CSV.match(/<!--[\s\S]*?-->/g); |
| 128 | + CSV = CSV.replace(/<!--[\s\S]*?-->/g, "").replace(/^\s*\n/gm, ""); |
| 129 | + if (!canvases[i].hasAttribute("data-chart-src")) { |
| 130 | + createChart(canvases[i], CSV, comments); |
| 131 | + } else { |
| 132 | + var canvas = canvases[i]; |
| 133 | + var xhr = new XMLHttpRequest(); |
| 134 | + xhr.onload = function() { |
| 135 | + if (xhr.readyState === 4) { |
| 136 | + createChart(canvas, xhr.responseText, comments); |
| 137 | + } else { |
| 138 | + console.warn( |
| 139 | + "Failed to get file " + canvas.getAttribute("data-chart-src") + ". ReadyState: " + xhr.readyState |
| 140 | + + ", Status: " + xhr.status, |
| 141 | + ); |
| 142 | + } |
| 143 | + }; |
| 144 | + |
| 145 | + xhr.open("GET", canvas.getAttribute("data-chart-src"), false); |
| 146 | + try { |
| 147 | + xhr.send(); |
| 148 | + } catch (error) { |
| 149 | + console.warn( |
| 150 | + "Failed to get file " + canvas.getAttribute("data-chart-src") |
| 151 | + + ". Make sure that the presentation and the file are served by a HTTP server and the file can be found there. " |
| 152 | + + error, |
| 153 | + ); |
| 154 | + } |
148 | 155 | } |
149 | 156 | } |
150 | | - |
151 | 157 | } |
152 | | - } |
153 | | -} |
154 | | - |
155 | | -function recreateChart(canvas) { |
156 | | - // clear data to redraw animation |
157 | | - var data = canvas.chart.data.datasets; |
158 | | - canvas.chart.data.datasets = []; |
159 | | - canvas.chart.update(); |
160 | | - canvas.style.visibility = "hidden"; |
161 | | - setTimeout( function(canvas, data) { |
162 | | - canvas.chart.data.datasets = data; |
163 | | - canvas.style.visibility = "visible"; |
| 158 | + }; |
| 159 | + |
| 160 | + function recreateChart(canvas) { |
| 161 | + // clear data to redraw animation |
| 162 | + var data = canvas.chart.data.datasets; |
| 163 | + canvas.chart.data.datasets = []; |
164 | 164 | canvas.chart.update(); |
165 | | - }, 500, canvas, data); // wait for slide transition to re-add data and animation |
166 | | -/* |
| 165 | + canvas.style.visibility = "hidden"; |
| 166 | + setTimeout( |
| 167 | + function(canvas, data) { |
| 168 | + canvas.chart.data.datasets = data; |
| 169 | + canvas.style.visibility = "visible"; |
| 170 | + canvas.chart.update(); |
| 171 | + }, |
| 172 | + 500, |
| 173 | + canvas, |
| 174 | + data, |
| 175 | + ); // wait for slide transition to re-add data and animation |
| 176 | + /* |
167 | 177 | var config = canvas.chart.config; |
168 | 178 | canvas.chart.destroy(); |
169 | 179 | setTimeout( function() { canvas.chart = new Chart(canvas, config);}, 500); // wait for slide transition |
170 | | -*/ |
171 | | -} |
172 | | - |
173 | | -// check if chart option is given or not |
174 | | -var chartConfig = Reveal.getConfig().chart || {}; |
175 | | - |
176 | | -// set global chart options |
177 | | -var config = chartConfig.defaults; |
178 | | -if ( config ) { |
179 | | - mergeRecursive(Chart.defaults, config); |
180 | | -} |
181 | | - |
182 | | -Reveal.addEventListener('ready', function(){ |
183 | | - initializeCharts(); |
184 | | - Reveal.addEventListener('slidechanged', function(){ |
185 | | - var canvases = Reveal.getCurrentSlide().querySelectorAll("canvas[data-chart]"); |
186 | | - for (var i = 0; i < canvases.length; i++ ){ |
187 | | - if ( canvases[i].chart && canvases[i].chart.config.options.animation !== false ) { |
188 | | - recreateChart( canvases[i] ); |
189 | | - } |
190 | | - } |
| 180 | + */ |
| 181 | + } |
| 182 | + |
| 183 | + // check if chart option is given or not |
| 184 | + var chartConfig = Reveal.getConfig().chart || {}; |
191 | 185 |
|
| 186 | + // set global chart options |
| 187 | + var config = chartConfig.defaults; |
| 188 | + if (config) { |
| 189 | + mergeRecursive(Chart.defaults, config); |
| 190 | + } |
| 191 | + |
| 192 | + Reveal.addEventListener("ready", function() { |
| 193 | + initializeCharts(); |
| 194 | + Reveal.addEventListener("slidechanged", function() { |
| 195 | + var canvases = Reveal.getCurrentSlide().querySelectorAll("canvas[data-chart]"); |
| 196 | + for (var i = 0; i < canvases.length; i++) { |
| 197 | + if (canvases[i].chart && canvases[i].chart.config.options.animation !== false) { |
| 198 | + recreateChart(canvases[i]); |
| 199 | + } |
| 200 | + } |
| 201 | + }); |
192 | 202 | }); |
193 | | -}); |
194 | 203 |
|
195 | | -this.update = updateChart; |
| 204 | + this.update = updateChart; |
196 | 205 |
|
197 | | -return this; |
| 206 | + return this; |
198 | 207 | }; |
0 commit comments