├── LICENSE
├── README.md
├── bower.json
└── dpeges.js
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Pascal TOUSSAINT
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://badge.fury.io/gh/pascalz%2Fdpeges)
2 |
3 | # DPE-GES
4 |
5 | A pure javascript utility to generate an SVG graph for DPE and GES diagnostics.
6 | No dependency needed, no need jQuery or RaphaelJS
7 |
8 | **DPE** : Diagnostic de performance énergétique (Energy Performance Diagnostic)
9 | **GES** : Gaz à effet de serre (Greenhouse Gas Emissions)
10 |
11 | ## Installation
12 |
13 | Just copy the dpeges.js file in your scripts folder.
14 |
15 | You can also use bower:
16 | ```
17 | $ bower install dpeges
18 | ```
19 |
20 | ## Basic example
21 |
22 | ```html
23 |
24 |
25 |
26 |
27 | GES/DPE basic example
28 |
29 |
30 |
31 |
32 |
33 |
34 |
46 |
47 |
48 |
49 | ```
50 |
51 | ## Options
52 |
53 | Option name | Description | Required | Default value
54 | ------------- | --------------------------------------------------------------- | -------- | -------------
55 | domId | The id of the element that will contain the generated SVG image | Yes |
56 | value | The DPE or GES actual value, can be an integer or just a letter | No | 200
57 | width | The width of the generated SVG image | No | 250
58 | height | The height of the generated SVG image | No | 200
59 | shadow | Add shadow to the image | No | false
60 | lang | The language to use (currently supported: 'fr' and 'en') | No | 'fr'
61 |
62 | ## Demo
63 |
64 | http://pascalz.github.io/dpeges/
65 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dpeges",
3 | "description": "Create an SVG graphic for DPE and GES diagnostics.",
4 | "main": "dpeges.js",
5 | "version": "0.0.4",
6 | "homepage": "https://github.com/Pascalz/dpeges",
7 | "authors": [
8 | "Pascalz (http://www.pascalz.com)"
9 | ],
10 | "keywords": [
11 | "DPE",
12 | "GES"
13 | ],
14 | "license": "MIT",
15 | "ignore": [
16 | "**/.*",
17 | "node_modules",
18 | "bower_components",
19 | "test",
20 | "tests"
21 | ]
22 | }
23 |
--------------------------------------------------------------------------------
/dpeges.js:
--------------------------------------------------------------------------------
1 | var DpeGes = function () {
2 |
3 | "use strict";
4 |
5 | function Diag(options) {
6 |
7 | var self = this;
8 |
9 | // Default options is DPE
10 | var defaultOptions = {
11 | width: 250,
12 | height: 200,
13 | value: 200,
14 | header: '',
15 | footer: '',
16 | valuesRange: [
17 | { min: null, max: 50, color: '#319834', textColor: '#000000', label: 'A' },
18 | { min: 51, max: 90, color: '#33cc31', textColor: '#000000', label: 'B' },
19 | { min: 91, max: 150, color: '#cbfc34', textColor: '#000000', label: 'C' },
20 | { min: 151, max: 230, color: '#fbfe06', textColor: '#000000', label: 'D' },
21 | { min: 231, max: 330, color: '#fbcc05', textColor: '#000000', label: 'E' },
22 | { min: 331, max: 450, color: '#fc9935', textColor: '#000000', label: 'F' },
23 | { min: 451, max: null, color: '#fc0205', textColor: '#ffffff', label: 'G' }
24 | ],
25 | shadow: false,
26 | lang: 'fr',
27 | pad: 5,
28 | shape: 'sharp',
29 | domId: undefined
30 | };
31 |
32 | self.width = options.width || defaultOptions.width;
33 | self.height = options.height || defaultOptions.height;
34 |
35 | self.value = options.value || defaultOptions.value;
36 | self.shadow = options.shadow || defaultOptions.shadow;
37 |
38 | self.header = options.header || defaultOptions.header;
39 | self.footer = options.footer || defaultOptions.footer;
40 |
41 | //self.options = options;
42 | self.lang = options.lang || defaultOptions.lang;
43 | self.pad = options.pad || defaultOptions.pad;
44 | self.shape = options.shape || defaultOptions.shape;
45 |
46 | self.domId = options.domId || defaultOptions.domId;
47 |
48 | var svgNS = "http://www.w3.org/2000/svg";
49 |
50 | self.container = document.getElementById(self.domId);
51 |
52 | // Empty container
53 | while (self.container.firstChild) {
54 | self.container.removeChild(self.container.firstChild);
55 | }
56 |
57 | self.score = -1;
58 |
59 | // Get texts and colors for each value in valuesRange
60 | self.getValuesDatas = function () {
61 |
62 | self.values = [];
63 | self.colors = [];
64 | self.textColors = [];
65 | self.labels = [];
66 |
67 | var toTxt = " à ";
68 | switch (self.lang) {
69 | case "fr":
70 | toTxt = " à ";
71 | break;
72 | case "en":
73 | toTxt = " to ";
74 | break;
75 | }
76 | options.valuesRange.forEach(function (value) {
77 | if (value.min === null && value.max !== null) {
78 | self.values.push("≤ " + value.max);
79 | } else if (value.min !== null && value.max !== null) {
80 | self.values.push(value.min + toTxt + value.max);
81 | } else if (value.min !== null && value.max === null) {
82 | self.values.push("> " + (value.min - 1));
83 | }
84 | self.colors.push(value.color);
85 | self.textColors.push(value.textColor);
86 | self.labels.push(value.label);
87 | });
88 | };
89 |
90 |
91 | self.getScore = function () {
92 | try {
93 | options.valuesRange.forEach(function (values) {
94 | self.score++;
95 | if (typeof self.value === 'string') {
96 | if (self.value === values.label) {
97 | throw {};
98 | }
99 | } else if (values.min === null && values.max !== null) {
100 | if (self.value <= values.max) {
101 | throw {};
102 | }
103 | } else if (values.min !== null && values.max !== null) {
104 | if (self.value >= values.min && self.value <= values.max) {
105 | throw {};
106 | }
107 | } else if (values.min !== null && values.max === null) {
108 | if (self.value >= values.min) {
109 | throw {};
110 | }
111 | }
112 | });
113 | } catch (e) {
114 | //
115 | }
116 | };
117 |
118 | self.setAttributes = function (elem, o) {
119 | if (o.fill) {
120 | elem.setAttribute("fill", o.fill);
121 | }
122 | if (o.fontSize) {
123 | elem.setAttribute("font-size", o.fontSize);
124 | }
125 | if (o.fontFamily) {
126 | elem.setAttribute("font-family", o.fontFamily);
127 | }
128 | if (o.textAnchor) {
129 | elem.setAttribute("text-anchor", o.textAnchor);
130 | }
131 | if (o.fontWeight) {
132 | elem.setAttribute("font-weight", o.fontWeight);
133 | }
134 | if (o.strokeWidth) {
135 | elem.setAttribute("stroke-width", o.strokeWidth);
136 | }
137 | if (o.stroke) {
138 | elem.setAttribute("stroke", o.stroke);
139 | }
140 | if (o.opacity) {
141 | elem.setAttribute("opacity", o.opacity);
142 | }
143 | };
144 |
145 | self.getPath = function (path, options) {
146 | var elem = document.createElementNS(svgNS, "path");
147 | self.setAttributes(elem, options);
148 |
149 | elem.setAttribute("d", path);
150 |
151 | return elem;
152 | };
153 |
154 | self.getPolygon = function (points, color) {
155 | var elem = document.createElementNS(svgNS, "polygon");
156 | elem.setAttribute("style", "fill-opacity: 1;fill: " + color + ";stroke: #000000;" + (self.shadow ? "filter:url(#fs)" : ""));
157 | elem.setAttribute("points", points);
158 |
159 | return elem;
160 | };
161 |
162 | self.getText = function (text) {
163 | var elem = document.createElementNS(svgNS, "text");
164 | elem.setAttribute("x", text.x);
165 | elem.setAttribute("y", text.y);
166 | elem.textContent = text.text;
167 | self.setAttributes(elem, text.options);
168 | return elem;
169 | };
170 |
171 | self.createSVG = function () {
172 | self.getScore();
173 | self.getValuesDatas();
174 |
175 | var svg = document.createElementNS(svgNS, "svg");
176 | svg.setAttribute("style", "overflow: hidden; position: relative;");
177 | svg.setAttribute("width", self.width);
178 | svg.setAttribute("height", self.height);
179 | svg.setAttribute("version", "1.1");
180 | svg.setAttribute("viewBox", "0 0 " + self.width + " " + self.height);
181 | svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
182 |
183 | var desc = document.createElementNS(svgNS, "desc");
184 | desc.textContent = 'Created by Pascalz (http://pascalz.github.io/dpeges/)';
185 | svg.appendChild(desc);
186 | var defs = document.createElementNS(svgNS, "defs");
187 | var filter = document.createElementNS(svgNS, "filter");
188 | filter.setAttribute("id", "fs");
189 | //filter.setAttribute("height", "120%");
190 |
191 | var feGaussianBlur = document.createElementNS(svgNS, "feGaussianBlur");
192 | feGaussianBlur.setAttribute("in", "SourceAlpha");
193 | feGaussianBlur.setAttribute("stdDeviation", "1");
194 | filter.appendChild(feGaussianBlur);
195 |
196 | var feOffset = document.createElementNS(svgNS, "feOffset");
197 | feOffset.setAttribute("result", "offsetblur");
198 | feOffset.setAttribute("dx", "1");
199 | feOffset.setAttribute("dy", "0.5");
200 | filter.appendChild(feOffset);
201 |
202 | var feMerge = document.createElementNS(svgNS, "feMerge");
203 | var feMergeNode1 = document.createElementNS(svgNS, "feMergeNode");
204 | feMerge.appendChild(feMergeNode1);
205 | var feMergeNode2 = document.createElementNS(svgNS, "feMergeNode");
206 | feMergeNode2.setAttribute("in", "SourceGraphic");
207 | feMerge.appendChild(feMergeNode2);
208 | filter.appendChild(feMerge);
209 | defs.appendChild(filter);
210 | svg.appendChild(defs);
211 |
212 | var countElem = self.values.length;
213 |
214 | var blocHeight = (self.height - ((countElem + 1) * self.pad)) / countElem;
215 | var blocWidth = (self.width - (2 * self.pad)) - 45;
216 |
217 | var blocPart = ((blocWidth / 3) * 2) / (countElem - 1);
218 | blocWidth = (blocWidth / 3);
219 |
220 | for (var i = 0; i < countElem; i++) {
221 | var x, y, x1, y1, x2, y2, poly;
222 | x = self.pad;
223 | y = ((i * self.pad) + self.pad) + (i * blocHeight);
224 |
225 | switch (self.shape) {
226 | case "sharp":
227 | x1 = ((blocWidth + (blocPart * i)) - (blocHeight / 2));
228 |
229 | x2 = x + (blocWidth + blocPart * i);
230 | y1 = y + (blocHeight / 2);
231 |
232 | y2 = y + blocHeight;
233 | poly = x + "," + y + " " +
234 | x1 + "," + y + " " +
235 | x2 + "," + y1 + " " +
236 | x1 + "," + y2 + " " +
237 | x + "," + y2 + " " +
238 | x + "," + y;
239 | break;
240 | case "flat":
241 | x1 = x + (blocWidth + blocPart * i);
242 |
243 | y1 = y + blocHeight;
244 | poly = x + "," + y + " " +
245 | x1 + "," + y + " " +
246 | x1 + "," + y1 + " " +
247 | x + "," + y1 + " " +
248 | x + "," + y;
249 | break;
250 | }
251 |
252 | if (self.score === i) {
253 | var sx1 = x - 2;
254 | var sx2 = (self.width - (2 * self.pad)) + 2;
255 | var sy1 = y - 2;
256 | var sy2 = y + blocHeight + 3;
257 |
258 | var scorePath = "M " + sx1 + " " + sy1 +
259 | "L" + sx2 + " " + sy1 +
260 | "L" + sx2 + " " + sy2 +
261 | "L" + sx1 + " " + sy2 + " Z";
262 | svg.appendChild(self.getPath(scorePath,
263 | {
264 | 'stroke': '#5b5b5b',
265 | 'strokeWidth': 1,
266 | 'fill': "#ffffff",
267 | 'fillOpacity': 0.8
268 | }));
269 |
270 | svg.appendChild(self.getText(
271 | {
272 | x: sx2 - 5,
273 | y: y + blocHeight * 0.9,
274 | text: self.value,
275 | options: {
276 | 'fill': '#000000',
277 | 'fontSize': blocHeight * 0.9,
278 | 'fontWeight': 'bold',
279 | 'fontFamily': "'Arial Narrow', sans-serif",
280 | 'textAnchor': 'end'
281 | }
282 | }
283 | ));
284 | }
285 |
286 | svg.appendChild(self.getPolygon(poly, self.colors[i]));
287 |
288 | var whiteIdx = (self.shape === "sharp") ? 5 : 3;
289 |
290 | svg.appendChild(self.getText(
291 | {
292 | x: x1 - self.pad,
293 | y: y + (blocHeight * 0.8),
294 | text: self.labels[i],
295 | options: {
296 | fill: i > whiteIdx ? '#ffffff' : '#000000',
297 | fontSize: blocHeight * 0.8,
298 | fontWeight: 'bold',
299 | fontFamily: "'Arial Narrow', sans-serif",
300 | textAnchor: 'end'
301 | }
302 | }));
303 | svg.appendChild(self.getText(
304 | {
305 | x: x + self.pad,
306 | y: y + blocHeight - ((blocHeight * 0.6) / 2),
307 | text: self.values[i],
308 | options: {
309 | fill: i > whiteIdx ? '#ffffff' : '#000000',
310 | fontSize: blocHeight * 0.6,
311 | fontFamily: "'Arial Narrow', sans-serif",
312 | textAnchor: 'start'
313 | }
314 | }));
315 | }
316 |
317 | self.container.appendChild(svg);
318 | };
319 |
320 | self.createSVG();
321 | };
322 |
323 | function DPE(options) {
324 |
325 | options.valuesRange = [
326 | { min: null, max: 50, color: '#319834', textColor: '#000000', label: 'A' },
327 | { min: 51, max: 90, color: '#33cc31', textColor: '#000000', label: 'B' },
328 | { min: 91, max: 150, color: '#cbfc34', textColor: '#000000', label: 'C' },
329 | { min: 151, max: 230, color: '#fbfe06', textColor: '#000000', label: 'D' },
330 | { min: 231, max: 330, color: '#fbcc05', textColor: '#000000', label: 'E' },
331 | { min: 331, max: 450, color: '#fc9935', textColor: '#000000', label: 'F' },
332 | { min: 451, max: null, color: '#fc0205', textColor: '#ffffff', label: 'G' }
333 | ];
334 |
335 | options.shape = "sharp";
336 |
337 | return new Diag(options);
338 | };
339 |
340 | function GES(options) {
341 |
342 | options.valuesRange = [
343 | { min: null, max: 5, color: '#f2eff4', textColor: '#000000', label: 'A' },
344 | { min: 6, max: 10, color: '#dfc1f7', textColor: '#000000', label: 'B' },
345 | { min: 11, max: 20, color: '#d6aaf4', textColor: '#000000', label: 'C' },
346 | { min: 21, max: 35, color: '#cc93f4', textColor: '#000000', label: 'D' },
347 | { min: 36, max: 55, color: '#bb72f3', textColor: '#ffffff', label: 'E' },
348 | { min: 56, max: 80, color: '#a94cee', textColor: '#ffffff', label: 'F' },
349 | { min: 81, max: null, color: '#8b1ae1', textColor: '#ffffff', label: 'G' }
350 | ];
351 |
352 | options.shape = "flat";
353 |
354 | return new Diag(options);
355 | };
356 |
357 | return {
358 | dpe: DPE,
359 | ges: GES
360 | };
361 |
362 | };
363 |
--------------------------------------------------------------------------------