Wiki source code of TableToChartJS
Last modified by SuperNico Laub on 2025/09/18 16:38
Show last authors
| author | version | line-number | content |
|---|---|---|---|
| 1 | == Description == | ||
| 2 | |||
| 3 | Draws charts using Chart.js and the data from a table. | ||
| 4 | |||
| 5 | == Usage == | ||
| 6 | |||
| 7 | {{code language="none"}} | ||
| 8 | (% id="myTable" %) | ||
| 9 | |=Header1|=Header2 | ||
| 10 | |label|numeric value | ||
| 11 | ... | ||
| 12 | |||
| 13 | {{tableToChartJS type="..." table="myTable" /}} | ||
| 14 | {{/code}} | ||
| 15 | |||
| 16 | == Parameters == | ||
| 17 | |||
| 18 | {{velocity}} | ||
| 19 | #set ($parameters = $doc.getObjects('XWiki.WikiMacroParameterClass')) | ||
| 20 | #set ($headers = '|=Name|=Description|=Mandatory|=Default') | ||
| 21 | #set ($body = '') | ||
| 22 | #foreach ($parameter in $parameters) | ||
| 23 | #set ($isMandatory = ${parameter.getProperty('mandatory').value}) | ||
| 24 | #if ($isMandatory == 1) #set ($isMandatory = "Yes") #else #set ($isMandatory = "No") #end | ||
| 25 | #set ($body = "$body|${parameter.getProperty('name').value}|(((${parameter.getProperty('description').value})))|$isMandatory|$parameter.getProperty('defaultValue').value | ||
| 26 | ") | ||
| 27 | #end | ||
| 28 | ## This option is handy for generating the code to be pasted to the online extension.xwiki.org page for documenting the parameters statically (i.e. without having the macro object attached to the page). | ||
| 29 | #if ($request.debug) | ||
| 30 | {{code}} | ||
| 31 | $headers | ||
| 32 | $body | ||
| 33 | {{/code}} | ||
| 34 | #end | ||
| 35 | |||
| 36 | $headers | ||
| 37 | $body | ||
| 38 | {{/velocity}} | ||
| 39 | |||
| 40 | == Examples == | ||
| 41 | |||
| 42 | === Single Data Set === | ||
| 43 | |||
| 44 | (% id="singleDataSet" %) | ||
| 45 | |=Issue Type|=Count | ||
| 46 | |Bug|23 | ||
| 47 | |Improvement|17 | ||
| 48 | |{{html}}New Feature{{/html}}|9 | ||
| 49 | |Ideas|0 | ||
| 50 | |||
| 51 | {{velocity}} | ||
| 52 | #set ($chartOptions = { | ||
| 53 | "backgroundColors": ["#ff16e8", "#0018f4","#065d00"], | ||
| 54 | "opacity": 0.8, | ||
| 55 | "skipZeros": true, | ||
| 56 | "legend": { | ||
| 57 | "display": false | ||
| 58 | }, | ||
| 59 | "layout": { | ||
| 60 | "padding": { | ||
| 61 | "left": 50, | ||
| 62 | "right": 50, | ||
| 63 | "top": 50, | ||
| 64 | "bottom": 50 | ||
| 65 | } | ||
| 66 | }, | ||
| 67 | "plugins" : { | ||
| 68 | "datalabels": { | ||
| 69 | "anchor": "end", | ||
| 70 | "align": "end", | ||
| 71 | "includeLegend": true | ||
| 72 | } | ||
| 73 | } | ||
| 74 | }) | ||
| 75 | #set ($options = $jsontool.serialize($chartOptions).replaceAll("~","~~").replaceAll("'","~'")) | ||
| 76 | |||
| 77 | (% class="row" %)((( | ||
| 78 | #foreach ($type in ['pie', 'doughnut', 'polarArea']) | ||
| 79 | (% class="col-sm-6 col-md-4" %)((( | ||
| 80 | {{tableToChartJS type="$type" id="issues-$type" title="Issues" table="singleDataSet" options='$options' height="200px" cssClass="my-chart"/}} | ||
| 81 | ))) | ||
| 82 | #end | ||
| 83 | ))) | ||
| 84 | {{/velocity}} | ||
| 85 | |||
| 86 | === Multiple Data Sets === | ||
| 87 | |||
| 88 | {{velocity}} | ||
| 89 | #set ($chartOptions = { | ||
| 90 | "backgroundColors": ["#ff16e8", "#0018f4","#065d00"], | ||
| 91 | "opacity": 0.8, | ||
| 92 | "skipZeros": true | ||
| 93 | }) | ||
| 94 | #set ($options = $jsontool.serialize($chartOptions).replaceAll("~","~~").replaceAll("'","~'")) | ||
| 95 | {{/velocity}} | ||
| 96 | |||
| 97 | (% id="multipleDataSetsMerged" %) | ||
| 98 | |=Issue Type|=CKEditor|=Diagram | ||
| 99 | |Bug|25|34 | ||
| 100 | |Improvement|17|11 | ||
| 101 | |New Feature|5|6 | ||
| 102 | |Ideas|0|0 | ||
| 103 | |||
| 104 | {{velocity}} | ||
| 105 | (% class="row" %)((( | ||
| 106 | #foreach ($type in ['pie', 'doughnut']) | ||
| 107 | (% class="col-sm-6 col-md-4" %)((( | ||
| 108 | {{tableToChartJS type="$type" table="multipleDataSetsMerged" multipleDataSets="true" options='$options' /}} | ||
| 109 | ))) | ||
| 110 | #end | ||
| 111 | #set($chartOptions = { | ||
| 112 | "backgroundColors": ["#0079b6", "#ffe600"], | ||
| 113 | "opacity": 0.8, | ||
| 114 | "skipZeros": true, | ||
| 115 | "plugins" : { | ||
| 116 | "datalabels": { | ||
| 117 | "anchor": "end", | ||
| 118 | "align": "end", | ||
| 119 | "showLegend": true | ||
| 120 | } | ||
| 121 | } | ||
| 122 | }) | ||
| 123 | #set ($options = $jsontool.serialize($chartOptions).replaceAll("~","~~").replaceAll("'","~'")) | ||
| 124 | |||
| 125 | (% class="col-sm-6 col-md-4" %)((( | ||
| 126 | {{tableToChartJS type="bar" table="multipleDataSetsMerged" multipleDataSets="true" options='$options' /}} | ||
| 127 | ))) | ||
| 128 | |||
| 129 | ))) | ||
| 130 | {{/velocity}} | ||
| 131 | |||
| 132 | (% id="multipleDataSetsLine" %) | ||
| 133 | |=Month|=2016|=2017 | ||
| 134 | |January|65|61 | ||
| 135 | |February|59|73 | ||
| 136 | |March|80|82 | ||
| 137 | |April|81|69 | ||
| 138 | |May|56|70 | ||
| 139 | |June|55|58 | ||
| 140 | |July|40|47 | ||
| 141 | |||
| 142 | (% class="row" %)((( | ||
| 143 | (% class="col-sm-6" %)((( | ||
| 144 | {{tableToChartJS type="line" table="multipleDataSetsLine" multipleDataSets="true"/}} | ||
| 145 | ))) | ||
| 146 | |||
| 147 | {{velocity}} | ||
| 148 | #set ($stackedLineOptions = { | ||
| 149 | 'scales': { | ||
| 150 | 'yAxes': [{ | ||
| 151 | 'stacked': true | ||
| 152 | }] | ||
| 153 | } | ||
| 154 | }) | ||
| 155 | (% class="col-sm-6" %)((( | ||
| 156 | {{tableToChartJS type="line" table="multipleDataSetsLine" multipleDataSets="true" | ||
| 157 | options='$jsontool.serialize($stackedLineOptions)'/}} | ||
| 158 | ))) | ||
| 159 | {{/velocity}} | ||
| 160 | ))) | ||
| 161 | |||
| 162 | (% class="row" %)((( | ||
| 163 | (% class="col-sm-6" %)((( | ||
| 164 | (% id="multipleDataSetsRadar" %) | ||
| 165 | |=Month|=2016|=2017 | ||
| 166 | |Eating|65|28 | ||
| 167 | |Running|40|100 | ||
| 168 | |Cycling|55|27 | ||
| 169 | |Coding|56|96 | ||
| 170 | |Designing|81|19 | ||
| 171 | |Sleeping|90|40 | ||
| 172 | |Drinking|59|48 | ||
| 173 | ))) | ||
| 174 | |||
| 175 | (% class="col-sm-6" %)((( | ||
| 176 | {{tableToChartJS type="radar" table="multipleDataSetsRadar" multipleDataSets="true"/}} | ||
| 177 | ))) | ||
| 178 | ))) | ||
| 179 | |||
| 180 | === Merged Data Sets === | ||
| 181 | |||
| 182 | (% id="multipleDataSetsSplit" %) | ||
| 183 | |=Issue Type|=Project|=Count | ||
| 184 | |Bug|CKEditor|23 | ||
| 185 | |Bug|Diagram|34 | ||
| 186 | |Improvement|CKEditor|17 | ||
| 187 | |Improvement|Diagram|11 | ||
| 188 | |New Feature|CKEditor|5 | ||
| 189 | |New Feature|Diagram|6 | ||
| 190 | |||
| 191 | (% class="row" %)((( | ||
| 192 | (% class="col-sm-6" %)((( | ||
| 193 | {{tableToChartJS type="bar" table="multipleDataSetsSplit" multipleDataSets="true" dataSetLabel="1"/}} | ||
| 194 | ))) | ||
| 195 | |||
| 196 | (% class="col-sm-6" %)((( | ||
| 197 | {{tableToChartJS type="horizontalBar" table="multipleDataSetsSplit" multipleDataSets="true" dataSetLabel="1"/}} | ||
| 198 | ))) | ||
| 199 | |||
| 200 | {{velocity}} | ||
| 201 | #set ($stackedBarOptions = { | ||
| 202 | 'scales': { | ||
| 203 | 'xAxes': [{ | ||
| 204 | 'stacked': true | ||
| 205 | }], | ||
| 206 | 'yAxes': [{ | ||
| 207 | 'stacked': true | ||
| 208 | }] | ||
| 209 | } | ||
| 210 | }) | ||
| 211 | (% class="col-sm-6" %)((( | ||
| 212 | {{tableToChartJS type="bar" table="multipleDataSetsSplit" multipleDataSets="true" dataSetLabel="1" | ||
| 213 | options='$jsontool.serialize($stackedBarOptions)'/}} | ||
| 214 | ))) | ||
| 215 | |||
| 216 | (% class="col-sm-6" %)((( | ||
| 217 | {{tableToChartJS type="horizontalBar" table="multipleDataSetsSplit" multipleDataSets="true" dataSetLabel="1" | ||
| 218 | options='$jsontool.serialize($stackedBarOptions)'/}} | ||
| 219 | ))) | ||
| 220 | {{/velocity}} | ||
| 221 | ))) |