From c8cc74e7622c42dd0f4bd2ec39ed70791c01bbd8 Mon Sep 17 00:00:00 2001 From: Gareth James Date: Tue, 6 Aug 2013 10:02:12 +0100 Subject: [PATCH 1/5] added bower configuration --- bower.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 bower.json diff --git a/bower.json b/bower.json new file mode 100644 index 0000000..320abb3 --- /dev/null +++ b/bower.json @@ -0,0 +1,12 @@ +{ + "name": "dangle", + "version": "1.0.0", + "main": "src/dangle.module.js", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ] +} From 56f4da3b7176d112c8f09124c07740b95c1a61ea Mon Sep 17 00:00:00 2001 From: Gareth James Date: Tue, 6 Aug 2013 12:41:04 +0100 Subject: [PATCH 2/5] added support for setting margins with attributes added support for setting ticks on the x and y axis from attributes --- src/modules/area/area.js | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/modules/area/area.js b/src/modules/area/area.js index 568a191..6565c36 100644 --- a/src/modules/area/area.js +++ b/src/modules/area/area.js @@ -41,18 +41,25 @@ angular.module('dangle') duration: '@', delay: '@', plot: '@', - pointRadius: '@' + pointRadius: '@', + marginLeft: '=', + marginRight: '=', + marginBottom:'=', + marginTop: '=', + xticks: '=', + yticks: '=' }, link: function(scope, element, attrs) { var margin = { - top: 20, - right: 20, - bottom: 30, - left: 80 + top: scope.marginTop || 20, + right: scope.marginRight || 20, + bottom: scope.marginBottom || 30, + left: scope.marginLeft || 80 }; + // default width/height - mainly to create initial aspect ratio var width = scope.width || 1280; var height = scope.height || 300; @@ -83,6 +90,15 @@ angular.module('dangle') .scale(y) .orient('left'); + //set the number of ticks if specified + if(scope.xticks) { + xAxis.ticks(scope.xticks); + } + + if(scope.yticks) { + yAxis.ticks(scope.yticks); + } + // create line generator var line = d3.svg.line() .x(function(d) { return x(d.time); }) From 4f62360c20fb7eb90c955972c05bae258cc4cad5 Mon Sep 17 00:00:00 2001 From: Gareth James Date: Wed, 7 Aug 2013 19:25:10 +0100 Subject: [PATCH 3/5] version number increments --- bower.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bower.json b/bower.json index 320abb3..f9c6cd7 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "dangle", - "version": "1.0.0", + "version": "1.1.0", "main": "src/dangle.module.js", "ignore": [ "**/.*", diff --git a/package.json b/package.json index 9fcc6ba..1428558 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dangle", "description": "A set of AngularJS directives that provide common visualizations for elasticsearch based on D3", - "version": "1.0.0", + "version": "1.1.0", "homepage": "http://www.fullscale.co/dangle", "keywords": ["angularjs", "d3", "charts", "graphs", "elasticsearch"], "repository": { From 8768494c41ae7296d723d8698043c73097865c10 Mon Sep 17 00:00:00 2001 From: Gareth James Date: Thu, 8 Aug 2013 13:34:40 +0100 Subject: [PATCH 4/5] option to rotate the label with a default of true --- src/modules/area/area.js | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/modules/area/area.js b/src/modules/area/area.js index 6565c36..803f6f6 100644 --- a/src/modules/area/area.js +++ b/src/modules/area/area.js @@ -68,6 +68,7 @@ angular.module('dangle') var interpolate = attrs.interpolate || 'false'; var label = attrs.label || 'Frequency'; + var rotateLabel = attrs.rotateLabel || 'true'; var klass = attrs.class || ''; // add margins (make room for x,y labels) @@ -136,16 +137,24 @@ angular.module('dangle') .attr('transform', 'translate(0,' + height + ')') .call(xAxis); - // insert the x axis (no data yet) - svg.append('g') + var axis = svg.append('g') .attr('class', 'area y axis ' + klass) .call(yAxis) - .append('text') - .attr('transform', 'rotate(-90)') - .attr('y', 6) - .attr('dy', '.71em') - .style('text-anchor', 'end') - .text(label); + .append('text') + .attr('dy', '.71em') + .text(label); + // insert the y axis (no data yet) + if(rotateLabel == 'true') { + axis + .attr('transform', 'rotate(-90)') + .attr('y', 6) + .style('text-anchor', 'end') + } else { + axis + .attr('y', -10) + .attr('dy', '.71em') + } + // generate the line. Data is empty at link time svg.append('path') From 1f7a84cc3dc93c09495dce253d24a98314148d62 Mon Sep 17 00:00:00 2001 From: Gareth James Date: Thu, 8 Aug 2013 14:20:34 +0100 Subject: [PATCH 5/5] added tooltips to area --- bower.json | 2 +- css/dangle.css | 13 +++++++++++ package.json | 2 +- src/modules/area/area.js | 50 ++++++++++++++++++++++++++++++---------- 4 files changed, 53 insertions(+), 14 deletions(-) diff --git a/bower.json b/bower.json index f9c6cd7..2aacb14 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "dangle", - "version": "1.1.0", + "version": "1.1.1", "main": "src/dangle.module.js", "ignore": [ "**/.*", diff --git a/css/dangle.css b/css/dangle.css index 5dfd680..1b0c00c 100644 --- a/css/dangle.css +++ b/css/dangle.css @@ -53,4 +53,17 @@ fill: #000; stroke: none; font-size: 12px; +} + +.area-tooltip { + position: absolute; + text-align: left; + width: 150px; + height: 40px; + padding: 2px; + font: 12px sans-serif; + background: white; + border: 2px #959595 solid; + border-radius: 2px; + pointer-events: none; } \ No newline at end of file diff --git a/package.json b/package.json index 1428558..a97bdfe 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dangle", "description": "A set of AngularJS directives that provide common visualizations for elasticsearch based on D3", - "version": "1.1.0", + "version": "1.1.1", "homepage": "http://www.fullscale.co/dangle", "keywords": ["angularjs", "d3", "charts", "graphs", "elasticsearch"], "repository": { diff --git a/src/modules/area/area.js b/src/modules/area/area.js index 803f6f6..ef6b8e7 100644 --- a/src/modules/area/area.js +++ b/src/modules/area/area.js @@ -24,7 +24,7 @@ */ angular.module('dangle') - .directive('fsArea', [function() { + .directive('fsArea', ['$filter', function($filter) { 'use strict'; return { @@ -47,11 +47,14 @@ angular.module('dangle') marginBottom:'=', marginTop: '=', xticks: '=', - yticks: '=' + yticks: '=', + tooltips: '@' }, link: function(scope, element, attrs) { + var dateFilter = $filter('date'); + var margin = { top: scope.marginTop || 20, right: scope.marginRight || 20, @@ -70,6 +73,7 @@ angular.module('dangle') var label = attrs.label || 'Frequency'; var rotateLabel = attrs.rotateLabel || 'true'; var klass = attrs.class || ''; + var tooltips = attrs.tooltips || 'false'; // add margins (make room for x,y labels) width = width - margin.left - margin.right; @@ -82,7 +86,7 @@ angular.module('dangle') var y = d3.scale.linear() .range([height, 0]); - // create x,y axis + // create x,y axis var xAxis = d3.svg.axis() .scale(x) .orient('bottom'); @@ -100,7 +104,7 @@ angular.module('dangle') yAxis.ticks(scope.yticks); } - // create line generator + // create line generator var line = d3.svg.line() .x(function(d) { return x(d.time); }) .y(function(d) { return y(d.count); }); @@ -111,7 +115,7 @@ angular.module('dangle') .y0(height) .y1(function(d) { return y(d.count); }); - // enable interpolation if specified + // enable interpolation if specified if (attrs.interpolate == 'true') { line.interpolate('cardinal'); area.interpolate('cardinal'); @@ -162,6 +166,10 @@ angular.module('dangle') .attr('class', 'area line ' + klass) .attr("d", line); + var div = d3.select("body").append("div") + .attr("class", "area-tooltip") + .style("opacity", 0); + // main observer fn called when scope is updated. Data and scope vars are now bound scope.$watch('bind', function(data) { @@ -183,7 +191,7 @@ angular.module('dangle') x.domain(d3.extent(data, function(d) { return d.time; })); y.domain([0, d3.max(data, function(d) { return d.count; })]); - // create the transition + // create the transition var t = svg.transition().duration(duration); // feed the current data to our area/line generators @@ -197,13 +205,13 @@ angular.module('dangle') // using Math.random as (optional) key fn ensures old // data values are flushed and all new values inserted var points = svg.selectAll('circle') - .data(data.filter(function(d) { - return d.count; - }), function(d) { - return Math.random(); + .data(data.filter(function(d) { + return d.count; + }), function(d) { + return Math.random(); }); - // d3 enter fn binds each new value to a circle + // d3 enter fn binds each new value to a circle points.enter() .append('circle') .attr('class', 'area line points ' + klass) @@ -219,10 +227,28 @@ angular.module('dangle') .attr("r", pointRadius); // wire up any events (registers filter callback) - points.on('mousedown', function(d) { + points.on('mousedown', function(d) { scope.$apply(function() { (scope.onClick || angular.noop)(field, d.time); }); + }).on("mouseover", function(d) { + if(tooltips === 'true') { + div.transition() + .duration(200) + .style("opacity", .9); + div .html( + "" + dateFilter(new Date(d.time), "EEEE, MMM d, yyyy") + "" + + "
" + label + ":" + "" + d.count +"" + ) + .style("left", (d3.event.pageX) + "px") + .style("top", (d3.event.pageY - 28) + "px"); + } + }).on("mouseout", function(d) { + if(tooltips === 'true') { + div.transition() + .duration(100) + .style("opacity", .0); + } }); // d3 exit/remove flushes old values (removes old circles)