Added map chart (back & front)

This commit is contained in:
Florian Sylvain
2022-01-09 18:50:35 +01:00
parent bf2f8fb2f4
commit 2fbf159ad5
9 changed files with 151 additions and 31 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="JavaScriptLibraryMappings"> <component name="JavaScriptLibraryMappings">
<file url="PROJECT" libraries="{highcharts.src, variable-pie}" /> <file url="PROJECT" libraries="{data, exporting, fr-all, highcharts.src, highmaps, map, offline-exporting, proj4js, us-all, variable-pie}" />
</component> </component>
</project> </project>
+8
View File
@@ -8,5 +8,13 @@
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="highcharts.src" level="application" /> <orderEntry type="library" name="highcharts.src" level="application" />
<orderEntry type="library" name="variable-pie" level="application" /> <orderEntry type="library" name="variable-pie" level="application" />
<orderEntry type="library" name="highmaps" level="application" />
<orderEntry type="library" name="us-all" level="application" />
<orderEntry type="library" name="offline-exporting" level="application" />
<orderEntry type="library" name="exporting" level="application" />
<orderEntry type="library" name="data" level="application" />
<orderEntry type="library" name="map" level="application" />
<orderEntry type="library" name="proj4js" level="application" />
<orderEntry type="library" name="fr-all" level="application" />
</component> </component>
</module> </module>
+1
View File
@@ -260,6 +260,7 @@ function displayResults(results, aCount) {
currentPage = (parseInt(urlOffset) + RESULTS_NUMBER) / RESULTS_NUMBER currentPage = (parseInt(urlOffset) + RESULTS_NUMBER) / RESULTS_NUMBER
updatePageNumber(currentPage) updatePageNumber(currentPage)
fadeIn() fadeIn()
console.log("chargment liste terminé")
let waitForPageToLoad = setInterval(function() { let waitForPageToLoad = setInterval(function() {
if (chartsState) { if (chartsState) {
hideLoading() hideLoading()
File diff suppressed because one or more lines are too long
+70 -3
View File
@@ -1,6 +1,7 @@
let chart1State = false let chart1State = false
let chart2State = false let chart2State = false
let chart3State = false let chart3State = false
let mapState = false
function initYearsChart(results) { function initYearsChart(results) {
let categories = [] let categories = []
@@ -68,6 +69,7 @@ function initYearsChart(results) {
}) })
chart1State = true chart1State = true
console.log("chargment graphique 1 terminé")
} }
function initDisciplinesChart(results) { function initDisciplinesChart(results) {
@@ -119,7 +121,7 @@ function initEstablishmentsChart(results) {
let disc = Object.keys(elem)[0] let disc = Object.keys(elem)[0]
let obj = { let obj = {
"name" : disc, "name" : disc,
"y" : parseInt(elem[disc]) "y" : parseInt(elem[disc]['number'])
} }
data.push(obj) data.push(obj)
}) })
@@ -152,6 +154,70 @@ function initEstablishmentsChart(results) {
}) })
chart3State = true chart3State = true
console.log("chargment graphique 3 terminé")
}
function initMapVisuals(data) {
const H = Highcharts, map = H.maps['countries/fr/fr-all'];
Highcharts.mapChart('map', {
"title": {
"text": "Nombre de thèses soutenues par établissements et leur géolocalisation"
},
"tooltip": {
"pointFormat": "{point.name}<br>" +
"Thèses: {point.z}"
},
"series": [{
"name": "Basemap",
"mapData": map,
"showInLegend": false
}, {
"name": "Separators",
"type": "mapline",
"showInLegend": false
}, {
"type": "mapbubble",
"dataLabels": {
"enabled": true,
"format": "{point.capital}"
},
"name": "Établissements",
"data": data
}]
});
mapState = true
console.log("chargement map terminé (les ID des établissements sont complètement cassés dans mon jeu de donnée)")
}
function initMap(results) {
let i = 0
let result = []
results.data.forEach(elem => {
let establishment = Object.keys(elem)[0]
let id = parseInt(elem[establishment]['ID'])
let number = parseInt(elem[establishment]['number'])
fetch(`https://data.enseignementsup-recherche.gouv.fr/api/records/1.0/search/?dataset=fr-esr-principaux-etablissements-enseignement-superieur&q=${id}&rows=10&fileds=identifiant_idref&fields=identifiant_idref,coordonnees`)
.then(response => response.json())
.then(data => {
if (data["records"].length > 0) {
let coordinates = data["records"][0]["fields"]["coordonnees"]
let obj = {
"name": establishment,
"lat": coordinates[0],
"lon": coordinates[1],
"z": number
}
result.push(obj)
}
i += 1
if (i === 10) {
initMapVisuals(result)
}
})
})
} }
function initCharts(search, option) { function initCharts(search, option) {
@@ -171,12 +237,13 @@ function initCharts(search, option) {
.then(response => response.json()) .then(response => response.json())
.then(results => { .then(results => {
initEstablishmentsChart(results) initEstablishmentsChart(results)
initMap(results)
}) })
let waitForChartsToLoad = setInterval(function() { let waitForChartsToLoad = setInterval(function() {
if (chart1State && chart2State && chart2State) { if (chart1State && chart2State && chart2State && mapState) {
chartsState = true chartsState = true
clearInterval(waitForChartsToLoad); clearInterval(waitForChartsToLoad);
} }
}, 100) }, 100)
} }
+13 -8
View File
@@ -254,6 +254,7 @@ class dump {
return $disciplines_array; return $disciplines_array;
} }
// SET sql_mode=''; au lieu de SET sql_mode='ONLY_FULL_GROUP_BY';
public static function getThesesEstablishments(string $search, string $option) : array { public static function getThesesEstablishments(string $search, string $option) : array {
$establishments_array = []; $establishments_array = [];
@@ -265,19 +266,20 @@ class dump {
$stmt = match ($option) { $stmt = match ($option) {
'auto' => $pdo->prepare(" 'auto' => $pdo->prepare("
SELECT soutenance_establishment AS Establishment, SELECT soutenance_establishment AS Establishment,
COUNT(soutenance_establishment) AS Number COUNT(soutenance_establishment) AS Number,
id_establishment AS ID
FROM theses FROM theses
WHERE author LIKE :search WHERE author LIKE :search
OR title LIKE :search OR title LIKE :search
OR these_director LIKE :search OR these_director LIKE :search
OR soutenance_establishment LIKE :search
GROUP BY Establishment GROUP BY Establishment
ORDER BY `Number` DESC ORDER BY Number DESC LIMIT 10
LIMIT 10;
"), "),
'author' => $pdo->prepare("SELECT soutenance_establishment AS Establishment, COUNT(soutenance_establishment) AS Number FROM theses WHERE author LIKE :search GROUP BY Establishment ORDER BY `Number` DESC LIMIT 10;"), 'author' => $pdo->prepare("SELECT soutenance_establishment AS Establishment, COUNT(soutenance_establishment) AS Number, id_establishment AS ID FROM theses WHERE author LIKE :search GROUP BY Establishment ORDER BY `Number` DESC LIMIT 10;"),
'title' => $pdo->prepare("SELECT soutenance_establishment AS Establishment, COUNT(soutenance_establishment) AS Number FROM theses WHERE title LIKE :search GROUP BY Establishment ORDER BY `Number` DESC LIMIT 10;"), 'title' => $pdo->prepare("SELECT soutenance_establishment AS Establishment, COUNT(soutenance_establishment) AS Number, id_establishment AS ID FROM theses WHERE title LIKE :search GROUP BY Establishment ORDER BY `Number` DESC LIMIT 10;"),
'director' => $pdo->prepare("SELECT soutenance_establishment AS Establishment, COUNT(soutenance_establishment) AS Number FROM theses WHERE these_director LIKE :search GROUP BY Establishment ORDER BY `Number` DESC LIMIT 10;"), 'director' => $pdo->prepare("SELECT soutenance_establishment AS Establishment, COUNT(soutenance_establishment) AS Number, id_establishment AS ID FROM theses WHERE these_director LIKE :search GROUP BY Establishment ORDER BY `Number` DESC LIMIT 10;"),
'establishment' => $pdo->prepare("SELECT soutenance_establishment AS Establishment, COUNT(soutenance_establishment) AS Number FROM theses WHERE soutenance_establishment LIKE :search GROUP BY Establishment ORDER BY `Number` DESC LIMIT 10;"), 'establishment' => $pdo->prepare("SELECT soutenance_establishment AS Establishment, COUNT(soutenance_establishment) AS Number, id_establishment AS ID FROM theses WHERE soutenance_establishment LIKE :search GROUP BY Establishment ORDER BY `Number` DESC LIMIT 10;"),
default => "", default => "",
}; };
@@ -287,7 +289,10 @@ class dump {
$i = 0; $i = 0;
while ($obj = $stmt->fetchObject()) { while ($obj = $stmt->fetchObject()) {
$establishments_array[$i] = array( $establishments_array[$i] = array(
$obj->Establishment => $obj->Number $obj->Establishment => array(
"number" => $obj->Number,
"ID" => $obj->ID
)
); );
$i++; $i++;
} }
+13 -6
View File
@@ -29,12 +29,6 @@
</svg> </svg>
</div> </div>
<div id="charts">
<div class="chart" id="years"></div>
<div class="chart" id="disciplines"></div>
<div class="chart" id="establishments"></div>
</div>
<div id="results-count"></div> <div id="results-count"></div>
<div class="page-nav"> <div class="page-nav">
@@ -43,6 +37,13 @@
<p onclick="browseResults(nbPages)">-&#62;</p> <p onclick="browseResults(nbPages)">-&#62;</p>
</div> </div>
<div id="charts">
<div class="chart" id="years"></div>
<div class="chart" id="disciplines"></div>
<div class="chart" id="establishments"></div>
<div class="chart" id="map"></div>
</div>
<div id="results"> <div id="results">
<h1 style="color:#CFCFCF;text-align: center">Bienvenue sur theses.fr</h1> <h1 style="color:#CFCFCF;text-align: center">Bienvenue sur theses.fr</h1>
</div> </div>
@@ -63,6 +64,12 @@
<!-- TODO Footer avec lien vers depot github --> <!-- TODO Footer avec lien vers depot github -->
<script src="https://code.highcharts.com/highcharts.src.js"></script> <script src="https://code.highcharts.com/highcharts.src.js"></script>
<script src="assets/proj4.js"></script>
<script src="https://code.highcharts.com/maps/modules/map.js"></script>
<script src="https://code.highcharts.com/maps/modules/data.js"></script>
<script src="https://code.highcharts.com/maps/modules/exporting.js"></script>
<script src="https://code.highcharts.com/maps/modules/offline-exporting.js"></script>
<script src="https://code.highcharts.com/mapdata/countries/fr/fr-all.js"></script>
<script src="charts.js"></script> <script src="charts.js"></script>
<script src="app.js"></script> <script src="app.js"></script>
+18 -6
View File
@@ -38,12 +38,24 @@
<div> <div>
<h3>Options : </h3> <h3>Options : </h3>
<div class="chart-button">
<svg id="chart-svg" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> <div>
<path d="M13.012 5.007v-1.668l2.802-2.771c.409.136.809.293 1.197.471l-3.999 3.968zm7.089-1.93l-7.089 7.058v.853h.877l7.044-7.076c-.263-.292-.541-.57-.832-.835zm-7.089-1.468l1.437-1.406c-.46-.094-.96-.163-1.437-.203v1.609zm10.789 7.962l-1.386 1.417h1.585c-.04-.47-.106-.964-.199-1.417zm-.363-1.366c-.135-.41-.292-.81-.469-1.199l-3.951 3.982h1.668l2.752-2.783zm-1.063-2.337c-.205-.346-.426-.682-.664-1.004l-6.093 6.124h1.668l5.089-5.12zm-3.225-3.57c-.322-.238-.657-.459-1.003-.665l-5.135 5.104v1.668l6.138-6.107zm-8.15 10.702v-13c-6.161.519-11 5.683-11 11.978 0 6.639 5.382 12.022 12.021 12.022 6.296 0 11.46-4.839 11.979-11h-13z"/> <div class="chart-button">
</svg> <svg id="chart-svg" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<div class="toggle-switch"> <path d="M13.012 5.007v-1.668l2.802-2.771c.409.136.809.293 1.197.471l-3.999 3.968zm7.089-1.93l-7.089 7.058v.853h.877l7.044-7.076c-.263-.292-.541-.57-.832-.835zm-7.089-1.468l1.437-1.406c-.46-.094-.96-.163-1.437-.203v1.609zm10.789 7.962l-1.386 1.417h1.585c-.04-.47-.106-.964-.199-1.417zm-.363-1.366c-.135-.41-.292-.81-.469-1.199l-3.951 3.982h1.668l2.752-2.783zm-1.063-2.337c-.205-.346-.426-.682-.664-1.004l-6.093 6.124h1.668l5.089-5.12zm-3.225-3.57c-.322-.238-.657-.459-1.003-.665l-5.135 5.104v1.668l6.138-6.107zm-8.15 10.702v-13c-6.161.519-11 5.683-11 11.978 0 6.639 5.382 12.022 12.021 12.022 6.296 0 11.46-4.839 11.979-11h-13z"/>
<div class="slider untoggle"></div> </svg>
<div class="toggle-switch">
<div class="slider toggle"></div>
</div>
</div>
<div class="chart-button">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M18 0c-3.148 0-6 2.553-6 5.702 0 4.682 4.783 5.177 6 12.298 1.217-7.121 6-7.616 6-12.298 0-3.149-2.852-5.702-6-5.702zm0 8c-1.105 0-2-.895-2-2s.895-2 2-2 2 .895 2 2-.895 2-2 2zm-12-3c-2.099 0-4 1.702-4 3.801 0 3.121 3.188 3.451 4 8.199.812-4.748 4-5.078 4-8.199 0-2.099-1.901-3.801-4-3.801zm0 5.333c-.737 0-1.333-.597-1.333-1.333s.596-1.333 1.333-1.333 1.333.596 1.333 1.333-.596 1.333-1.333 1.333zm6 5.775l-3.215-1.078c.365-.634.777-1.128 1.246-1.687l1.969.657 1.92-.64c.388.521.754 1.093 1.081 1.75l-3.001.998zm12 7.892l-6.707-2.427-5.293 2.427-5.581-2.427-6.419 2.427 3.62-8.144c.299.76.554 1.776.596 3.583l-.443.996 2.699-1.021 4.809 2.091.751-3.725.718 3.675 4.454-2.042 3.099 1.121-.461-1.055c.026-.392.068-.78.131-1.144.144-.84.345-1.564.585-2.212l3.442 7.877z"/>
</svg>
<div class="toggle-switch">
<div class="slider toggle"></div>
</div>
</div> </div>
</div> </div>
</div> </div>
+24 -7
View File
@@ -165,7 +165,7 @@ header {
#hamburger-menu { #hamburger-menu {
position: relative; position: relative;
z-index: 10; z-index: 25;
width: 100%; width: 100%;
background: linear-gradient(245deg, #39B4E7 -15%, #1779A3 110%); background: linear-gradient(245deg, #39B4E7 -15%, #1779A3 110%);
box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 5px; box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 5px;
@@ -183,6 +183,20 @@ header {
margin: 0; margin: 0;
} }
#hamburger-menu > div {
display: flex;
flex-direction: column;
gap: 5px;
}
#hamburger-menu > div + div {
}
#hamburger-menu > div + div > div {
display: flex;
gap: 15px;
}
.filters { .filters {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
@@ -292,7 +306,9 @@ header {
#results { #results {
padding: 10px; padding: 10px;
display: flex; display: flex;
flex-direction: column; flex-wrap: wrap;
justify-content: center;
align-items: center;
gap: 15px; gap: 15px;
overflow-x: hidden; overflow-x: hidden;
} }
@@ -304,6 +320,8 @@ header {
.result-element { .result-element {
display: flex; display: flex;
width: 100%;
max-width: 768px;
flex-direction: column; flex-direction: column;
box-shadow: rgba(0, 0, 0, 0.05) 2px 2px 15px; box-shadow: rgba(0, 0, 0, 0.05) 2px 2px 15px;
border-radius: 25px; border-radius: 25px;
@@ -543,14 +561,17 @@ header {
#charts { #charts {
display: none; display: none;
flex-direction: column; flex-wrap: wrap;
align-items: center; align-items: center;
justify-content: center;
padding: 15px; padding: 15px;
gap: 10px; gap: 10px;
} }
.chart { .chart {
width: 100%; width: 100%;
max-width: 500px;
min-width: 300px;
border-radius: 25px; border-radius: 25px;
padding: 15px; padding: 15px;
box-shadow: rgba(0, 0, 0, 0.05) 2px 2px 15px; box-shadow: rgba(0, 0, 0, 0.05) 2px 2px 15px;
@@ -572,10 +593,6 @@ header {
/* Medium */ /* Medium */
@media (min-width: 768px) { @media (min-width: 768px) {
.result-element {
width: 768px;
margin: auto;
}
#hamburger-menu { #hamburger-menu {
flex-direction: row; flex-direction: row;
} }