diff -r 94f586daa623 -r 8ca7f2cea729 alcatel/static/libraries/nco/cartographie.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/alcatel/static/libraries/nco/cartographie.js Thu Jan 24 16:58:55 2013 +0100 @@ -0,0 +1,801 @@ +function Carte(parametres, articles, links) { + + var object = this; + + this.parametres = { + // Module dimensions and caracteristics + width: 1440, + height: 800, + top: 50, + left: -240, + name: null, + boxID: "box", + selectorID: "carto", + canvasID: "canvas", + info: "infos", + + couleurs: null, + relations: null, + + // How to deal with the data + isPositions: false, + + charge: -30, + gravity: .13, + theta: 3, + + // Node rendering + nodeSizeInterval: [3, 15], + log: false, + exp: false, + layerStyle: { + opacity: 0.6 + }, + handle_len_rate: 2.2, + maxDistance: 35, + + scaleInterval: [0.5, 10], + + infobulleHtml: function(node) { + return node.titre + "
cluster: " + node.group +"
"; + }, + + activerZoom: true, + activerNodeZoom: true, + activerInfobulle: true, + zoomNode: false, + logZoomNode: false, + logZoomNodeParameter: 2 + }; + + this.beginDate = new Date(); + this.etendre(parametres); + + if (null==this.parametres.name) { + this.parametres.name = this.parametres.selectorID; + } + + //création du contenant sur la page, si inexistant + if (null == (document.getElementById(this.parametres.boxID))) { + d3.select('.content').append('div') + .attr("id", this.parametres.boxID) + .classed("gallery", true) + .style("position", "absolute") + .style("border", "1 px dashed"); + } + + d3.select('#' + this.parametres.boxID) + .style("width", this.parametres.width) + .style("height", this.parametres.height) + .style("position", "absolute") + .style("top", this.parametres.top) + .style("left", this.parametres.left) + .style("overflow", "hidden") + .style('z-index', 0); + + + if (null == (document.getElementById(this.parametres.selectorID))) { + d3.select('.gallery').append('div') + .attr("id", this.parametres.selectorID); + } + + d3.select('#' + this.parametres.selectorID) + .attr("width", this.parametres.width) + .attr("height", this.parametres.height) + .style("position", "absolute") + .style('z-index', 2); + + // Create drag interaction with the module + this.drag = d3.behavior.drag() + .on("dragstart", function(d, i) {object.dragstart(d, i, object);}) + .on("drag", object.dragmove) + .on("dragend", function(d, i) {object.dragend(d, i, object);}); + + this.static = false; + + if (this.parametres.activerNodeZoom) { + this.nodeMouseover = function(node) { + var scale = object.getScale(object.rect); + object.grow(node, scale); + }; + + this.nodeMouseout = function(node) { + var radius = object.radius(node.datum("scaledPoids")); + object.shrink(radius, node); + }; + } + + if (this.parametres.activerInfobulle) { + + this.nodeClick = function(d) { + object.highlight(d); + }; + + this.infoClick = function(d) { + object.blur(); + }; + } + + //création de l'infobulle, si inexistante + if (null == (this.infoBulle = d3.select('#' + this.parametres.info)[0][0])) { + this.infoBulle = d3.select('#' + this.parametres.selectorID).append('div') + .attr("id", this.parametres.info) + .style("top", this.parametres.height) + .style("opacity", 0) + .style("z-index", 1); + } + + if (null!=this.parametres.relations) { + this.parametres.relations.add( + this.parametres.name + ".infobulle", this.infoBulle) + .click(this.infoClick); + } + else { + this.infoBulle.on("click", this.infoClick); + } + + + //création du canvas sur la page, si inexistant + if (null == (this.canvas = document.getElementById(this.parametres.canvasID))) { + d3.select('.gallery').insert('canvas', '#' + this.parametres.selectorID) + .attr("id", this.parametres.canvasID) + .attr("resize", false); + this.canvas = document.getElementById(this.parametres.canvasID); + } + d3.select('#' + this.parametres.canvasID) + .attr("width", d3.select('#' + this.parametres.selectorID).attr("width")) + .attr("height", d3.select('#' + this.parametres.selectorID).attr("height")) + .style("position", "absolute") + .style("z-index", 1); + + this.mouse = {}; + this.isDown = false; + this.drag2 = false; + + this.svg = d3.select('#' + this.parametres.selectorID).append('svg') + .attr("width", this.parametres.width) + .attr("height", this.parametres.height) + .on("mousedown", function() {object.mouseDown(event);}) + .on("mousemove", function() {object.mouseMove(event);}) + .on("mouseup", function() {object.mouseUp(event);}); + + paper.setup(this.canvas); + paper.view.viewSize = new paper.Size(object.parametres.width, object.parametres.height); + + this.clusters = articles.clusters; + + //génération d'une palette de couleurs + if (null == this.parametres.couleurs) { + //this.parametres.couleurs = this.selectColors(this.clusters.length); + this.parametres.couleurs = new Couleurs(this.clusters.length); + } + + console.log("Environnement OK."); + + this.data = {}; + this.zones = []; + + if (this.parametres.isPositions) { + // Use directly data + this.data.nodes = this.generateNodes(articles, this.parametres.isPositions); + this.length = articles.nbItems; + this.display(); + + } + else { + //initialisation du Force Directed Graph + this.data.nodes = this.generateNodes(articles, this.parametres.isPositions); + this.data.links = this.generateLinks(links, this.data.nodes); + + this.force = d3.layout.force() + .charge(this.parametres.charge) //-20 + .nodes(this.data.nodes) + .links(this.data.links) + .linkDistance(function(link) {return link.linkDistance;}) //20 + .linkStrength(function(link) {return link.linkStrength;}) + .size([this.parametres.width, this.parametres.height]) + .gravity(this.parametres.gravity) //.1 + .theta(this.parametres.theta) + .start(); + + console.log("Graphe en cours de stabilisation . . ."); + + this.force.on("tick", function() { + console.log("Stabilisation OK."); + object.display(); + }); + + } +}; + + + +Carte.prototype = { + constructor: Carte, + + //gestion des paramètres + etendre: function(parametres) { + if (null==parametres || "object"!=typeof(parametres)) { + return; + } + + for (var cle in parametres) { + this.parametres[cle] = parametres[cle]; + } + }, + + display: function () { + + this.showNodes(); + if (this.parametres.activerZoom) { + this.activateZoom(); + } + + paper.setup(this.canvas); + paper.view.viewSize = new paper.Size( + this.parametres.width, this.parametres.height); + this.createBackground(); + }, + + activateZoom: function() { + this.rect = this.svg.selectAll("rect") + .data([{ + x: this.parametres.width*(1 - this.parametres.scaleInterval[0])/(this.parametres.scaleInterval[1] - this.parametres.scaleInterval[0]), + y: 0 + }]) + .enter().append("rect") + .attr("x", function(d) { return d.x; }) + .attr("y", function(d) { return d.y; }) + .attr("width", 15) + .attr("height", 15) + .style("stroke", "black") + .style("fill", "#00f") + .style("z-index", 2) + .call(this.drag); + + if (null!=this.parametres.relations) { + this.parametres.relations.add( + this.parametres.name + ".zoomButton", this.rect); + } + }, + + //génération d'une palette de couleurs + selectColors: function(nbClusters) { + var colors = colorbrewer; + var sets = ["BrBG", "PiYG", "PRGn", "PuOr", "RdBu", "RdYlBu", "RdYlGn"]; + var selectorID, finalColors = []; + + while (finalColors.length < nbClusters) { + selectorID = Math.floor(Math.random()*7); + selectorID2 = Math.floor(Math.random()*11); + color = new paper.RgbColor(colors[sets[selectorID]][11][selectorID2]); + + var available = true; + for (var i = 0; i < finalColors.length; i++) { + if (Math.floor(finalColors[i].hue) == Math.floor(color.hue)) { + available = false; + } + } + + if (color.brightness < 0.9 && available) { + finalColors.push(color.toCssString()); + } + } + + return finalColors; + }, + + //génération des noeuds √† partir du json + generateNodes: function(items, isPos) { + + var nodes = []; + var poidsMin = 100000, poidsMax = 0; + + // on crée les noeuds + for (var i = 0 ; i