Bonjour à tous,

Je suis actuellement en train de développer une petite application de statistiques avec Backbone et je rencontre un problème.

Voici déjà l'application ici

Mon problème : Lorsque je clique sur le menu d'échantillonnage en haut à droite (heure / jour / semaine / mois), mon graphique doit changer et ne change justement pas.

Voici mon code :

Le modèle :
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 
// Déclaration des models
 
window.time = Backbone.Model.extend({
	defaults : {
		route : "",
		libelle : "",
		graph : ""
	},
 
	initialize : function Graph() {
		console.log('Graph Constructor');
	},
 
	getGraph : function() {
		return this.get('graph');
	}
});
 
 
// Déclaration des collections
echantillonnage.Collections.times = Backbone.Collection.extend( {
	model : window.time
});


Le router :
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
 
echantillonnage.Router = Backbone.Router.extend({
 
	initialize : function(times) {
		// On créé un raccourci pour accéder plus rapidement à la collection par la suite
		this.times = echantillonnage.collections.times;
		// On instancie la vue principale
		echantillonnage.views.main = new echantillonnage.Views.main();
	},
 
	routes : {
		'' : 'root',
		':routeChart' : 'displayChart',
	},
 
	// Cette route sera appelé à chaque fois qu'une route est inexistante ainsi qu'au lancement de l'application
	root : function() {
		var firstElement = this.times.toJSON()[1];
		if (firstElement) {
			this.displayChart(firstElement.route);
		}
	},
 
	// Cette route est appelée à chaque fois qu'une route pour un echantillonnage est appelée
	displayChart : function(route) {
		// On cherche dans la collection si la route existe dans un de nos echantillonnage
		var time = _.find(this.times.toJSON(), function (el) {
			return el.route === route;
		});
		// var graphique = graphMonth.getGraph();
		// return graphique;
		// Si l'échantillonnage existe, on appelle la fonction de notre vue afin d'afficher le graphique correspondant
		// if (time) {
			// echantillonnage.views.main.displayChart(time);
		// }
	}
});
 
graph.Router = Backbone.Router.extend({
 
	initialize : function(times) {
		// On créé un raccourci pour accéder plus rapidement à la collection par la suite
		this.times = echantillonnage.collections.times;
		// On instancie la vue principale
		graphique = new graph();
	},
 
	routes : {
		'' : 'root',
		':routeChart' : 'displayChart',
	},
 
	// Cette route sera appelé à chaque fois qu'une route est inexistante ainsi qu'au lancement de l'application
	root : function() {
		var firstElement = this.times.toJSON()[3];
		if (firstElement) {
			this.displayChart(firstElement.route);
		}
	},
 
	// Cette route est appelée à chaque fois qu'une route pour un echantillonnage est appelée
	displayChart : function(route) {
		// On cherche dans la collection si la route existe dans un de nos echantillonnage
		var time = _.find(this.times.toJSON(), function (el) {
			return el.route === route;
		});
		// Si l'échantillonnage existe, on appelle la fonction de notre vue afin d'afficher le graphique correspondant
		if (time) {
			graphique.displayChart(time);
		}
		// Sinon on appelle la route "root" afin d'afficher le premier personnage de la liste
		else if (this.times.length) {
			this.root();
		}
	}
});


La vue
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
 
// Vue Echantillonnage
echantillonnage.Views.main = Backbone.View.extend({
	el : '#echantillonnage',
	// Fonction appelé automatiquement lors de l'instanciation de la vue
	initialize : function() {
		// déclaration des templates
		this.templaceTimeline = $('#templaceTimeline').html();
		// On initialise le menu
		this.initEchantillonnage();
	},
 
	initEchantillonnage : function() {
		// On transforme notre collection en un tableau de Hash
		var times = echantillonnage.collections.times.toJSON();
		//Création des éléments du menu en utilisant le template et les différents temps
		var echantillonnageHTML = _.template(this.templaceTimeline, { times : times });
		// On affiche le menu
		this.$('#content-echantillonnage').html(echantillonnageHTML);
	}/*,
 
	displayChart : function(time) {
		// On génère le html pour afficher la courbe correspondante à l'échantillonnage
		var chartHTML = _.template(this.templaceChart, { time : time });
		// On l'affiche
		this.$('#import-chart').html(chartHTML)
	}*/
});
 
// Vue graphique
window.graph = Backbone.View.extend({
	el : '#import-js',
	// Fonction appelé automatiquement lors de l'instanciation de la vue
	initialize : function() {
		// déclaration des templates
		this.templaceChart = $('#templaceChart').html();
	},
 
	displayChart : function(time) {
		// On génère le html pour afficher la courbe correspondante à l'échantillonnage
		var chartHTML = _.template(this.templaceChart, { time : time });
		// On l'affiche
		this.$('#import-chart').html(chartHTML)
	}
});

Le fichier html :
Code html : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 
..........
<div class="row"> <!-- Zone d'affichage du graphique -->
	<div class="col-xs-12" id="content-chart">
		<div class="table-responsive" id="chart_div">
		</div><!-- /.table-responsive -->
	</div><!-- /span -->
</div><!-- /row -->
 
..........
 
<script type="text/template" id="templaceChart">
	<!-- Base des Charts -->
	<%= time.graph %>
	<script type="text/javascript" src="src/<%= time.route %>_charts.js" onload="location.reload(document.getElementById('chart_div'));"></script>
</script>
 
..........
 
<div id="import-js">
	<div id="import-chart">
		<script type="text/javascript" src="src/charts.js"></script>
	</div>
</div>

L'application :
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// Menu d'échantillonnage
var echantillonnage = {
	// Classes
	Collections : {},
	Models : {},
	Views : {},
	// Instances
	collections : {},
	models : {},
	views : {},
	init : function(times) {
	console.log(times[3]);
		graphHour = new time(times[0]);
		graphDay = new time(times[1]);
		graphWeek = new time(times[2]);
		graphMonth = new time(times[3]);
		// Initialisation de la collection Times
		this.collections.times = new this.Collections.times().add([graphHour, graphDay, graphWeek, graphMonth]);
		// this.collections.times.add(graphDay);
		// Initialisation du router, c'est lui qui va instancier notre vue
		this.router = new echantillonnage.Router();
		// Initialisation du router, c'est lui qui va instancier notre vue
		this.router = new graph.Router();
		// On pr?se Backbone JS de commencer écouter les changement de l'url afin d'appeler notre routeur
		Backbone.history.start();
	}
};
 
$(document).ready(function() {
	var dataMois = [
		['Mois', '2012', '2013'],
		['Jan.', 1000, 400],
		['Fév.', 1170, 460],
		['Mars', 660, 1120],
		['Avr.', 1030, 540],
		['Mai', 1000, 400],
		['Juin', 950, 540],
		['Juil.', 1032, 1303],
		['Août', 968, 2023],
		['Sept.', 1664, 1234],
		['Oct.', 1235, 1321],
		['Nov.', 346, 954],
		['Déc.', 1263, 912]
	];
	var dataSemaine = [
		['Semaine', '2012', '2013'],
		['1', 1000, 400],
		['2', 1170, 460],
		['3', 660, 1120],
		['4', 1030, 540],
		['5', 1000, 400],
		['6', 950, 540],
		['7', 1032, 1303],
		['8', 968, 2023],
		['9', 1664, 1234],
		['10', 1235, 1321],
		['11', 346, 954],
		['12', 1235, 1321],
		['13', 346, 954],
		['14', 1235, 1321],
		['15', 346, 954],
		['16', 1263, 912]
	];
 
	var times = [
		{ route : "heure", libelle : "Heure", graph : "" },
		{ route : "jour", libelle : "Jour", graph : "" },
		{ route : "semaine", libelle : "Semaine", graph : dataSemaine },
		{ route : "mois", libelle : "Mois", graph : dataMois }
	];
 
	function refresh() {
		$.ajax({
			url: "recherches.html", // Ton fichier ou se trouve ton chat
			success:
				function(retour){
				$('chart_div').html(retour); // rafraichi toute ta DIV "bien sur il lui faut un id "
			}
		});
	}
 
	// On lance l'application une fois que notre HTML est chargé
	echantillonnage.init(times);
});

Le code Google Charts pour les mois (mois_charts.js) :
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Graphique Visites
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
	document.getElementById('chart_div').innerHTML = "";
	var data = google.visualization.arrayToDataTable(graphMonth.getGraph());
 
	var options = {
		title: 'Nombre de visites'
	};
 
	var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
	chart.draw(data, options);
 
}

Le code Google Charts pour les semaines (semaine_charts.js) :
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Graphique Visites
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
	document.getElementById('chart_div').innerHTML = "";
	var data = google.visualization.arrayToDataTable(graphWeek.getGraph());
 
	var options = {
		title: 'Nombre de visites'
	};
 
	var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
	chart.draw(data, options);
 
}


Quelques explications :

J'ai tronqué quelques morceaux de codes, surtout dans le html, afin de vous montrer seulement les parties concernées. Comme j'utilise un template bootstrap ça ne sert à rien de surcharger la page.

Donc mon modèle échantillonnage me sert pour afficher à la fois le menu d'échantillonnage et à donner à Google Charts les valeurs pour la courbe (la partie graph de mon modèle).

Lorsque l'on clique sur semaine ou mois (seules valeurs renseignées pour mes tests), la route s'affiche bien dans l'url, et lorsque l'on regarde dans le code les changements se font bien. Comme vous pouvez le voir dans le template du html, je me sers du router pour importé tel ou tel fichier javascript dans mon code. Sachant qu'en réalité les fichiers sont les mêmes à la différence près que les valeurs correspondent soit à l'affichage des mois ou des semaines.

J'imagine que mon problème est là, d'où ma question, comment faire pour que mon graphique se recharge dans ma page lors du changement d'import de fichier javascript ?

A savoir que si j'affiche ma page avec le graphique des mois, si je bascule sur semaine le graphique des mois reste, mais si maintenant que j'ai #semaine comme route je rafraîchis ma page, le graphique des semaines viendra se mettre correctement.

J'en est probablement beaucoup mis mais mieux vaut trop que pas assez je pense

En tout cas merci d'avance