diff d3s_examples/python-neo4jrestclient/static/platin/js/PieChart/PieChart.js @ 8:18ef6948d689

new d3s examples
author Dirk Wintergruen <dwinter@mpiwg-berlin.mpg.de>
date Thu, 01 Oct 2015 17:17:27 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/d3s_examples/python-neo4jrestclient/static/platin/js/PieChart/PieChart.js	Thu Oct 01 17:17:27 2015 +0200
@@ -0,0 +1,384 @@
+/*
+* PieChart.js
+*
+* Copyright (c) 2013, Sebastian Kruse. All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+* MA 02110-1301  USA
+*/
+
+/**
+ * @class PieChart
+ * Implementation for a PieChart
+ * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de)
+ *
+ * @param {HTML object} parent div to append the PieChart
+ */
+function PieChart(parent, watchedDataset, watchedColumn, selectionFunction) {
+
+	if ((typeof selectionFunction !== "undefined") &&
+		(typeof selectionFunction.type !== "undefined") && 
+		(typeof selectionFunction.categories !== "undefined")){
+		this.type = selectionFunction.type;
+		this.categories = selectionFunction.categories;
+	}
+	this.pieChart = this;
+	this.pieChartDiv;
+	this.preHighlightObjects;
+	this.highlightedLabel;
+	
+	this.informationDIV;
+	this.pieChartLabel;
+	
+	this.parent = parent;
+	this.options = parent.options;
+	
+	this.watchedDatasetObject;
+	this.watchedDataset = parseInt(watchedDataset);
+	this.watchColumn = watchedColumn;
+	if (typeof selectionFunction !== "undefined")
+		this.selectionFunction = selectionFunction;
+	else
+		//default selectionFunction returns value (creates "distinct" piechart)
+		this.selectionFunction = function(columnData){return columnData;};	
+}
+
+PieChart.prototype = {
+
+	remove : function() {
+		for (var i = 0; i < this.parent.pieCharts.length; i++){
+			if (this.parent.pieCharts[i] === this)
+				this.parent.pieCharts[i] = null;
+		}			
+		$(this.pieChartDiv).remove();
+		$(this.informationDIV).remove();
+		this.parent.redrawPieCharts();
+	},
+	
+	refreshLabel : function(){
+		$(this.pieChartLabel).empty();
+		$(this.pieChartLabel).append(this.watchedDatasetObject.label + " - " + this.watchColumn);		
+		
+		var c = GeoTemConfig.getColor(this.watchedDataset);
+		$(this.pieChartLabel).css("color","rgb("+c.r1+","+c.g1+","+c.b1+")");
+	},
+	
+	initialize : function() {
+		var pieChart = this;
+		
+		if (typeof this.pieChartDiv === "undefined"){
+			this.informationDIV = document.createElement("div");
+			this.pieChartLabel = $("<span></span>");
+			$(this.informationDIV).append(this.pieChartLabel);
+			this.refreshLabel(); 
+
+			var removeButton = document.createElement("button");
+			$(this.informationDIV).append(removeButton);
+			$(removeButton).text("remove");
+			$(removeButton).click(function(){
+				pieChart.remove();
+			});
+
+			//only allow editing if it is a "manually" created piechart
+			//automatic (with a selection function) ones, can lead to numerous problems,
+			//e.g. too many categories or numeral categories threated as text ones
+			if ((typeof pieChart.type !== "undefined")&&
+				(typeof pieChart.categories !== "undefined")){
+				var editButton = document.createElement("button");
+				$(this.informationDIV).append(editButton);
+				$(editButton).text("edit");
+				$(editButton).click(function(){
+					var chooser = new PieChartCategoryChooser(
+							pieChart.parent,
+							pieChart.parent.options,
+							pieChart.watchedDataset,
+							pieChart.watchColumn,
+							pieChart.type,
+							pieChart.categories);
+				});
+				
+				//add save button
+				if (pieChart.options.allowLocalStorage){
+					var saveButton = document.createElement("button");
+					$(this.informationDIV).append(saveButton);
+					$(saveButton).text("save");
+					$(saveButton).click(function(){
+						$(	"<div>" +
+								"pie chart name : " +
+								"<input type='text' size=30 id='saveName' class='ui-widget-content ui-corner-all'></input>" +
+							"</div>").dialog({
+						        width:'auto',
+								buttons: [
+								          {
+								        	  text: "save",
+								        	  click: function(){
+								        		  var saveName = $("#saveName").val();
+								        		  var saveObject = new Object();
+								        		  saveObject.type = pieChart.type;
+								        		  saveObject.categories = pieChart.categories;
+								        		  saveObject.columnName = pieChart.watchColumn;
+								        		  //save to LocalStorage
+								        		  $.remember({
+								        			  name:pieChart.options.localStoragePrefix+saveName,
+								        			  value:saveObject,
+								        			  json:true
+								        		  });
+								        		  $(this).dialog( "close" );
+								        	  }
+								          }
+								]
+						});
+						
+						//set value to default (column name)
+						$("#saveName").val(pieChart.watchColumn);
+						//TODO: z-index has to be set, as the "tool-bars" of map (.ddbToolbar in style.css)
+						//also have a z-index of 10000. z-index should be removed from all elements. 
+						$(".ui-dialog").css("z-index",10005);
+					});
+				}
+			}							
+
+			$(this.parent.gui.pieChartsDiv).append(this.informationDIV);
+			this.pieChartDiv = document.createElement("div");
+			$(this.parent.gui.pieChartsDiv).append(this.pieChartDiv);
+
+			$(this.pieChartDiv).unbind();
+		    $(this.pieChartDiv).bind("plothover", function (event, pos, item) {
+		    	var highlightedLabel;
+		    	
+		        if (item) {
+		        	highlightedLabel = item.series.label;
+		        }
+		        if (highlightedLabel !== pieChart.highlightedLabel){
+		        	pieChart.highlightedLabel = highlightedLabel;
+		        	pieChart.triggerHighlight(highlightedLabel);
+		        }
+		    });
+			
+		    $(this.pieChartDiv).bind("plotclick", function (event, pos, item) {
+		        if (item) {
+					//item.series.label contains the column element
+					pieChart.triggerSelection(item.series.label);                              
+		        } else {
+		        	pieChart.triggerSelection();
+		        }
+		    });
+		}
+	},
+
+	//check if dataset is still there
+	checkForDataSet : function() {
+		var datasets = this.parent.datasets;
+		if ((typeof datasets !== "undefined") && (typeof this.watchedDatasetObject !== "undefined")){
+			//check if our data went missing
+			for (var i = 0; i < datasets.length; i++){
+				if (datasets[i] === this.watchedDatasetObject){
+					//if dataset "before" this one was removed, the index changes
+					if (this.watchedDataset !== i){
+						//change color to the new one (changes with index!)
+						this.watchedDataset = i;
+						this.refreshLabel();
+					}					
+					return true;
+				}
+			}
+		}
+		return false;
+	},
+	
+	initPieChart : function(dataSets) {
+		// get dataset object (could not be there on startup, e.g. piechart defined before load completes)
+		if (typeof this.watchedDatasetObject === "undefined")
+			this.watchedDatasetObject = this.parent.datasets[this.watchedDataset];
+
+		this.initialize();
+
+		// if our dataset went missing, remove this piechart
+		if (!this.checkForDataSet()){
+				this.remove();
+				return;
+		}
+		
+		var objects = [];
+		for (var i = 0; i < dataSets.length; i++)
+			objects.push([]);
+		objects[this.watchedDataset] = dataSets[this.watchedDataset].objects;
+		
+		this.preHighlightObjects = objects;
+		this.redrawPieChart(objects);
+	},
+
+	redrawPieChart : function(objects) {
+		
+		if (typeof objects === "undefined")
+			objects = this.preHighlightObjects;
+		
+		if (this.checkForDataSet(objects)){
+			var pieChart = this;
+			if (objects[this.watchedDataset].length === 0)
+				objects = this.preHighlightObjects;
+			
+			var calculateSlices = function(dataObjects){
+				var chartDataCounter = new Object;
+
+				$(dataObjects).each(function(){
+					var columnData = pieChart.parent.getElementData(this, pieChart.watchColumn, pieChart.selectionFunction);
+					
+					//disregard empty cells
+					if ( (typeof columnData === "undefined") || (columnData == "") )
+						return;
+					
+					var weight = this.weight;
+				
+					if (typeof chartDataCounter[columnData] === "undefined")
+						chartDataCounter[columnData] = weight;
+					else
+						chartDataCounter[columnData] += weight;
+				});
+				
+				var chartData = [];
+				$.each(chartDataCounter, function(name,val){
+					//get rgb-color (24bit = 6 hex digits) from hash
+					var color = '#'+hex_md5(name).substr(0,6);
+					chartData.push({label:name,data:val,color:color});
+				});
+				
+				//sort by count (occurances of category)
+				var sortByVal = function(a,b){
+					return (b.data-a.data);
+				};
+				chartData.sort(sortByVal);
+				
+				return chartData;
+			};
+			
+			var chartData = calculateSlices(objects[this.watchedDataset]);
+			
+			if (chartData.length>0){
+				$(this.pieChartDiv).empty();
+				
+				//calculate height (flot NEEDS a height)				
+				var parentHeight = $(this.parent.gui.pieChartsDiv).outerHeight(true) - $(this.parent.gui.columnSelectorDiv).outerHeight(true);
+				var pieChartCount = 0;
+				$(this.parent.pieCharts).each(function(){
+					if (this instanceof PieChart)
+						pieChartCount++;
+				});
+				var height = (parentHeight/pieChartCount) - $(this.informationDIV).outerHeight(true);
+				if (pieChart.options.restrictPieChartSize !== false)
+					height = Math.min(height, $(window).height() * pieChart.options.restrictPieChartSize);
+				$(this.pieChartDiv).height(height);
+	
+				$.plot($(this.pieChartDiv), chartData,
+					{
+						series: {
+							// Make this a pie chart.
+							pie: {
+								show:true
+							}
+						},
+						legend: { show:true, position: 'se' },
+						grid: {
+				            hoverable: true,
+				            clickable: true
+				        },
+				        tooltip: true,
+				        tooltipOpts: {
+				            content: "%s %p.1%"
+				        }
+					}
+				);
+			}
+		}
+	},
+		
+	triggerHighlight : function(columnElement) {
+		var highlightedObjects = [];
+		for (var i = 0; i < GeoTemConfig.datasets.length; i++)
+			highlightedObjects.push([]);
+		
+		if (this.watchedDataset >= 0)
+			highlightedObjects[this.watchedDataset] = 
+				this.parent.getElementsByValue(columnElement, this.watchedDataset, this.watchColumn, this.selectionFunction);
+		else
+			highlightedObjects[this.watchedDataset] = [];
+		
+		this.parent.core.triggerHighlight(highlightedObjects);
+		
+		var pieChart = this;
+		$(this.parent.pieCharts).each(function(){
+			if (this instanceof PieChart && (this !== pieChart)){
+				if (this.watchedDataset === pieChart.watchedDataset)
+					this.redrawPieChart(highlightedObjects);
+			}				
+		});
+	},
+
+	triggerSelection : function(columnElement) {
+		var selectedObjects = [];
+		for (var i = 0; i < GeoTemConfig.datasets.length; i++)
+			selectedObjects.push([]);
+
+		var selection;
+		if (typeof columnElement !== "undefined"){
+			selectedObjects[this.watchedDataset] = 
+				this.parent.getElementsByValue(columnElement, this.watchedDataset, this.watchColumn, this.selectionFunction);
+			selection = new Selection(selectedObjects, this);
+		} else {
+			selection = new Selection(selectedObjects);
+		}
+
+		this.parent.core.triggerSelection(selection);
+		
+		if (!selection.valid()){
+			selection.loadAllObjects();
+			//"undo" selection (click next to piechart)
+			//so also redraw this dataset
+			this.preHighlightObjects = selection.objects;
+			this.redrawPieChart(selection.objects);
+		}			
+		
+		var pieChart = this;
+		$(this.parent.pieCharts).each(function(){
+			if (this instanceof PieChart && (this !== pieChart)){
+				if (this.watchedDataset === pieChart.watchedDataset){
+					this.preHighlightObjects = selection.objects;
+					this.redrawPieChart(selection.objects);
+				}
+			}				
+		});
+	},
+
+	deselection : function() {
+	},
+
+	filtering : function() {
+	},
+
+	inverseFiltering : function() {
+	},
+
+	triggerRefining : function() {
+	},
+
+	reset : function() {
+	},
+	
+	show : function() {		
+	},
+
+	hide : function() {
+	}
+};