Giter VIP home page Giter VIP logo

qxd3's Introduction

QxD3

use D3.js within your qooxdoo applications

Run qx serve for a demo.

qxd3's People

Contributors

mbgonicus avatar oetiker avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

qxd3's Issues

addCssRule doesn't work if more than one qxd3 object

Sample code:

/* ************************************************************************

   Copyright:

   License:

   Authors:

 ************************************************************************ */

/**
 * This is the main application class of your custom application "testApp"
 * 
 * @asset(testapp/*)
 */
qx.Class.define("testapp.Application",
		{
	extend : qx.application.Standalone,


	/*
	 * ****************************************************************************
	 * MEMBERS
	 * ****************************************************************************
	 */

	members :
	{
		/**
		 * This method contains the initial application code and gets called during
		 * startup of the application
		 * 
		 * @lint ignoreDeprecated(alert)
		 */
		main : function()
		{
			// Call super class
			this.base(arguments);

			// Enable logging in debug variant
			if (qx.core.Environment.get("qx.debug"))
			{
				// support native logging capabilities, e.g. Firebug for Firefox
				qx.log.appender.Native;
				// support additional cross-browser console. Press F7 to toggle
				// visibility
				qx.log.appender.Console;
			}

			/*
			 * -------------------------------------------------------------------------
			 * Below is your actual application code...
			 * -------------------------------------------------------------------------
			 */


			// Document is the application root
			var doc = this.getRoot();

			var container = new qx.ui.container.Composite(new qx.ui.layout.Grid(10, 20)).set({
				decorator: "main",
				backgroundColor: "white",
				allowGrowX: false,
				allowGrowY: false
			});

			doc.add(container);

			// The following 2 definitions are needed to set width of container
			// columns.
			container.add(new qx.ui.core.Widget().set({
				height: 0,
				width: 600
			}), {row: 0, column: 0});
			container.add(new qx.ui.core.Widget().set({
				height: 0,
				width: 400
			}), {row: 0, column: 1});
			container.add(new qx.ui.core.Widget().set({
				height: 0,
				width: 200
			}), {row: 0, column: 2});

			var d3Obj1 = this.__makeGearDemo();
			container.add(d3Obj1, {row: 1, column: 0});

			var d3Obj2 = this.__makePieChart();	
			container.add(d3Obj2, {row: 1, column: 1});

			var d3Obj3 = this.__makeDashboard(container);


		},	// end main

		__makeDashboard : function(container) {
			var freqData=[
			              {State:'AL',freq:{low:4786, mid:1319, high:249}}
			              ,{State:'AZ',freq:{low:1101, mid:412, high:674}}
			              ,{State:'CT',freq:{low:932, mid:2149, high:418}}
			              ,{State:'DE',freq:{low:832, mid:1152, high:1862}}
			              ,{State:'FL',freq:{low:4481, mid:3304, high:948}}
			              ,{State:'GA',freq:{low:1619, mid:167, high:1063}}
			              ,{State:'IA',freq:{low:1819, mid:247, high:1203}}
			              ,{State:'IL',freq:{low:4498, mid:3852, high:942}}
			              ,{State:'IN',freq:{low:797, mid:1849, high:1534}}
			              ,{State:'KS',freq:{low:162, mid:379, high:471}}
			              ];

			var d3Obj = new qxd3.Svg();
			var svgRoot = d3Obj.getD3SvgNode();
			var d3 = d3Obj.getD3();
			d3Obj.setHeight(300);

			d3Obj.addCssRule('.arc path',
					{
				stroke : '#fff'
					}
			);

			d3Obj.addCssRule('.arc path:hover',
					{
				opacity : '0.9'
					}
			);

			d3Obj.addCssRule('.arc rect:hover',
					{
				fill : 'blue'
					}
			);

			d3Obj.addCssRule(".axis ", 
					{
				font: '10px sans-serif'
					}
			);

			d3Obj.addCssRule('.axis path .axis line',
					{
				fill: 'none',
				stroke: '#000',
				shapeRendering: 'crispEdges'
					}
			);

			d3Obj.addCssRule('x.axis path',
					{
				display: 'none'
					}
			);

			var d3Obj2 = new qxd3.Svg();
			var svgRoot2 = d3Obj2.getD3SvgNode();
			var d32 = d3Obj2.getD3();
			d3Obj2.setHeight(300);
			d3Obj2.addCssRule('.arc path',
					{
				stroke : '#fff'
					}
			);

			d3Obj2.addCssRule('.arc path:hover',
					{
				opacity : '0.9'
					}
			);

			d3Obj2.addCssRule('.arc rect:hover',
					{
				fill : 'blue'
					}
			);



			var d3Obj3 = new qxd3.Svg();
			var svgRoot3 = d3Obj3.getD3SvgNode();
			var d33 = d3Obj3.getD3();
			d3Obj3.setHeight(300);
			d3Obj2.addCssRule('.legend tr',
					{
				borderBottom: '1px solid grey'
					}
			);

			d3Obj2.addCssRule('.legend tr:first-child',
					{
				borderTop: '1px solid grey'
					}
			);
			d3Obj3.addCssRule('.legend',
					{
				marginBottom: '76px',
				display: 'inline-block',
				borderCollapse: 'collapse',
				borderSpacing: '0px'
					}
			);

			d3Obj3.addCssRule('.legend td',
					{
				padding: '4px 5px',
				verticalAlign: 'bottom'
					}
			);

			d3Obj3.addCssRule('.legendFreq .legendPerc',
					{
				align: 'right',
				width: '50px'
					}
			);

			dashboard(freqData, container);

			function dashboard(fData, container){
				var barColor = 'steelblue';
				function segColor(c){ return {low:"#807dba", mid:"#e08214",high:"#41ab5d"}[c]; }

				// compute total for each state.
				fData.forEach(function(d){d.total=d.freq.low+d.freq.mid+d.freq.high;});

				// function to handle histogram.
				function histoGram(fD){
					var hG={},    hGDim = {t: 60, r: 0, b: 30, l: 0};
					hGDim.w = 500 - hGDim.l - hGDim.r, 
					hGDim.h = 300 - hGDim.t - hGDim.b;

					// create svg for histogram.
					// var hGsvg = d3.select(id).append("svg")
					// var hGsvg = svg.attr("viewBox", "0 0 " + hGDim.w + hGDim.l + hGDim.r
					// + " " + hGDim.h + hGDim.t + hGDim.b/2).append("g")
					// var hGsvg = id.append()
					// .attr("width", hGDim.w + hGDim.l + hGDim.r)
					// .attr("height", hGDim.h + hGDim.t + hGDim.b).append("g")
					// .attr("transform", "translate(" + hGDim.l + "," + hGDim.t + ")");
					var width = hGDim.w + hGDim.l + hGDim.r;	
					var height = hGDim.h + hGDim.t + hGDim.b;	
					var hGsvg = svgRoot.append("svg").attr("viewBox", "0 0 " + width + " " + height).append("g")
					.attr("transform", "translate(" + hGDim.l + "," + hGDim.t + ")");

					// create function for x-axis mapping.
					var x = d3.scale.ordinal().rangeRoundBands([0, hGDim.w], 0.1)
					.domain(fD.map(function(d) { return d[0]; }));

					// Add x-axis to the histogram svg.
					hGsvg.append("g").attr("class", "x axis")
					.attr("transform", "translate(0," + hGDim.h + ")")
					.call(d3.svg.axis().scale(x).orient("bottom"));

					// Create function for y-axis map.
					var y = d3.scale.linear().range([hGDim.h, 0])
					.domain([0, d3.max(fD, function(d) { return d[1]; })]);

					// Create bars for histogram to contain rectangles and freq labels.
					var bars = hGsvg.selectAll(".bar").data(fD).enter()
					.append("g").attr("class", "bar");

					// create the rectangles.
					bars.append("rect")
					.attr("x", function(d) { return x(d[0]); })
					.attr("y", function(d) { return y(d[1]); })
					.attr("width", x.rangeBand())
					.attr("height", function(d) { return hGDim.h - y(d[1]); })
					.attr('fill',barColor)
					.on("mouseover",mouseover)// mouseover is defined below.
					.on("mouseout",mouseout);// mouseout is defined below.

					// Create the frequency labels above the rectangles.
					bars.append("text").text(function(d){ return d3.format(",")(d[1])})
					.attr("x", function(d) { return x(d[0])+x.rangeBand()/2; })
					.attr("y", function(d) { return y(d[1])-5; })
					.attr("text-anchor", "middle");

					function mouseover(d){  // utility function to be called on mouseover.
						// filter for selected state.
						var st = fData.filter(function(s){ return s.State == d[0];})[0],
						nD = d3.keys(st.freq).map(function(s){ return {type:s, freq:st.freq[s]};});

						// call update functions of pie-chart and legend.
						pC.update(nD);
						leg.update(nD);
					}

					function mouseout(d){    // utility function to be called on
						// mouseout.
						// reset the pie-chart and legend.
						pC.update(tF);
						leg.update(tF);
					}

					// create function to update the bars. This will be used by pie-chart.
					hG.update = function(nD, color){
						// update the domain of the y-axis map to reflect change in
						// frequencies.
						y.domain([0, d3.max(nD, function(d) { return d[1]; })]);

						// Attach the new data to the bars.
						var bars = hGsvg.selectAll(".bar").data(nD);

						// transition the height and color of rectangles.
						bars.select("rect").transition().duration(500)
						.attr("y", function(d) {return y(d[1]); })
						.attr("height", function(d) { return hGDim.h - y(d[1]); })
						.attr("fill", color);

						// transition the frequency labels location and change value.
						bars.select("text").transition().duration(500)
						.text(function(d){ return d3.format(",")(d[1])})
						.attr("y", function(d) {return y(d[1])-5; });            
					}        
					return hG;
				}

				// function to handle pieChart.
				function pieChart(pD){
					var pC ={},    pieDim ={w:250, h: 250};
					pieDim.r = Math.min(pieDim.w, pieDim.h) / 2;

					// create svg for pie chart.
					// var piesvg = d3.select(id).append("svg")
					// .attr("width", pieDim.w).attr("height", pieDim.h).append("g")
					// .attr("transform", "translate("+pieDim.w/2+","+pieDim.h/2+")");
					var width = pieDim.w;
					var height = pieDim.h;
					var piesvg = svgRoot2.append("svg").attr("viewBox", "0 0 " + width + " " + height).append("g")
					.attr("transform", "translate("+pieDim.w/2+","+pieDim.h/2+")");

					// create function to draw the arcs of the pie slices.
					var arc = d3.svg.arc().outerRadius(pieDim.r - 10).innerRadius(0);

					// create a function to compute the pie slice angles.
					var pie = d3.layout.pie().sort(null).value(function(d) { return d.freq; });

					// Draw the pie slices.
					piesvg.selectAll("path").data(pie(pD)).enter().append("path").attr("d", arc)
					.each(function(d) { this._current = d; })
					.style("fill", function(d) { return segColor(d.data.type); })
					.on("mouseover",mouseover).on("mouseout",mouseout);

					// create function to update pie-chart. This will be used by histogram.
					pC.update = function(nD){
						piesvg.selectAll("path").data(pie(nD)).transition().duration(500)
						.attrTween("d", arcTween);
					}        
					// Utility function to be called on mouseover a pie slice.
					function mouseover(d){
						// call the update function of histogram with new data.
						hG.update(fData.map(function(v){ 
							return [v.State,v.freq[d.data.type]];}),segColor(d.data.type));
					}
					// Utility function to be called on mouseout a pie slice.
					function mouseout(d){
						// call the update function of histogram with all data.
						hG.update(fData.map(function(v){
							return [v.State,v.total];}), barColor);
					}
					// Animating the pie-slice requiring a custom function which specifies
					// how the intermediate paths should be drawn.
					function arcTween(a) {
						var i = d3.interpolate(this._current, a);
						this._current = i(0);
						return function(t) { return arc(i(t));    };
					}    
					return pC;
				}

				// function to handle legend.
				function legend(lD){
					var leg = {};

					// create table for legend.
					// var legend = d3.select(id).append("table").attr('class','legend');
					var width = 150, height = 150;
					var svg = svgRoot3.append("svg").attr("viewBox", "0 0 " + width + " " + height);
					var legend = svg.append("table").attr('class','legend');

					// create one row per segment.
					var tr = legend.append("tbody").selectAll("tr").data(lD).enter().append("tr");

					// create the first column for each segment.
					tr.append("td").append("svg").attr("width", '16').attr("height", '16').append("rect")
					.attr("width", '16').attr("height", '16')
					.attr("fill",function(d){ return segColor(d.type); });

					// create the second column for each segment.
					tr.append("td").text(function(d){ return d.type;});

					// create the third column for each segment.
					tr.append("td").attr("class",'legendFreq')
					.text(function(d){ return d3.format(",")(d.freq);});

					// create the fourth column for each segment.
					tr.append("td").attr("class",'legendPerc')
					.text(function(d){ return getLegend(d,lD);});

					// Utility function to be used to update the legend.
					leg.update = function(nD){
						// update the data attached to the row elements.
						var l = legend.select("tbody").selectAll("tr").data(nD);

						// update the frequencies.
						l.select(".legendFreq").text(function(d){ return d3.format(",")(d.freq);});

						// update the percentage column.
						l.select(".legendPerc").text(function(d){ return getLegend(d,nD);});        
					}

					function getLegend(d,aD){ // Utility function to compute percentage.
						return d3.format("%")(d.freq/d3.sum(aD.map(function(v){ return v.freq; })));
					}

					return leg;
				}

				// calculate total frequency by segment for all state.
				var tF = ['low','mid','high'].map(function(d){ 
					return {type:d, freq: d3.sum(fData.map(function(t){ return t.freq[d];}))}; 
				});    

				// calculate total frequency by state for all segment.
				var sF = fData.map(function(d){return [d.State,d.total];});

				var hG = histoGram(sF), // create the histogram.
				pC = pieChart(tF), // create the pie-chart.
				leg = legend(tF);  // create the legend.
				container.add(d3Obj, {row: 2, column: 0});
				container.add(d3Obj2, {row: 2, column: 2});
				container.add(d3Obj3, {row: 2, column: 1});
			}
		},





		__makePieChart : function() {

			var dataAP = [
			                { age: '<5', population: 2704659 },
			                { age: '5-13', population: 4499890 },
			                { age: '14-17', population: 2159981 },
			                { age: '18-24', population: 3853788 },
			                { age: '25-44', population: 14106543 },
			                { age: '45-64', population: 8819342 },
			                { age: '>=65', population: 612463 }
			                ];

			var d3Obj4 = new qxd3.Svg();
			var svgRoot = d3Obj4.getD3SvgNode();
			var d3 = d3Obj4.getD3();
			d3Obj4.setHeight(300);
			d3Obj4.addCssRule('.arc path',
					{
				stroke : '#fff'
					}
			);

			d3Obj4.addCssRule(".arc text", 
					{
				textAlign: 'left',
				font: '28px sans-serif'// ,
					// text-anchor: 'middle'
					}
			);

			var width = 800, height = 500;
			var radiusAP = Math.min(width, height) / 2;
//			var svg = d3.select("svg"),
//			width = +svg.attr("width"),
//			height = +svg.attr("height"),
//			radius = Math.min(width, height) / 2,
//			g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height
//			/ 2 + ")");
			var svg = svgRoot.attr("viewBox", "0 0 " + width + " " + height).append("g")
			.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); 

			var color = d3.scale.category10(); // d3.scale.ordinal.range(["#98abc5",
			// "#8a89a6", "#7b6888", "#6b486b",
			// "#a05d56", "#d0743c",
			// "#ff8c00"]);
			// var color = d3.scale.ordinal.range["#98abc5", "#8a89a6", "#7b6888",
			// "#6b486b", "#a05d56", "#d0743c", "#ff8c00"];
			var pie = d3.layout.pie()
			.sort(null)
			.value(function(d) { return d.population; });

			var path = d3.svg.arc()
			.outerRadius(radiusAP - 10)
			.innerRadius(0);

			var label = d3.svg.arc()
			.outerRadius(radiusAP - 40)
			.innerRadius(radiusAP - 40);

			var arc = svg.selectAll(".arc")
			.data(pie(dataAP))
			.enter().append("g")
			.attr("class", "arc");

			arc.append('path')
			.attr('d', path)
			.attr('fill', function(d, i) {
				return color(d.data.age);
			});

			arc.append('text')
			.attr("transform", function(d) { return "translate(" + label.centroid(d) + ")"; })
			.attr("dy", "0.35em")
			.attr("font-weight", "bold")
			.attr("font-size", "20")
			.attr("text-anchor", "middle")
			.text(function(d) { return d.data.age; });

			return d3Obj4;	
		},


		__makeGearDemo : function()
		{
			var d3Obj5 = new qxd3.Svg();
			var svgRoot5 = d3Obj5.getD3SvgNode();
			var d35 = d3Obj5.getD3();
			
			d3Obj5.addCssRule('path',
					{
				fillRule : 'evenodd',
				stroke : '#333',
				strokeWidth : '1px'
					}
			);
			//The following is no longer effective, so I added .attr after the .append below
			//d3Obj5.addCssRule(".sun path", {
			//	fill : '#6baed6'
			//}
			//);
			d3Obj5.addCssRule(".planet path", {
				fill : '#9ecae1'
			}
			);
			d3Obj5.addCssRule(".annulus path", {
				fill : '#c6dbef'
			}
			);
			var width = 600, height = 300, radius = 80, x = Math.sin(2 * Math.PI / 3), y = Math.cos(2 * Math.PI / 3);
			var offset = 0, speed = 4, start = Date.now();
			/*
			 * var svg = d3.select("body").append("svg") .attr("width", width)
			 * .attr("height", height)
			 * 
			 * .append("g") .attr("transform", "translate(" + width / 2 + "," +
			 * height / 2 + ")scale(.55)") .append("g");
			 */
			var svg = svgRoot5.attr("viewBox", "0 0 " + width + " " + height).append("g")
			.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")scale(.30)").append("g"); // scale
			// was
			// .55
			var frame = svg.append("g").datum( {
				radius : Infinity
			});
			frame.append("g").attr("class", "annulus").datum(
					{
						teeth : 80,
						radius : -radius * 5,
						annulus : true
					}).append("path").attr("d", gear);
			frame.append("g").attr("class", "sun").datum(
					{
						teeth : 16,
						radius : radius
					}).append("path").attr("d", gear).attr("fill","#6baed6");
			frame.append("g").attr("class", "planet").attr("transform", "translate(0,-" + radius * 3 + ")").datum(
					{
						teeth : 32,
						radius : -radius * 2
					}).append("path").attr("d", gear);
			frame.append("g").attr("class", "planet").attr("transform", "translate(" + -radius * 3 * x + "," + -radius * 3 * y + ")").datum(
					{
						teeth : 32,
						radius : -radius * 2
					}).append("path").attr("d", gear);
			frame.append("g").attr("class", "planet").attr("transform", "translate(" + radius * 3 * x + "," + -radius * 3 * y + ")").datum(
					{
						teeth : 32,
						radius : -radius * 2
					}).append("path").attr("d", gear);
			function gear(d)
			{
				var n = d.teeth, r2 = Math.abs(d.radius), r0 = r2 - 8, r1 = r2 + 8, r3 = d.annulus ? (r3 = r0, r0 = r1, r1 = r3, r2 + 20) : 20, da = Math.PI / n, a0 = -Math.PI / 2 + (d.annulus ? Math.PI / n : 0), i = -1, path = ["M", r0 * Math.cos(a0), ",", r0 * Math.sin(a0)];
				while (++i < n)path.push("A", r0, ",", r0, " 0 0,1 ", r0 * Math.cos(a0 += da), ",", r0 * Math.sin(a0), "L", r2 * Math.cos(a0), ",", r2 * Math.sin(a0), "L", r1 * Math.cos(a0 += da / 3), ",", r1 * Math.sin(a0), "A", r1, ",", r1, " 0 0,1 ", r1 * Math.cos(a0 += da / 3), ",", r1 * Math.sin(a0), "L", r2 * Math.cos(a0 += da / 3), ",", r2 * Math.sin(a0), "L", r0 * Math.cos(a0), ",", r0 * Math.sin(a0));

				path.push("M0,", -r3, "A", r3, ",", r3, " 0 0,0 0,", r3, "A", r3, ",", r3, " 0 0,0 0,", -r3, "Z");
				return path.join("");
			}
			d35.timer(function()
					{
				var angle = (Date.now() - start) * speed, transform = function(d) {
					return "rotate(" + angle / d.radius + ")";
				};
				frame.selectAll("path").attr("transform", transform);
				frame.attr("transform", transform); /* frame of reference */
					});
			return d3Obj5;
		}

	}
});

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.