Blame view

app/main/static/js/charges.js 20.1 KB
5e6f4e07   hitier   Set Rokotyan Solu...
1
/* Round float to two decimals only */
966f9b78   hitier   Js Round float be...
2
function roundToTwo(num) {
bf0e0b24   hitier   Fix empty charges...
3
    return +(Math.round(num + "e+2") + "e-2");
966f9b78   hitier   Js Round float be...
4
5
}

90c7b0e4   hitier   Small comments an...
6
7
function build_chart(div_selector, data_url, entity_name, category_type) {

5f89fdc7   hitier   Fix color scale: ...
8
    const main_elt = document.getElementById("main")
7c1b38be   hitier   Draw charts to fi...
9

dffcf5b7   hitier   Update legend col...
10
    var margin = {top: 60, right: 100, bottom: 200, left: 90},
5f89fdc7   hitier   Fix color scale: ...
11
        width = main_elt.offsetWidth * 0.95 - margin.left - margin.right,
13c144c8   Anais Amato   Add horizontal le...
12
        height = 600 - margin.top - margin.bottom;
54e2baa6   hitier   Add charge charts...
13

90c7b0e4   hitier   Small comments an...
14
    const height_ratio = 1.2;    // how murch room to give above chart for lisibility
ff5fd5bf   hitier   Less and Longer ...
15

5f89fdc7   hitier   Fix color scale: ...
16
17
    const tooltip_offset = {dx: 0, dy: 100}
    const tooltip_offset_dot = {dx: 20, dy: 60}
f9fef9d0   hitier   Add tooltip
18

90c7b0e4   hitier   Small comments an...
19
    const y_ticks_num = 5        // dont show to many y ticks for lisibility
f0706d95   hitier   Add color legend
20

8ede71fd   hitier   Truncate legend k...
21
    const legend_rect_size = 15; // size of rectangle in legend
1cb6e878   hitier   New draw_projects...
22
    const legend_height = 20;
dffcf5b7   hitier   Update legend col...
23
    const legend_max_length = 20;
8ede71fd   hitier   Truncate legend k...
24
    const legend_spacing = 5;
54e2baa6   hitier   Add charge charts...
25

90c7b0e4   hitier   Small comments an...
26
    const dot_radius = 6;        // size of total line dot
f9c1f568   hitier   Add dot on total ...
27

54e2baa6   hitier   Add charge charts...
28

90c7b0e4   hitier   Small comments an...
29
    var colorScale = d3.scaleOrdinal([]); //  Will be really set later by category type
de63cb72   hitier   Add title to proj...
30

90c7b0e4   hitier   Small comments an...
31
32
33
    //
    // Configure chart by the category given as arg
    //
83d933c9   hitier   New draw_categori...
34
35
    var chart_title = ""
    var category_title = ""
1cb6e878   hitier   New draw_projects...
36
    var draw_areas = () => void 0;
90c7b0e4   hitier   Small comments an...
37
38
    var draw_total_line = () => void 0;
    var draw_categories_bars = () => void 0;
7d095c38   hitier   One color scale b...
39

2a36f990   hitier   Remove tooltip ho...
40
41
42
43
    var mouseoverlegend = category_mouseoverlegend;
    var mouseleavelegend = category_mouseleavelegend;


90c7b0e4   hitier   Small comments an...
44
    if (category_type == 'capacity') {
83d933c9   hitier   New draw_categori...
45
46
47
48
        chart_title = "Charges par fonction"
        category_title = "Fonction"
        //draw_total_line
        draw_categories_bars = draw_categories_grouped
7d095c38   hitier   One color scale b...
49
        colorScale = d3.scaleOrdinal(d3.schemeSet3);
90c7b0e4   hitier   Small comments an...
50
    } else if (category_type == 'service') {
83d933c9   hitier   New draw_categori...
51
52
53
54
        chart_title = "Charges par service"
        category_title = "Service"
        draw_total_line = draw_totalcharge_line
        draw_categories_bars = draw_categories_stacked
7d095c38   hitier   One color scale b...
55
        colorScale = d3.scaleOrdinal(d3.schemeTableau10);
90c7b0e4   hitier   Small comments an...
56
    } else if (category_type == 'project') {
c8b7caf5   hitier   Agent now uses co...
57
58
59
60
        chart_title = "Charges par projet"
        category_title = "Projet"
        draw_categories_bars = draw_categories_stacked
        colorScale = d3.scaleOrdinal(d3.schemeTableau10);
1cb6e878   hitier   New draw_projects...
61
    } else if (category_type == 'area') {
dffcf5b7   hitier   Update legend col...
62
        margin.bottom = 400
1cb6e878   hitier   New draw_projects...
63
64
65
66
67
        height = 1200 - margin.top - margin.bottom;
        chart_title = "Tous agents confondus"
        category_title = "Projet"
        draw_areas = draw_projects_areas
        colorScale = d3.scaleOrdinal(d3.schemeTableau10);
2a36f990   hitier   Remove tooltip ho...
68
69
        mouseoverlegend = () => void 0;
        mouseleavelegend = () => void 0;
6b44860d   hitier   Make a draw_line ...
70
71
    } else {
        alert("ALERT ! Every body shall quit the boat, we are sinking ! ALERT !")
de63cb72   hitier   Add title to proj...
72
    }
54e2baa6   hitier   Add charge charts...
73

1cb6e878   hitier   New draw_projects...
74
75
76
77
78
79
80
81
82

    const xScale = d3.scaleBand()
        .range([0, width])
        .padding(0.4);

    const yScale = d3.scaleLinear()
        .range([height, 0]);


a30b11ff   Anais Amato   Add an 'export me...
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
    // Configure the tooltip to export svg to png or csv
    var update_export_menu = function (e, d) {

        const tooltip_test = document.getElementsByClassName('tooltip_hamburger');

        if (tooltip_test.length == 0) {
            d3.select(".tooltip_hamburger").remove();

            const tooltip_hamburger = hamburger.append("div")
                .style("opacity", 0)
                .attr("class", "tooltip tooltip_hamburger");

            d3.select(this).transition()
                .duration(1)
            tooltip_hamburger
                .transition()
                .duration(200)
                .style("opacity", 1)
            tooltip_hamburger
                .html("<span>Export </span>" +
7d42e277   hitier   Download chart csv
103
                    "<li id='to_csv'>To CSV</li>" +
a30b11ff   Anais Amato   Add an 'export me...
104
105
                    "<li id='to_png'>To PNG</li>")
            d3.select("#to_png").on("click", download_png);
bf0e0b24   hitier   Fix empty charges...
106
107
108
            d3.select("#to_csv").on("click", function () {
                download_csv(this, data_url);
            })
a30b11ff   Anais Amato   Add an 'export me...
109
110
111
112
113
        } else {
            d3.select(".tooltip_hamburger").remove();
        }

    }
cfc5bded   hitier   More chart classe...
114
    // Create a download button inside the div contaning svg chart
a30b11ff   Anais Amato   Add an 'export me...
115
116
117
118
    const hamburger = d3.select(div_selector).append('i')
        .attr('class', 'fas fa-bars fa-lg export')
        .on("click", update_export_menu);

5ac5d2b6   Anais Amato   Resize d3 js grap...
119
120
    const real_width = width + margin.left + margin.right;
    const real_height = height + margin.top + margin.bottom;
cfc5bded   hitier   More chart classe...
121

54e2baa6   hitier   Add charge charts...
122
    const svg = d3.select(div_selector).append("svg")
5ac5d2b6   Anais Amato   Resize d3 js grap...
123
        .attr("viewBox", [0, 0, real_width, real_height])
cfc5bded   hitier   More chart classe...
124
        .attr("class", "svg_chart")
5ac5d2b6   Anais Amato   Resize d3 js grap...
125
126
        .attr("width", real_width)
        .attr("height", real_height)
54e2baa6   hitier   Add charge charts...
127
128
129
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

069a5102   hitier   Fixed tooltip
130
    const tooltip = d3.select('html')
f9fef9d0   hitier   Add tooltip
131
132
133
134
135
136
137
138
139
140
141
142
143
        .append("div")
        .style("opacity", 0)
        .attr("class", "tooltip")

    var mousemove = function (e, d) {
        tooltip
            .style("left", (e.pageX - tooltip_offset.dx) + "px")
            .style("top", (e.pageY - tooltip_offset.dy) + "px")
    }

    var mouseleave = function (d) {
        tooltip
            .transition()
67ab2300   hitier   Fix appearance de...
144
            .duration(900)
f9fef9d0   hitier   Add tooltip
145
146
147
148
149
150
            .style("opacity", 0)
    }

    var mouseover = function (e, d) {
        var category_name = d3.select(this.parentNode).datum().key
        var category_charge = d.data[category_name]
22397f43   hitier   Show tooltip on g...
151
        show_tooltip(e, category_name, category_charge)
2a36f990   hitier   Remove tooltip ho...
152
        console.log("HELLO")
22397f43   hitier   Show tooltip on g...
153
154
155
156
157
158
159
160
    }

    var mouseovergrouped = function (e, d) {
        var category_name = d.key
        var category_charge = d.value
        show_tooltip(e, category_name, category_charge)
    }
    var show_tooltip = function (e, category_name, category_charge) {
f9fef9d0   hitier   Add tooltip
161
162
163
164
165
        tooltip
            .transition()
            .duration(200)
            .style("opacity", 1);
        tooltip
582e1ee2   hitier   Change charts leg...
166
            .html("<b>" + category_title + ":</b> " + category_name + "<br>" + "<b>Charge:</b> " + category_charge + " ETP")
f9fef9d0   hitier   Add tooltip
167
168
169
170
            .style("left", (e.pageX - tooltip_offset.dx) + "px")
            .style("top", (e.pageY - tooltip_offset.dy) + "px")
    }

f9c1f568   hitier   Add dot on total ...
171
172
173
174
175
176
    var mouseleavedot = function (e, d) {
        d3.select(this).transition()
            .duration(1)
            .attr("r", dot_radius);
        mouseleave(d);
    }
6b44860d   hitier   Make a draw_line ...
177

f9c1f568   hitier   Add dot on total ...
178
179
180
181
182
183
184
185
186
    var mouseoverdot = function (e, d) {
        d3.select(this).transition()
            .duration(1)
            .attr("r", dot_radius * 1.5);
        tooltip
            .transition()
            .duration(200)
            .style("opacity", 1)
        tooltip
582e1ee2   hitier   Change charts leg...
187
            .html("<b>" + d.period + ": </b>" + d.total + " ETP")
f9c1f568   hitier   Add dot on total ...
188
189
190
191
            .style("left", (e.pageX - tooltip_offset_dot.dx) + "px")
            .style("top", (e.pageY - tooltip_offset_dot.dy) + "px")
    }

2a36f990   hitier   Remove tooltip ho...
192
    function category_mouseoverlegend() {
8afeed29   Anais Amato   Add hover effect ...
193
194
195
196
197
        var legend_category = $(this).attr("class");
        var bar_category = document.getElementsByClassName(legend_category);
        if (bar_category[0].tagName === "g") {
            var rect_to_hover = bar_category[0].children;
            (bar_category[1].children[0]).classList.add("brillance");
2a36f990   hitier   Remove tooltip ho...
198
            for (var i = 0; i < rect_to_hover.length; i++) {
8afeed29   Anais Amato   Add hover effect ...
199
200
201
                rect_to_hover[i].classList.add("brillance");
            }
        } else {
2a36f990   hitier   Remove tooltip ho...
202
            for (var i = 0; i < bar_category.length; i++) {
8afeed29   Anais Amato   Add hover effect ...
203
204
205
206
207
                bar_category[i].classList.add("brillance");
            }
        }
    }

2a36f990   hitier   Remove tooltip ho...
208
    function category_mouseleavelegend() {
8afeed29   Anais Amato   Add hover effect ...
209
210
211
212
213
        var legend_category = $(this).attr("class");
        var bar_category = document.getElementsByClassName(legend_category);
        if (bar_category[0].tagName === "g") {
            var rect_to_hover = bar_category[0].children;
            (bar_category[1].children[0]).classList.remove("brillance");
2a36f990   hitier   Remove tooltip ho...
214
            for (var i = 0; i < rect_to_hover.length; i++) {
8afeed29   Anais Amato   Add hover effect ...
215
216
217
218
                rect_to_hover[i].classList.remove("brillance");
            }
        } else {
            var lenght_i = bar_category.length - 1;
2a36f990   hitier   Remove tooltip ho...
219
            for (var i = lenght_i; i >= 0; i--) {
8afeed29   Anais Amato   Add hover effect ...
220
221
222
223
224
                bar_category[i].classList.remove("brillance");
            }
        }
    }

f0706d95   hitier   Add color legend
225
226
    var addlegend = function (color_scale) {

13c144c8   Anais Amato   Add horizontal le...
227
        // add horizontal legend
48613832   hitier   Fix legend keys o...
228
        let legend_keys = color_scale.domain();
8ede71fd   hitier   Truncate legend k...
229
230
231
232
233
234
235

        // Truncate legend keys when too long
        legend_keys = legend_keys.map(function (l) {
            const n = legend_max_length;
            return (l.length > n) ? l.substr(0, n - 1) : l;
        });

f0706d95   hitier   Add color legend
236

13c144c8   Anais Amato   Add horizontal le...
237
238
239
        var legendWrap = svg.append('g')
            .attr('width', '100%')
            .attr('class', 'legendwrap');
f0706d95   hitier   Add color legend
240

13c144c8   Anais Amato   Add horizontal le...
241
        var legend = svg.select('.legendwrap').selectAll('.legend')
48613832   hitier   Fix legend keys o...
242
            .data(legend_keys)
13c144c8   Anais Amato   Add horizontal le...
243
244
            .enter()
            .append('g')
2a36f990   hitier   Remove tooltip ho...
245
            .attr('class', d => d)
8afeed29   Anais Amato   Add hover effect ...
246
247
            .on("mouseover", mouseoverlegend)
            .on("mouseleave", mouseleavelegend);
f0706d95   hitier   Add color legend
248

13c144c8   Anais Amato   Add horizontal le...
249
        legend.append('rect')
8ede71fd   hitier   Truncate legend k...
250
251
            .attr('width', legend_rect_size)
            .attr('height', legend_rect_size)
13c144c8   Anais Amato   Add horizontal le...
252
            .style('fill', color_scale)
cfc5bded   hitier   More chart classe...
253
            .attr('class', 'legend');
13c144c8   Anais Amato   Add horizontal le...
254
255

        legend.append('text')
f0706d95   hitier   Add color legend
256
            .attr('class', 'legend')
8ede71fd   hitier   Truncate legend k...
257
            .attr('x', legend_rect_size + legend_spacing * 1.5)
13c144c8   Anais Amato   Add horizontal le...
258
            .attr('y', 13)
8ede71fd   hitier   Truncate legend k...
259
            .text(d => d);
13c144c8   Anais Amato   Add horizontal le...
260
261
262
263
264
265

        var ypos = 0,
            newxpos = 0,
            maxwidth = 0,
            xpos;

dffcf5b7   hitier   Update legend col...
266
        // Get Max legend key length for later display
2a36f990   hitier   Remove tooltip ho...
267
268
        const text_length_list = legend.selectAll('text.legend')._groups.map(el => el[0].getComputedTextLength())
        const keycol_length = Math.max(...text_length_list) + 40
dffcf5b7   hitier   Update legend col...
269

13c144c8   Anais Amato   Add horizontal le...
270
        legend
bf0e0b24   hitier   Fix empty charges...
271
            .attr("transform", function (d, i) {
13c144c8   Anais Amato   Add horizontal le...
272
                xpos = newxpos;
dffcf5b7   hitier   Update legend col...
273
                if (width < xpos + keycol_length) {
13c144c8   Anais Amato   Add horizontal le...
274
                    newxpos = xpos = 0;
1cb6e878   hitier   New draw_projects...
275
276
                    ypos += legend_height;

13c144c8   Anais Amato   Add horizontal le...
277
                }
dffcf5b7   hitier   Update legend col...
278
                newxpos += keycol_length;
13c144c8   Anais Amato   Add horizontal le...
279
280
281
282
283
284
285
286
                if (newxpos > maxwidth) maxwidth = newxpos;

                return 'translate(' + xpos + ',' + ypos + ')';

            });


        legendWrap
bf0e0b24   hitier   Fix empty charges...
287
            .attr("transform", function (d, i) {
13c144c8   Anais Amato   Add horizontal le...
288
289
                return "translate(0 ," + (height + 100) + ")";
            });
f0706d95   hitier   Add color legend
290
291
    }

83d933c9   hitier   New draw_categori...
292
293
    function draw_categories_grouped(data, categories) {

22cc6fe8   hitier   Extract common co...
294
        // TODO: use ymax_from_stacked
bf0e0b24   hitier   Fix empty charges...
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
        // Get the max y to plot
        // If no data at all, force to 0
        if (categories.length == 0) {
            y_max = 0
        } else {
            var y_max = d3.max(data, function (d) {
                return d3.max(categories, function (c) {
                    return +d[c]
                })
            });
        }
        // Force maximum in any cases
        if (y_max == 0) {
            y_max = 100
        }
a07df204   hitier   Compute for group...
310
311
        y_max = y_max * height_ratio
        yScale.domain([0, y_max])
83d933c9   hitier   New draw_categori...
312
313
314
315
        // Another scale for subgroup position
        var xCategories = d3.scaleBand()
            .domain(categories)
            .range([0, xScale.bandwidth()])
67ab2300   hitier   Fix appearance de...
316
            .padding([0.2])
83d933c9   hitier   New draw_categori...
317
318
319
320
321
322
323

        svg.append("g")
            .selectAll("g")
            // Enter in data = loop group per group
            .data(data)
            .enter()
            .append("g")
a5294567   hitier   Rewrite anonymous...
324
            .attr("transform", d => "translate(" + xScale(d.period) + ",0)")
83d933c9   hitier   New draw_categori...
325
326
327
328
329
330
331
            .selectAll("rect")
            .data(function (d) {
                return categories.map(function (key) {
                    return {key: key, value: d[key]};
                });
            })
            .enter().append("rect")
a5294567   hitier   Rewrite anonymous...
332
            .attr("x", d => xCategories(d.key))
83d933c9   hitier   New draw_categori...
333
            .attr("width", xCategories.bandwidth())
1cb6e878   hitier   New draw_projects...
334
335
336
337
338
339
340
341
342
343
            /* Transition part */
            .attr("y", d => {
                return height;
            })
            .attr("height", 0)
            .transition()
            .duration(750)
            .delay(function (d, i) {
                return i * 150;
            })
8dad7ce7   Anais Amato   Add animations to...
344
            .attr("y", d => yScale(d.value))
a5294567   hitier   Rewrite anonymous...
345
            .attr("height", d => height - yScale(d.value))
22397f43   hitier   Show tooltip on g...
346
            .attr("fill", d => colorScale(d.key))
8afeed29   Anais Amato   Add hover effect ...
347
            .attr("class", d => d.key);
8dad7ce7   Anais Amato   Add animations to...
348
349

        svg.selectAll("rect")
22397f43   hitier   Show tooltip on g...
350
351
352
            .on("mouseover", mouseovergrouped)
            .on("mousemove", mousemove)
            .on("mouseleave", mouseleave);
83d933c9   hitier   New draw_categori...
353

8dad7ce7   Anais Amato   Add animations to...
354

a48677c4   hitier   Make a draw_categ...
355
356
    }

2a36f990   hitier   Remove tooltip ho...
357
    function ymax_from_stacked(stacked_data) {
22cc6fe8   hitier   Extract common co...
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375

        // Get the max y to plot
        // If no data at all, force to 0
        if (stacked_data.length == 0) {
            y_max = 0
        } else {
            var y_max = d3.max(stacked_data[stacked_data.length - 1], d => d[1]);
        }
        // Force maximum in any cases
        if (y_max == 0) {
            y_max = 100
        }
        // Enhance it by %ratio to leave room on the top of the graph
        y_max = y_max * height_ratio

        return y_max
    }

1cb6e878   hitier   New draw_projects...
376
377
378
379
380
381
382
383
384
385
    function draw_projects_areas(data, projects) {

        // Now build the stacked data for stacked bars
        //
        var stack = d3.stack()
            .keys(projects)
        // .order(d3.stackOrderNone)
        // .offset(d3.stackOffsetNone);
        var stacked_data = stack(data)

22cc6fe8   hitier   Extract common co...
386
        const y_max = ymax_from_stacked(stacked_data);
2a36f990   hitier   Remove tooltip ho...
387
        yScale.domain([0, y_max]);
1cb6e878   hitier   New draw_projects...
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404

        const area = d3.area()
            .x(d => xScale(d.data.period))
            .y0(d => yScale(d[0]))
            .y1(d => yScale(d[1]))

        let paths = svg.append("g")
            .selectAll("path")
            .data(stacked_data)
            .join("path")
            .attr("fill", ({key}) => colorScale(key))
            .attr("stroke", 'black')
            .attr("stroke-width", '0.2pt')
            .attr("d", area)
            .append("title")
            .text(({key}) => key);

1cb6e878   hitier   New draw_projects...
405
406
407
    }


83d933c9   hitier   New draw_categori...
408
409
410
411
412
413
414
415
416
417
    function draw_categories_stacked(data, categories) {

        // Now build the stacked data for stacked bars
        //
        var stack = d3.stack()
            .keys(categories)
        // .order(d3.stackOrderNone)
        // .offset(d3.stackOffsetNone);
        var stacked_data = stack(data)

22cc6fe8   hitier   Extract common co...
418
        const y_max = ymax_from_stacked(stacked_data);
2a36f990   hitier   Remove tooltip ho...
419
        yScale.domain([0, y_max]);
83d933c9   hitier   New draw_categori...
420

90c7b0e4   hitier   Small comments an...
421
        // first draw one group for one category containing all bars over periods
a48677c4   hitier   Make a draw_categ...
422
423
424
425
        let groups = svg.selectAll("g.category")
            .data(stacked_data)
            .enter()
            .append("g")
8afeed29   Anais Amato   Add hover effect ...
426
            .attr("class", d => d.key)
83d933c9   hitier   New draw_categori...
427
            .style("fill", (d) => colorScale(d.key));
a48677c4   hitier   Make a draw_categ...
428

90c7b0e4   hitier   Small comments an...
429
        // then draw each period/category bar
a48677c4   hitier   Make a draw_categ...
430
431
432
433
434
435
436
        let rect = groups.selectAll("rect")
            .data(d => d)
            .enter()
            .append("rect")
            .attr("class", "bar")
            .attr("x", d => xScale(d.data.period))
            .attr("width", xScale.bandwidth())
1cb6e878   hitier   New draw_projects...
437
438
439
440
441
442
443
444
445
446
            /* transition part */
            .attr("y", d => {
                return height;
            })
            .attr("height", 0)
            .transition()
            .duration(750)
            .delay(function (d, i) {
                return i * 150;
            })
a48677c4   hitier   Make a draw_categ...
447
448
            .attr("y", d => yScale(d[1]))
            .attr("height", d => height - yScale(d[1] - d[0]))
8dad7ce7   Anais Amato   Add animations to...
449
450

        groups.selectAll("rect")
a48677c4   hitier   Make a draw_categ...
451
452
453
454
455
456
            .on("mouseover", mouseover)
            .on("mousemove", mousemove)
            .on("mouseleave", mouseleave);

    }

6b44860d   hitier   Make a draw_line ...
457
458
    function draw_totalcharge_line(data) {
        // Build the total charge by period;
518c7cc5   hitier   Draw the total ca...
459
460
        // it will be used for the line drawing above bars.
        //
6b44860d   hitier   Make a draw_line ...
461
462
        var periods_total_charge = []

518c7cc5   hitier   Draw the total ca...
463
464
465
466
467
        data.forEach(function (d) {
            // get the list of values for all columns except the first one which is the period name
            var period_values = Object.values(d).slice(1)
            var row = {}
            row['period'] = d.period
966f9b78   hitier   Js Round float be...
468
            row['total'] = roundToTwo(d3.sum(period_values))
518c7cc5   hitier   Draw the total ca...
469
470
471
            periods_total_charge.push(row)
        });

6b44860d   hitier   Make a draw_line ...
472
473
474
475
476
477
478
479
480
481
        // the line itselet
        //
        const line = d3.line()
            .x(d => (xScale.bandwidth() / 2) + xScale(d.period)) // décalage pour centrer au milieu des barres
            .y(d => yScale(d.total))
            .curve(d3.curveMonotoneX); // Fonction de courbe permettant de l'adoucir

        svg.append("path")
            .datum(periods_total_charge)
            .attr("class", "total-line")
83d933c9   hitier   New draw_categori...
482
483
            .attr("d", line)
            .lower();// set it below bars if called after
6b44860d   hitier   Make a draw_line ...
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498

        // data dots at each point
        //
        svg.selectAll("line-circle")
            .data(periods_total_charge)
            .enter().append("circle")
            .attr("class", "total-circle")
            .attr("r", dot_radius)
            .attr("cx", function (d) {
                return (xScale.bandwidth() / 2) + xScale(d.period)
            })
            .attr("cy", function (d) {
                return yScale(d.total);
            })
            .on("mouseover", mouseoverdot)
83d933c9   hitier   New draw_categori...
499
500
            .on("mouseleave", mouseleavedot)
            .lower();// set it below bars if called after
6b44860d   hitier   Make a draw_line ...
501
502
503
504

    }

    d3.csv(data_url).then(data => {
a07df204   hitier   Compute for group...
505
        // we could get categories that way,
6b44860d   hitier   Make a draw_line ...
506
        // var categories = data.columns.slice(1)
1cb6e878   hitier   New draw_projects...
507
        // but instead we want to filter by non zero, see later
90c7b0e4   hitier   Small comments an...
508

6b44860d   hitier   Make a draw_line ...
509
510
511
        var periods = d3.map(data, d => d.period)
        xScale.domain(periods)

90c7b0e4   hitier   Small comments an...
512
513
        // Filter datas to only keep non zero categories
        // TODO: should be done on server (python/flask) side
518c7cc5   hitier   Draw the total ca...
514
        //
90c7b0e4   hitier   Small comments an...
515
        // 1- Get the charge sum for each category over periods
f0706d95   hitier   Add color legend
516
        // That will leave '0' to categories with no charge at all
a07df204   hitier   Compute for group...
517
        // TODO: to be done with Object.keys, Object.values and d3 filtering methods
ce5f45ea   hitier   Fix data bug
518
        //
6b44860d   hitier   Make a draw_line ...
519
        var categories_total_charge = {}
f0706d95   hitier   Add color legend
520
521
        data.forEach(function (d) {
            Object.keys(d).forEach(function (k) {
04f2b6e8   hitier   Fix period as cat...
522
523
524
                    if (k === 'period') {
                        return;
                    }
f0706d95   hitier   Add color legend
525
526
527
                    if (categories_total_charge.hasOwnProperty(k)) {
                        categories_total_charge[k] += +d[k]
                    } else {
582e1ee2   hitier   Change charts leg...
528
                        categories_total_charge[k] = +d[k]
f0706d95   hitier   Add color legend
529
                    }
966f9b78   hitier   Js Round float be...
530
                    categories_total_charge[k] = roundToTwo(categories_total_charge[k])
f0706d95   hitier   Add color legend
531
532
533
534
                }
            )
        })

518c7cc5   hitier   Draw the total ca...
535
        // 2- Now, filter only categories that have a non-zero charge
a07df204   hitier   Compute for group...
536
        // TODO: to be done with Object.keys, Object.values and d3 filtering methods
90c7b0e4   hitier   Small comments an...
537
        //
f0706d95   hitier   Add color legend
538
539
540
541
542
543
544
        var categories = []
        for (var key in categories_total_charge) {
            if (categories_total_charge[key] > 0) {
                categories.push(key)
            }
        }

518c7cc5   hitier   Draw the total ca...
545
        //
1cb6e878   hitier   New draw_projects...
546
547
548
549
550
        // Draw the  areas, stacked.
        //
        draw_areas(data, categories)

        //
90c7b0e4   hitier   Small comments an...
551
        // Draw the  bars, stacked or grouped
83d933c9   hitier   New draw_categori...
552
553
        //
        draw_categories_bars(data, categories)
54e2baa6   hitier   Add charge charts...
554

518c7cc5   hitier   Draw the total ca...
555
        //
83d933c9   hitier   New draw_categori...
556
557
558
559
560
561
562
563
564
565
        //  Draw the total charge line ( may be)
        //
        draw_total_line(data, categories)

        //
        // This former list we use as color_scale domain.
        // And that allows us to build the legend
        //
        colorScale.domain(categories)
        addlegend(colorScale)
54e2baa6   hitier   Add charge charts...
566

f0706d95   hitier   Add color legend
567
568
        // Xaxis
        //
518c7cc5   hitier   Draw the total ca...
569
        const xAxis = d3.axisBottom(xScale)
f0706d95   hitier   Add color legend
570

f0706d95   hitier   Add color legend
571
        // Draw Xaxis
68fd83a8   hitier   Add axis
572
        svg.append("g")
cfc5bded   hitier   More chart classe...
573
            .attr("class", "x_axis")
68fd83a8   hitier   Add axis
574
575
576
577
578
579
580
581
            .attr("transform", "translate(0," + height + ")")
            .call(xAxis)
            .selectAll("text")
            .style("text-anchor", "end")
            .attr("dx", "-.9em")
            .attr("dy", ".15em")
            .attr("transform", "rotate(-65)");

90c7b0e4   hitier   Small comments an...
582
583
584
585
586
        // Yaxis
        //
        const yAxis = d3.axisLeft(yScale)
            .ticks(y_ticks_num)

f0706d95   hitier   Add color legend
587
        // Draw Yaxis
68fd83a8   hitier   Add axis
588
        svg.append("g")
cfc5bded   hitier   More chart classe...
589
            .attr("class", "y_axis")
68fd83a8   hitier   Add axis
590
            .call(yAxis)
68fd83a8   hitier   Add axis
591

ff5fd5bf   hitier   Less and Longer ...
592
593
594
595
596
597
598
599
600
601
        // Draw horizontal lines
        svg.selectAll("y axis")
            .data(yScale.ticks(y_ticks_num))
            .enter()
            .append("line")
            .attr("class", d => (d == 0 ? "horizontalY0" : "horizontalY"))
            .attr("x1", 0)
            .attr("x2", width)
            .attr("y1", d => yScale(d))
            .attr("y2", d => yScale(d))
83d933c9   hitier   New draw_categori...
602
            .lower();// set it below bars if called after
ff5fd5bf   hitier   Less and Longer ...
603

f0706d95   hitier   Add color legend
604
        // Write Y axis title
68fd83a8   hitier   Add axis
605
606
607
608
609
        svg.append("text")
            .attr("text-anchor", "end")
            .attr("transform", "rotate(-90)")
            .attr("y", -margin.left + 40)
            .attr("x", -margin.top - 70)
582e1ee2   hitier   Change charts leg...
610
            .text("Charge en ETP");
54e2baa6   hitier   Add charge charts...
611

6b44860d   hitier   Make a draw_line ...
612
        //
f0706d95   hitier   Add color legend
613
        // Write chart Title
6b44860d   hitier   Make a draw_line ...
614
615
        //

f0706d95   hitier   Add color legend
616
        // part 1
de63cb72   hitier   Add title to proj...
617
        svg.append("text")
3c21ae9f   hitier   Change bar colors
618
619
620
621
            .attr("x", (width / 2))
            .attr("y", 0 - (margin.top / 2) - 10)
            .attr("text-anchor", "middle")
            .style("font-size", "16px")
c8b7caf5   hitier   Agent now uses co...
622
            .text(entity_name);
f0706d95   hitier   Add color legend
623
        // part 2
de63cb72   hitier   Add title to proj...
624
        svg.append("text")
3c21ae9f   hitier   Change bar colors
625
626
627
628
629
            .attr("x", (width / 2))
            .attr("y", 0 - (margin.top / 2) + 10)
            .attr("text-anchor", "middle")
            .style("font-size", "12px")
            .text(chart_title);
54e2baa6   hitier   Add charge charts...
630

518c7cc5   hitier   Draw the total ca...
631

6b44860d   hitier   Make a draw_line ...
632
    }); // end of d3.csv().then({})
54e2baa6   hitier   Add charge charts...
633
634

}