Commit 2f1df81b authored by Clement Brizard's avatar Clement Brizard

Merge branch '11-affichage-des-resultats' into 'master'

Afficher les graphes

See merge request tx-techno-num/impactometre!58
parents 4c00cc82 ed900d86
'use strict'
const express = require('express')
const resultsRouter = require('./results')
const router = express.Router()
router.get('/results', function (req, res, next) {
res.render('meeting/results', { title: 'Réunions' })
router.get('/', function (req, res, next) {
res.redirect('/reunion/resultats')
})
router.use('/resultats', resultsRouter)
module.exports = router
'use strict'
const express = require('express')
const hardwareDatabase = require('../../../database/meeting/hardware')
const softwareDatabase = require('../../../database/meeting/software')
const transportDatabase = require('../../../database/meeting/transportationMean')
const meetingScenarios = require('../../../database/meeting/meetingScenarios')
const MeetingScenario = require('../../../model/classes/meeting/MeetingScenario')
const { meetingCategoryDamage, bounds } = require('../../../constants/meeting')
const { normaliseDamages } = require('../../../utils/normalise')
const router = express.Router()
router.get('/', function (req, res, next) {
// The user who creates the meeting
const user = 'vlegauch'
// The meeting duration in minutes
const meetingDuration = 120
// Number of participants
const numberOfParticipants = 4
// The JSON object that enables to creates components linked to the meeting
const payload = {
[meetingCategoryDamage.HARDWARE]: [
{ name: hardwareDatabase.DESKTOP.name },
{ name: hardwareDatabase.DESKTOP.name },
{ name: hardwareDatabase.DESKTOP.name },
{ name: hardwareDatabase.LAPTOP.name },
{ name: hardwareDatabase.LOGITECH_KIT.name },
{ name: hardwareDatabase.TV.name },
{ name: hardwareDatabase.TV.name },
{ name: hardwareDatabase.METAL_STRUCTURE.name }
],
[meetingCategoryDamage.SOFTWARE]: [{ name: softwareDatabase.SKYPE.name }],
[meetingCategoryDamage.JOURNEY]: [
{
passenger: 'Passenger 1',
mean: transportDatabase.CAR_ELECTRIC_ONE_KM.name,
distance: 120,
numberOfPeople: 4
},
{
passenger: 'Passenger 1',
mean: transportDatabase.BUS_LARGE_DISTANCE_ONE_PERSON_KM.name,
distance: 40,
numberOfPeople: 1
},
{
passenger: 'Passenger 2',
mean: transportDatabase.CAR_ELECTRIC_ONE_KM.name,
distance: 120,
numberOfPeople: 4
},
{
passenger: 'Passenger 2',
mean: transportDatabase.TRAIN_REGIONAL_ONE_PERSON_KM.name,
distance: 300,
numberOfPeople: 1
},
{
passenger: 'Passenger 2',
mean: transportDatabase.BIKE_ONE_PERSON_ONE_KM.name,
distance: 10,
numberOfPeople: 1
}
]
}
meetingScenarios.clear()
// Create the MeetingScenario object
const meetingScenario = MeetingScenario.create({ user, meetingDuration, numberOfParticipants, payload })
const damageComputePayload = {
[meetingCategoryDamage.HARDWARE]: { meetingDuration: 120, bound: bounds.UPPER },
[meetingCategoryDamage.SOFTWARE]: { instancesNumber: 5, bandwithBound: bounds.UPPER, networkBound: bounds.UPPER, meetingDuration: 120 },
[meetingCategoryDamage.JOURNEY]: {}
}
meetingScenario.computeDamage(damageComputePayload)
meetingScenario.generateAlternatives()
const scenarios = []
meetingScenarios.forEach(scenario => {
if (scenario.user === user) {
scenarios.push(scenario)
}
})
const normalisedDamages = normaliseDamages(scenarios)
res.render('meeting/results/results', { title: 'Résultats', scenarios, normalisedDamages })
})
module.exports = router
function switchVue() {
if (document.getElementById('monoDiv').hidden === false) {
let ctx = document.getElementById('humanHealth').getContext('2d')
stackedBarChart(ctx, 'HUMAN_HEALTH')
ctx = document.getElementById('climateChange').getContext('2d')
stackedBarChart(ctx, 'CLIMATE_CHANGE')
ctx = document.getElementById('resources').getContext('2d')
stackedBarChart(ctx, 'RESOURCES')
ctx = document.getElementById('ecosystemQuality').getContext('2d')
stackedBarChart(ctx, 'ECOSYSTEM_QUALITY')
document.getElementById('monoDiv').hidden = true
document.getElementById('humanHealthChart').hidden = false
document.getElementById('climateChangeChart').hidden = false
document.getElementById('resourcesChart').hidden = false
document.getElementById('ecosystemQualityChart').hidden = false
document.getElementById('switchVue').firstChild.data = 'Revenir aux impacts résumés'
} else {
const ctx = document.getElementById('monoChart').getContext('2d')
barChart(ctx)
document.getElementById('monoDiv').hidden = false
document.getElementById('humanHealthChart').hidden = true
document.getElementById('climateChangeChart').hidden = true
document.getElementById('resourcesChart').hidden = true
document.getElementById('ecosystemQualityChart').hidden = true
document.getElementById('switchVue').firstChild.data = 'Voir les impacts détaillés'
}
}
const color = Chart.helpers.color
window.chartColors = {
red: 'rgb(255, 99, 132)',
orange: 'rgb(255, 159, 64)',
yellow: 'rgb(255, 205, 86)',
green: 'rgb(75, 192, 192)',
blue: 'rgb(54, 162, 235)',
purple: 'rgb(153, 102, 255)',
grey: 'rgb(201, 203, 207)'
}
const colors = [
color(window.chartColors.red).alpha(0.5).rgbString(),
color(window.chartColors.orange).alpha(0.5).rgbString(),
color(window.chartColors.yellow).alpha(0.5).rgbString(),
color(window.chartColors.green).alpha(0.5).rgbString(),
color(window.chartColors.blue).alpha(0.5).rgbString(),
color(window.chartColors.purple).alpha(0.5).rgbString(),
color(window.chartColors.grey).alpha(0.5).rgbString()
]
const labelsMap = {
RESOURCES: 'Ressources',
CLIMATE_CHANGE: 'Changement climatique',
ECOSYSTEM_QUALITY: 'Écosystèmes',
HUMAN_HEALTH: 'Santé humaine'
}
const componentsCategoriesMap = {
hardware: 'Hardware',
software: 'Software',
journey: 'Transport'
}
function barChart (ctx) {
window.myBar = new Chart(ctx, {
type: 'bar',
data: barData(damages, scenarios),
options: {
responsive: true,
legend: {
position: 'top',
},
title: {
display: true,
text: 'Résultats'
}
}
})
}
function stackedBarChart (ctx, category) {
window.myBar = new Chart(ctx, {
type: 'bar',
data: stackedBarData(damages, scenarios, category),
options: {
title: {
display: true,
text: labelsMap[category]
},
tooltips: {
mode: 'index',
intersect: false
},
responsive: true,
scales: {
xAxes: [{
stacked: true
}],
yAxes: [{
stacked: true
}]
}
}
})
}
function barData (damages, scenarios) {
// Initialize chart data
const chartData = {
labels: [],
datasets: []
}
// Initialize one dataset per scenario
const datasets = {}
let i = 0
scenarios.forEach(scenario => {
const index = i + 1
datasets[scenario._id] = {
label: 'Scénario ' + index,
backgroundColor: colors[i],
borderColor: Object.values(window.chartColors)[i],
data: []
}
i++
})
// Populate the datasets by category
damages.forEach(categoryDamage => {
// New category in chart labels
chartData.labels.push(labelsMap[categoryDamage[0].damageEndpoint])
// Get the value for each dataset
categoryDamage.forEach(scenario => {
datasets[scenario.meetingScenario].data.push(scenario.value)
})
})
// Set the chart datasets to the populated datasets
Object.values(datasets).forEach(dataset => chartData.datasets.push(dataset))
return chartData
}
function stackedBarData (damages, scenarios, category) {
// Initialize chart data
const chartData = {
labels: [],
datasets: []
}
let i = 0
scenarios.forEach(scenario => {
const index = i + 1
chartData.labels.push('Scénario ' + index)
i++
})
// Initialize one dataset per component category
const datasets = {}
i = 0
Object.keys(componentsCategoriesMap).forEach(category => {
datasets[category] = {
label: componentsCategoriesMap[category],
backgroundColor: colors[colors.length - 1 - i],
borderColor: Object.values(window.chartColors)[colors.length - 1 - i],
data: []
}
i++
})
// Populate the datasets
const categoryDamage = damages.filter(damageCategory => damageCategory[0].damageEndpoint === category)[0]
Object.values(categoryDamage).forEach(damage => {
Object.keys(componentsCategoriesMap).forEach(componentCategory => {
datasets[componentCategory].data.push(damage[componentCategory])
})
})
// Set the chart datasets to the populated datasets
Object.values(datasets).forEach(dataset => chartData.datasets.push(dataset))
return chartData
}
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1><%= title %></h1>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.css' />
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<script type="text/javascript" src="/javascripts/meeting/utils.js"></script>
<script type="text/javascript" src="/javascripts/meeting/switchVue.js"></script>
</head>
<body>
<h1><%= title %></h1>
<button id="switchVue" onclick="switchVue()" type="button">
Détailler les graphiques
</button>
<div id="multiWrapper" class="wrapper" style="display: grid; grid-template-columns: repeat(3, 1fr);">
<div id="monoDiv" style=" grid-column: 1 / span 2; grid-row: 1">
<canvas id="monoChart"></canvas>
</div>
<div id="humanHealthChart" style="grid-column: 1; grid-row: 1" hidden>
<canvas id="humanHealth"></canvas>
</div>
<div id="climateChangeChart" style="grid-column: 2; grid-row: 1" hidden>
<canvas id="climateChange"></canvas>
</div>
<div id="resourcesChart" style="grid-column: 1; grid-row: 2" hidden>
<canvas id="resources"></canvas>
</div>
<div id="ecosystemQualityChart" style="grid-column: 2; grid-row: 2" hidden>
<canvas id="ecosystemQuality"></canvas>
</div>
</div>
<script>
const damages = JSON.parse('<%- JSON.stringify(normalisedDamages) %>')
const scenarios = JSON.parse('<%- JSON.stringify(scenarios) %>')
// Draw graphs when page reload
const ctx = document.getElementById('monoChart').getContext('2d')
barChart(ctx)
</script>
</body>
</html>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment