diff --git a/quicktests/quicktest-selection.html b/quicktests/quicktest-selection.html
new file mode 100644
index 0000000000..a32845393c
--- /dev/null
+++ b/quicktests/quicktest-selection.html
@@ -0,0 +1,79 @@
+
+
+ Selection Quicktest
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/interactions/areaInteraction.ts b/src/interactions/areaInteraction.ts
deleted file mode 100644
index 97440fa994..0000000000
--- a/src/interactions/areaInteraction.ts
+++ /dev/null
@@ -1,100 +0,0 @@
-///
-
-module Plottable {
- export class AreaInteraction extends Interaction {
- private static CLASS_DRAG_BOX = "drag-box";
- private dragInitialized = false;
- private dragBehavior: D3.Behavior.Drag;
- private origin = [0,0];
- private location = [0,0];
- private constrainX: (n: number) => number;
- private constrainY: (n: number) => number;
- private dragBox: D3.Selection;
- private callbackToCall: (area: SelectionArea) => any;
-
- /**
- * Creates an AreaInteraction.
- *
- * @param {Component} componentToListenTo The component to listen for interactions on.
- */
- constructor(componentToListenTo: Component) {
- super(componentToListenTo);
- this.dragBehavior = d3.behavior.drag();
- this.dragBehavior.on("dragstart", () => this.dragstart());
- this.dragBehavior.on("drag", () => this.drag ());
- this.dragBehavior.on("dragend", () => this.dragend ());
- }
-
- /**
- * Adds a callback to be called when the AreaInteraction triggers.
- *
- * @param {(a: SelectionArea) => any} cb The function to be called. Takes in a SelectionArea in pixels.
- * @returns {AreaInteraction} The calling AreaInteraction.
- */
- public callback(cb?: (a: SelectionArea) => any): AreaInteraction {
- this.callbackToCall = cb;
- return this;
- }
-
- private dragstart(){
- this.clearBox();
- var availableWidth = parseFloat(this.hitBox.attr("width"));
- var availableHeight = parseFloat(this.hitBox.attr("height"));
- // the constraint functions ensure that the selection rectangle will not exceed the hit box
- var constraintFunction = (min: number, max: number) => (x: number) => Math.min(Math.max(x, min), max);
- this.constrainX = constraintFunction(0, availableWidth);
- this.constrainY = constraintFunction(0, availableHeight);
- }
-
- private drag(){
- if (!this.dragInitialized) {
- this.origin = [d3.event.x, d3.event.y];
- this.dragInitialized = true;
- }
-
- this.location = [this.constrainX(d3.event.x), this.constrainY(d3.event.y)];
- var width = Math.abs(this.origin[0] - this.location[0]);
- var height = Math.abs(this.origin[1] - this.location[1]);
- var x = Math.min(this.origin[0], this.location[0]);
- var y = Math.min(this.origin[1], this.location[1]);
- this.dragBox.attr("x", x).attr("y", y).attr("height", height).attr("width", width);
- }
-
- private dragend(){
- if (!this.dragInitialized) {
- return;
- }
-
- this.dragInitialized = false;
- if (this.callbackToCall == null) {
- return;
- }
-
- var xMin = Math.min(this.origin[0], this.location[0]);
- var xMax = Math.max(this.origin[0], this.location[0]);
- var yMin = Math.min(this.origin[1], this.location[1]);
- var yMax = Math.max(this.origin[1], this.location[1]);
- var pixelArea = {xMin: xMin, xMax: xMax, yMin: yMin, yMax: yMax};
- this.callbackToCall(pixelArea);
- }
-
- /**
- * Clears the highlighted drag-selection box drawn by the AreaInteraction.
- *
- * @returns {AreaInteraction} The calling AreaInteraction.
- */
- public clearBox(): AreaInteraction {
- this.dragBox.attr("height", 0).attr("width", 0);
- return this;
- }
-
- public _anchor(hitBox: D3.Selection): AreaInteraction {
- super._anchor(hitBox);
- var cname = AreaInteraction.CLASS_DRAG_BOX;
- var background = this.componentToListenTo.backgroundContainer;
- this.dragBox = background.append("rect").classed(cname, true).attr("x", 0).attr("y", 0);
- hitBox.call(this.dragBehavior);
- return this;
- }
- }
-}
diff --git a/src/interactions/drag/dragBoxInteraction.ts b/src/interactions/drag/dragBoxInteraction.ts
new file mode 100644
index 0000000000..3b4430a858
--- /dev/null
+++ b/src/interactions/drag/dragBoxInteraction.ts
@@ -0,0 +1,31 @@
+///
+
+module Plottable {
+ export class DragBoxInteraction extends DragInteraction {
+ private static CLASS_DRAG_BOX = "drag-box";
+ public dragBox: D3.Selection;
+
+ public _dragstart() {
+ super._dragstart();
+ this.clearBox();
+ }
+
+ /**
+ * Clears the highlighted drag-selection box drawn by the AreaInteraction.
+ *
+ * @returns {AreaInteraction} The calling AreaInteraction.
+ */
+ public clearBox() {
+ this.dragBox.attr("height", 0).attr("width", 0);
+ return this;
+ }
+
+ public _anchor(hitBox: D3.Selection) {
+ super._anchor(hitBox);
+ var cname = DragBoxInteraction.CLASS_DRAG_BOX;
+ var background = this.componentToListenTo.backgroundContainer;
+ this.dragBox = background.append("rect").classed(cname, true).attr("x", 0).attr("y", 0);
+ return this;
+ }
+ }
+}
diff --git a/src/interactions/drag/dragInteraction.ts b/src/interactions/drag/dragInteraction.ts
new file mode 100644
index 0000000000..3f56e9e1f9
--- /dev/null
+++ b/src/interactions/drag/dragInteraction.ts
@@ -0,0 +1,77 @@
+///
+
+module Plottable {
+ export class DragInteraction extends Interaction {
+ private dragInitialized = false;
+ private dragBehavior: D3.Behavior.Drag;
+ public origin = [0,0];
+ public location = [0,0];
+ private constrainX: (n: number) => number;
+ private constrainY: (n: number) => number;
+ public callbackToCall: (dragInfo: any) => any;
+
+ /**
+ * Creates a DragInteraction.
+ *
+ * @param {Component} componentToListenTo The component to listen for interactions on.
+ */
+ constructor(componentToListenTo: Component) {
+ super(componentToListenTo);
+ this.dragBehavior = d3.behavior.drag();
+ this.dragBehavior.on("dragstart", () => this._dragstart());
+ this.dragBehavior.on("drag", () => this._drag ());
+ this.dragBehavior.on("dragend", () => this._dragend ());
+ }
+
+ /**
+ * Adds a callback to be called when the AreaInteraction triggers.
+ *
+ * @param {(a: SelectionArea) => any} cb The function to be called. Takes in a SelectionArea in pixels.
+ * @returns {AreaInteraction} The calling AreaInteraction.
+ */
+ public callback(cb?: (a: any) => any) {
+ this.callbackToCall = cb;
+ return this;
+ }
+
+ public _dragstart(){
+ var availableWidth = this.componentToListenTo.availableWidth;
+ var availableHeight = this.componentToListenTo.availableHeight;
+ // the constraint functions ensure that the selection rectangle will not exceed the hit box
+ var constraintFunction = (min: number, max: number) => (x: number) => Math.min(Math.max(x, min), max);
+ this.constrainX = constraintFunction(0, availableWidth);
+ this.constrainY = constraintFunction(0, availableHeight);
+ }
+
+ public _drag(){
+ if (!this.dragInitialized) {
+ this.origin = [d3.event.x, d3.event.y];
+ this.dragInitialized = true;
+ }
+
+ this.location = [this.constrainX(d3.event.x), this.constrainY(d3.event.y)];
+ }
+
+ public _dragend(){
+ if (!this.dragInitialized) {
+ return;
+ }
+ this.dragInitialized = false;
+ this._doDragend();
+ }
+
+ public _doDragend() {
+ // seperated out so it can be over-ridden by dragInteractions that want to pass out diff information
+ // eg just x values for an xSelectionInteraction
+ if (this.callbackToCall != null) {
+ this.callbackToCall([this.origin, this.location]);
+ }
+ }
+
+ public _anchor(hitBox: D3.Selection) {
+ super._anchor(hitBox);
+ hitBox.call(this.dragBehavior);
+ return this;
+ }
+ }
+}
diff --git a/src/interactions/drag/xDragBoxInteraction.ts b/src/interactions/drag/xDragBoxInteraction.ts
new file mode 100644
index 0000000000..91c6618b0e
--- /dev/null
+++ b/src/interactions/drag/xDragBoxInteraction.ts
@@ -0,0 +1,24 @@
+///
+
+module Plottable {
+ export class XDragBoxInteraction extends DragBoxInteraction {
+ public _drag(){
+ super._drag();
+ var width = Math.abs(this.origin[0] - this.location[0]);
+ var height = this.componentToListenTo.availableHeight;
+ var x = Math.min(this.origin[0] , this.location[0]);
+ var y = 0
+ this.dragBox.attr({x: x, y: y, height: height, width: width});
+ }
+
+ public _doDragend(){
+ if (this.callbackToCall == null) {
+ return;
+ }
+ var xMin = Math.min(this.origin[0], this.location[0]);
+ var xMax = Math.max(this.origin[0], this.location[0]);
+ var pixelArea = {xMin: xMin, xMax: xMax};
+ this.callbackToCall(pixelArea);
+ }
+ }
+}
diff --git a/src/interactions/drag/xyDragBoxInteraction.ts b/src/interactions/drag/xyDragBoxInteraction.ts
new file mode 100644
index 0000000000..f39b1d9381
--- /dev/null
+++ b/src/interactions/drag/xyDragBoxInteraction.ts
@@ -0,0 +1,27 @@
+///
+
+module Plottable {
+ export class XYDragBoxInteraction extends DragBoxInteraction {
+ public _drag(){
+ super._drag();
+ var width = Math.abs(this.origin[0] - this.location[0]);
+ var height = Math.abs(this.origin[1] - this.location[1]);
+ var x = Math.min(this.origin[0] , this.location[0]);
+ var y = Math.min(this.origin[1] , this.location[1]);
+ this.dragBox.attr({x: x, y: y, height: height, width: width});
+ }
+
+ public _doDragend(){
+ if (this.callbackToCall == null) {
+ return;
+ }
+
+ var xMin = Math.min(this.origin[0], this.location[0]);
+ var xMax = Math.max(this.origin[0], this.location[0]);
+ var yMin = Math.min(this.origin[1], this.location[1]);
+ var yMax = Math.max(this.origin[1], this.location[1]);
+ var pixelArea = {xMin: xMin, xMax: xMax, yMin: yMin, yMax: yMax};
+ this.callbackToCall(pixelArea);
+ }
+ }
+}
diff --git a/src/reference.ts b/src/reference.ts
index 49675cebee..c0b9c624a6 100644
--- a/src/reference.ts
+++ b/src/reference.ts
@@ -33,10 +33,13 @@
///
///
-///
///
///
///
///
+///
+///
+///
+///
///
diff --git a/test/interactionTests.ts b/test/interactionTests.ts
index e17b55c103..a6d623a62a 100644
--- a/test/interactionTests.ts
+++ b/test/interactionTests.ts
@@ -20,12 +20,12 @@ function makeFakeEvent(x: number, y: number): D3.Event {
}
function fakeDragSequence(anyedInteraction: any, startX: number, startY: number, endX: number, endY: number) {
- anyedInteraction.dragstart();
+ anyedInteraction._dragstart();
d3.event = makeFakeEvent(startX, startY);
- anyedInteraction.drag();
+ anyedInteraction._drag();
d3.event = makeFakeEvent(endX, endY);
- anyedInteraction.drag();
- anyedInteraction.dragend();
+ anyedInteraction._drag();
+ anyedInteraction._dragend();
d3.event = null;
}
@@ -78,7 +78,7 @@ describe("Interactions", () => {
});
});
- describe("AreaInteraction", () => {
+ describe("XYDragBoxInteraction", () => {
var svgWidth = 400;
var svgHeight = 400;
var svg: D3.Selection;
@@ -86,7 +86,7 @@ describe("Interactions", () => {
var xScale: Plottable.QuantitiveScale;
var yScale: Plottable.QuantitiveScale;
var renderer: Plottable.XYRenderer;
- var interaction: Plottable.AreaInteraction;
+ var interaction: Plottable.XYDragBoxInteraction;
var dragstartX = 20;
var dragstartY = svgHeight-100;
@@ -100,12 +100,13 @@ describe("Interactions", () => {
yScale = new Plottable.LinearScale();
renderer = new Plottable.CircleRenderer(dataset, xScale, yScale);
renderer.renderTo(svg);
- interaction = new Plottable.AreaInteraction(renderer);
+ interaction = new Plottable.XYDragBoxInteraction(renderer);
interaction.registerWithComponent();
});
afterEach(() => {
- interaction.callback().clearBox();
+ interaction.callback();
+ interaction.clearBox();
});
it("All callbacks are notified with appropriate data when a drag finishes", () => {
@@ -132,7 +133,7 @@ describe("Interactions", () => {
it("Highlights and un-highlights areas appropriately", () => {
fakeDragSequence(( interaction), dragstartX, dragstartY, dragendX, dragendY);
- var dragBoxClass = "." + ( Plottable.AreaInteraction).CLASS_DRAG_BOX;
+ var dragBoxClass = "." + ( Plottable.XYDragBoxInteraction).CLASS_DRAG_BOX;
var dragBox = renderer.backgroundContainer.select(dragBoxClass);
assert.isNotNull(dragBox, "the dragbox was created");
var actualStartPosition = {x: parseFloat(dragBox.attr("x")), y: parseFloat(dragBox.attr("y"))};