Skip to content

Commit

Permalink
Merge pull request #103 from palantir/dev
Browse files Browse the repository at this point in the history
Merge Dev into Master (ver. 0.1.2)
  • Loading branch information
jtlan committed Feb 17, 2014
2 parents af036b8 + d65870b commit 36c9617
Show file tree
Hide file tree
Showing 29 changed files with 6,719 additions and 215 deletions.
38 changes: 26 additions & 12 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@ module.exports = function(grunt) {
files: ["src/*.ts", "test/*.ts"]
},
watch: {
"options": {
livereload: true
},
"rebuild": {
"tasks": ["build:rebuild"],
"files": [
"Gruntfile.js",
"src/*.ts",
]
"tasks": ["compile"],
"files": ["src/*.ts"]
},
"tests": {
"tasks": ["ts:test", "tslint"],
Expand All @@ -75,21 +75,35 @@ module.exports = function(grunt) {
"tasks": ["ts:examples", "tslint"],
"files": ["examples/**.ts"]
}
},
blanket_mocha: {
all: ['tests.html'],
options: {
threshold: 60
}
},
connect: {
server: {
options: {
port: 7007,
livereload: true
}
}
}
});

require('load-grunt-tasks')(grunt);

// default task (this is what runs when a task isn't specified)
grunt.registerTask("default", "build");
grunt.registerTask("default", "launch");

grunt.registerTask("build",
[
"compile",
"watch"
]
);
grunt.registerTask("build" , ["compile", "watch"]);
grunt.registerTask("launch", ["connect", "build"]);
grunt.registerTask("compile",
["ts:dev", "ts:test", "ts:examples", "tslint", "concat:license"]
);

grunt.registerTask("test", ["blanket_mocha"]);

grunt.registerTask("watch-test", ["blanket_mocha", "watch:test"]);
};
5,437 changes: 5,437 additions & 0 deletions blanket_mocha.js

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
},
"devDependencies": {
"chai": "1.9.0",
"mocha": "1.17.1"
"mocha": "1.17.1",
"jQuery": "2.1.0",
"jquery.simulate": "1.2.0"
}
}
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@
"grunt-ts": "~1.6.4",
"tsd": "~0.5.5",
"bower": "~1.2.8",
"grunt-bower-task": "~0.3.4",
"grunt-tsd": "0.0.1",
"tslint": "~0.4.2",
"grunt-tslint": "~0.4.0",
"grunt-contrib-concat": "~0.3.0"
"grunt-contrib-concat": "~0.3.0",
"grunt-mocha-phantomjs": "~0.4.0",
"grunt-contrib-connect": "~0.6.0",
"grunt-blanket-mocha": "~0.4.0"
}
}
6 changes: 4 additions & 2 deletions src/axis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,14 @@ class Axis extends Component {

this.cachedScale = 1;
this.cachedTranslate = 0;
this.scale.registerListener(this.rescale.bind(this));
this.scale.registerListener(() => this.rescale());
}


public anchor(element: D3.Selection) {
super.anchor(element);
this.axisElement = this.element.append("g").classed("axis", true); // TODO: remove extraneous sub-element
return this;
}

private transformString(translate: number, scale: number) {
Expand All @@ -54,7 +55,7 @@ class Axis extends Component {
}

public render() {
if (this.orientation === "left") {this.axisElement.attr("transform", "translate(" + Axis.yWidth + ")");};
if (this.orientation === "left") {this.axisElement.attr("transform", "translate(" + Axis.yWidth + ", 0)");};
if (this.orientation === "top") {this.axisElement.attr("transform", "translate(0," + Axis.xHeight + ")");};
var domain = this.scale.domain();
var extent = Math.abs(domain[1] - domain[0]);
Expand Down Expand Up @@ -87,6 +88,7 @@ class Axis extends Component {
}
// chai.assert.operator(this.element.node().getBBox().height, '<=', height, "axis height is appropriate");
// chai.assert.operator(this.element.node().getBBox().width, '<=', width, "axis width is appropriate");
return this;
}

public rescale() {
Expand Down
26 changes: 17 additions & 9 deletions src/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ class Component {
public yAlignment = "TOP"; // TOP, CENTER, BOTTOM

public anchor(element: D3.Selection) {
if (element.node().childNodes.length > 0) {
throw new Error("Can't anchor to a non-empty element");
}
this.element = element;
if (this.clipPathEnabled) {this.generateClipPath();};
this.cssClasses.forEach((cssClass: string) => {
Expand All @@ -34,21 +37,23 @@ class Component {
this.hitBox = this.addBox("hit-box");
this.addBox("bounding-box");

this.hitBox.style("fill", "#ffffff").style("opacity", 0); // We need to set these so Chrome will register events
this.registeredInteractions.forEach((r) => r.anchor(this.hitBox));
return this;
}

public computeLayout(xOffset?: number, yOffset?: number, availableWidth?: number, availableHeight?: number) {
if (xOffset == null || yOffset == null || availableWidth == null || availableHeight == null) {
if (this.element == null) {
throw new Error("It's impossible to computeLayout before anchoring");
throw new Error("anchor must be called before computeLayout");
} else if (this.element.node().nodeName === "svg") {
// we are the root node, let's guess width and height for convenience
xOffset = 0;
yOffset = 0;
availableWidth = parseFloat(this.element.attr("width" ));
availableHeight = parseFloat(this.element.attr("height"));
} else {
throw new Error("You need to pass non-null arguments when calling computeLayout on a non-root node");
throw new Error("null arguments cannot be passed to computeLayout() on a non-root (non-<svg>) node");
}
}
if (this.rowWeight() === 0 && this.rowMinimum() !== 0) {
Expand All @@ -62,7 +67,7 @@ class Component {
yOffset += availableHeight - this.rowMinimum();
break;
default:
throw new Error("unsupported alignment");
throw new Error(this.yAlignment + " is not a supported alignment");
}
availableHeight = this.rowMinimum();
}
Expand All @@ -77,7 +82,7 @@ class Component {
xOffset += availableWidth - this.colMinimum();
break;
default:
throw new Error("unsupported alignment");
throw new Error(this.xAlignment + " is not a supported alignment");
}
availableWidth = this.colMinimum();
}
Expand All @@ -87,17 +92,24 @@ class Component {
this.availableHeight = availableHeight;
this.element.attr("transform", "translate(" + this.xOffset + "," + this.yOffset + ")");
this.boxes.forEach((b: D3.Selection) => b.attr("width", this.availableWidth).attr("height", this.availableHeight));
return this;
}

public render() {
//no-op
return this;
}

private addBox(className?: string, parentElement?: D3.Selection) {
if (this.element == null) {
throw new Error("Adding boxes before anchoring is currently disallowed");
}
var parentElement = parentElement == null ? this.element : parentElement;
var box = parentElement.append("rect");
if (className != null) {box.classed(className, true);};
this.boxes.push(box);
if (this.availableWidth != null && this.availableHeight != null) {
box.attr("width", this.availableWidth).attr("height", this.availableHeight);
}
return box;
}

Expand All @@ -120,10 +132,6 @@ class Component {
}
}

public zoom(translate, scale) {
this.render(); // if not overwritten, a zoom event just causes the component to rerender
}

public classed(cssClass: string): boolean;
public classed(cssClass: string, addClass: boolean): Component;
public classed(cssClass: string, addClass?:boolean): any {
Expand Down
22 changes: 22 additions & 0 deletions src/coordinator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
///<reference path="reference.ts" />

class ScaleDomainCoordinator {
/* This class is responsible for maintaining coordination between linked scales.
It registers event listeners for when one of its scales changes its domain. When the scale
does change its domain, it re-propogates the change to every linked scale.
*/
private rescaleInProgress = false;
constructor(private scales: Scale[]) {
this.scales.forEach((s) => s.registerListener((sx: Scale) => this.rescale(sx)));
}

public rescale(scale: Scale) {
if (this.rescaleInProgress) {
return;
}
this.rescaleInProgress = true;
var newDomain = scale.domain();
this.scales.forEach((s) => s.domain(newDomain));
this.rescaleInProgress = false;
}
}
17 changes: 8 additions & 9 deletions src/interaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ interface ZoomInfo {
}

class PanZoomInteraction extends Interaction {
private zoom;
private zoom: D3.Behavior.Zoom;
public renderers: Component[];
public xScale: QuantitiveScale;
public yScale: QuantitiveScale;
Expand All @@ -43,7 +43,7 @@ class PanZoomInteraction extends Interaction {
this.zoom = d3.behavior.zoom();
this.zoom.x(this.xScale.scale);
this.zoom.y(this.yScale.scale);
this.zoom.on("zoom", this.rerenderZoomed.bind(this));
this.zoom.on("zoom", () => this.rerenderZoomed());

this.registerWithComponent();
}
Expand All @@ -55,7 +55,7 @@ class PanZoomInteraction extends Interaction {

private rerenderZoomed() {
// HACKHACK since the d3.zoom.x modifies d3 scales and not our TS scales, and the TS scales have the
// event listener machinery, let's grab the domain out of hte d3 scale and pipe it back into the TS scale
// event listener machinery, let's grab the domain out of the d3 scale and pipe it back into the TS scale
var xDomain = this.xScale.scale.domain();
var yDomain = this.yScale.scale.domain();
this.xScale.domain(xDomain);
Expand Down Expand Up @@ -94,14 +94,14 @@ class AreaInteraction extends Interaction {
) {
super(rendererComponent);
this.dragBehavior = d3.behavior.drag();
this.dragBehavior.on("dragstart", this.dragstart.bind(this));
this.dragBehavior.on("drag", this.drag .bind(this));
this.dragBehavior.on("dragend", this.dragend .bind(this));
this.dragBehavior.on("dragstart", () => this.dragstart());
this.dragBehavior.on("drag", () => this.drag ());
this.dragBehavior.on("dragend", () => this.dragend ());
this.registerWithComponent();
}

private dragstart(){
this.dragBox.attr("height", 0).attr("width", 0);
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
Expand Down Expand Up @@ -136,8 +136,7 @@ class AreaInteraction extends Interaction {
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};
var dataArea = this.rendererComponent.invertXYSelectionArea(pixelArea);
var fullArea = {pixel: pixelArea, data: dataArea};
var fullArea = this.rendererComponent.invertXYSelectionArea(pixelArea);
if (this.areaCallback != null) {
this.areaCallback(fullArea);
}
Expand Down
Loading

0 comments on commit 36c9617

Please sign in to comment.