User Tools

Site Tools


lmarmiesse:solution_homework2
Critères & points attribués (/10)
Rappel du contexte 6
Résultats 10
Qualité du code (commentaires, structures utilisées, …) 8
Animation du dessin 10
Explication en dehors du code 6
Total (/50) 40

B.P. : On obtient bien le résultat attendu et l'animation fonctionne bien et on peut aussi régler la vitesse. Vos explications en dehors du code sont trop légères.

Onion.py
# Powered by Python 2.7
 
# To cancel the modifications performed by the script
# on the current graph, click on the undo button.
 
# Some useful keyboards shortcuts : 
#   * Ctrl + D : comment selected lines.
#   * Ctrl + Shift + D  : uncomment selected lines.
#   * Ctrl + I : indent selected lines.
#   * Ctrl + Shift + I  : unindent selected lines.
#   * Ctrl + Return  : run script.
#   * Ctrl + F  : find selected text.
#   * Ctrl + R  : replace selected text.
#   * Ctrl + Space  : show auto-completion dialog.
from tulip import *
 
# the updateVisualization(centerViews = True) function can be called
# during script execution to update the opened views
 
# the pauseScript() function can be called to pause the script execution.
# To resume the script execution, you will have to click on the "Run script " button.
 
# the runGraphScript(scriptFile, graph) function can be called to launch another edited script on a tlp.Graph object.
# The scriptFile parameter defines the script name to call (in the form [a-zA-Z0-9_]+.py)
 
# the main(graph) function must be defined 
# to run the script on the current graph
 
 
def bougerNoeud(noeud,x,y):
 
	noeudX=float(graph.getProperty('viewLayout').getNodeStringValue(noeud).replace('(',''.replace(')','')).split(',')[0])
	noeudY=float(graph.getProperty('viewLayout').getNodeStringValue(noeud).replace('(',''.replace(')','')).split(',')[1])
	distanceX=float(noeudX)-x
	distanceY=float(noeudY)-y
 
	#on modifie le x et le y du noeud pixel par pixel
 
	while (noeudX-x)>1 or (x-noeudX)>1:	
 
		graph.getProperty('viewLayout').setNodeStringValue(noeud,"("+str(noeudX)+","+str(noeudY)+",0)")
		if distanceX<0:		
			noeudX=noeudX+1
		else:
			noeudX=noeudX-1
 
		#on actualise de temps en temps, la vitesse de l'animation depend de la frequence d'actualisation	
		if (noeudX%5)==0.0:
			updateVisualization(centerViews = True)
 
	while (noeudY-y)>1 or (y-noeudY)>1:	
 
		graph.getProperty('viewLayout').setNodeStringValue(noeud,"("+str(noeudX)+","+str(noeudY)+",0)")
		if distanceY<0:		
			noeudY=noeudY+1
		else:
			noeudY=noeudY-1
 
		if (noeudY%5)==0.0:
			updateVisualization(centerViews = True)
 
 
	graph.getProperty('viewLayout').setNodeStringValue(noeud,"("+str(x)+","+str(y)+",0)")
	updateVisualization(centerViews = True)
 
def grandirNoeud(noeud,x,y):
 
	graph.getSizeProperty("viewSize").setNodeStringValue(noeud,"(1,1,0)")	
	NoeudTailleX=0.0
	NoeudTailleY=0.0
 
	#on modifie la taille pixel par pixel	
 
	#compteur pour l'actualisation
	compteur=0
	while (((y-NoeudTailleY)>1) or (x-NoeudTailleX)>1): 
 
		compteur=compteur+1
 
		if x-NoeudTailleX>1:
			NoeudTailleX=NoeudTailleX+1		
		if y-NoeudTailleY>1:
			NoeudTailleY=NoeudTailleY+1	
 
		graph.getSizeProperty("viewSize").setNodeStringValue(noeud,"("+str(NoeudTailleX)+","+str(NoeudTailleY)+",0)")
 
		if compteur%5==0:
			updateVisualization(centerViews = True)
 
	graph.getSizeProperty("viewSize").setNodeStringValue(noeud,"("+str(x)+","+str(y)+",0)")
 
	updateVisualization(centerViews = True)	
 
 
 
 
 
def traiterNoeud(noeud):
 
#	traitement
#	1 - recupere le pere 
	pere=graph.getInNode(noeud,1)
 
	#2 - gestion de la couleur
 
	couleurPere=graph.getColorProperty("viewColor").getNodeValue(pere)
	if (couleurPere.getR()+30)>255:
			graph.getColorProperty("viewColor").setNodeValue(noeud,tlp.Color(004, 047, 104))
	else:
		graph.getColorProperty("viewColor").setNodeValue(noeud,tlp.Color(couleurPere.getR()+30,couleurPere.getG()+22,couleurPere.getB()+7))
 
 
	#3 - on recupere le nombre de freres et sa "place" dans la fratrie
	nbFreres=0.0
	place=0.0
	for fils in graph.getOutNodes(pere):
		nbFreres=nbFreres+1
		if fils==noeud:
			place=nbFreres
 
	#4 - placement en fonction du pere, du nombre de frere et de sa place 
 
	taillePereX= float(graph.getSizeProperty("viewSize").getNodeStringValue(pere).replace('(','').replace(')','').split(',')[0])
	taillePereY= float(graph.getSizeProperty("viewSize").getNodeStringValue(pere).replace('(','').replace(')','').split(',')[1])
	posPereX= float(graph.getLayoutProperty("viewLayout").getNodeStringValue(pere).replace('(','').replace(')','').split(',')[0])
	posPereY= float(graph.getLayoutProperty("viewLayout").getNodeStringValue(pere).replace('(','').replace(')','').split(',')[1])		
 
	#on place les fils en largeur ou en hauteur en fonction de la taille du pere
	if taillePereX>=taillePereY:		
 
		posNoeudY=posPereY
		tailleNoeudY=taillePereY-(taillePereY/15)
 
		#depend du nb de frere et de sa place 
		posNoeudX=((posPereX-taillePereX/2)+taillePereX/(nbFreres*2))+(place-1)*(taillePereX/nbFreres)
		tailleNoeudX=(taillePereX/nbFreres)-(taillePereX/25)
 
	else:
 
		posNoeudX=posPereX
		tailleNoeudX=taillePereX-(taillePereX/10)
 
		#depend du nb de frere et de sa place 
		posNoeudY=((posPereY-taillePereY/2)+taillePereY/(nbFreres*2))+(place-1)*(taillePereY/nbFreres)
		tailleNoeudY=(taillePereY/nbFreres)-(taillePereY/30)
 
 
	#on effectue les deplacements
	graph.getSizeProperty("viewSize").setNodeStringValue(noeud,"(5,5,0)")#on agradit un peu le noeud pour voir le deplaement
 
	bougerNoeud(noeud,posNoeudX,posNoeudY)
	grandirNoeud(noeud,tailleNoeudX,tailleNoeudY)
 
	#5-fini
 
 
	for fils in graph.getOutNodes(noeud):
		traiterNoeud(fils)
 
def main(graph): 
 
	viewBorderColor =  graph.getColorProperty("viewBorderColor")
	viewBorderWidth =  graph.getDoubleProperty("viewBorderWidth")
	viewColor =  graph.getColorProperty("viewColor")
	viewFont =  graph.getStringProperty("viewFont")
	viewFontSize =  graph.getIntegerProperty("viewFontSize")
	viewLabel =  graph.getStringProperty("viewLabel")
	viewLabelColor =  graph.getColorProperty("viewLabelColor")
	viewLabelPosition =  graph.getIntegerProperty("viewLabelPosition")
	viewLayout =  graph.getLayoutProperty("viewLayout")
	viewMetaGraph =  graph.getGraphProperty("viewMetaGraph")
	viewRotation =  graph.getDoubleProperty("viewRotation")
	viewSelection =  graph.getBooleanProperty("viewSelection")
	viewShape =  graph.getIntegerProperty("viewShape")
	viewSize =  graph.getSizeProperty("viewSize")
	viewSrcAnchorShape =  graph.getIntegerProperty("viewSrcAnchorShape")
	viewSrcAnchorSize =  graph.getSizeProperty("viewSrcAnchorSize")
	viewTexture =  graph.getStringProperty("viewTexture")
	viewTgtAnchorShape =  graph.getIntegerProperty("viewTgtAnchorShape")
	viewTgtAnchorSize =  graph.getSizeProperty("viewTgtAnchorSize")
 
	select=graph.getBooleanProperty('viewSelection')
	pos=graph.getProperty('viewLayout')
	shape=graph.getProperty('viewShape')
	size=graph.getProperty('viewSize')
 
	root=0	
 
	for n in graph.getNodes():
		viewBorderColor.setNodeValue(n,tlp.Color(255,255,255))
		viewBorderWidth.setNodeValue(n,1)
		viewShape.setNodeStringValue(n,"1")
		#on recupere la racine
		if not graph.getInEdges(n).hasNext():
			root=n
 
	viewColor.setAllEdgeValue(tlp.Color(0,0,0,0))
 
	#Traitement de la racine
 
	viewColor.setNodeValue(root,tlp.Color(004, 047, 104))	
	grandirNoeud(root,2000,2000)
	bougerNoeud(root,500,500)
	#Traitement du reste de l'arbre
	for a in graph.getOutNodes(root):
		traiterNoeud(a)

Ce script transforme la représentation d'un arbre en “onion tree”. Cet algorithme consiste à inclure les noeuds fils dans leur père en les représentant par des formes géométriques. J'ai choisi de représenter les noeuds par des rectangles de couleurs différentes, la racine forme un carré qui contiendra tous ses fils.

Le script fonctionne si un arbre est importé dans Tulip, et il fonctionne sur le principe de la récursivité. En effet chaque noeud se place en fonction de son père et demande ensuite à ses fils de se placer. La transformation se fait par une animation qui déplace d'abord les noeuds à leur destination finale avant de les agrandir jusqu'à leur taille finale. La vitesse de l'animation dépend de la vitesse de l'ordinateur qui exécute les script, j'ai noté des différences de vitesses significatives entre les machines de CREMI et ma machine personelle. J'ai donc choisi une fréquence d'actualisation de la visualisation qui me parait correcte.

/net/html/perso/melancon/Visual_Analytics_Course/data/pages/lmarmiesse/solution_homework2.txt · Last modified: 2012/10/23 11:26 by bpinaud