Skip to content

Instantly share code, notes, and snippets.

@andygup
Created April 23, 2014 16:09
Show Gist options
  • Save andygup/11221619 to your computer and use it in GitHub Desktop.
Save andygup/11221619 to your computer and use it in GitHub Desktop.
An old example js cluster layer with flaring
dojo.require("dojox.lang.functional");
dojo.require("dojox.lang.functional.lambda");
dojo.require("dojox.lang.functional.curry");
dojo.require("dojox.lang.functional.fold");
dojo.declare("esri.ux.layers.ClusterLayer", esri.layers.GraphicsLayer, {
constructor: function (a) {
if (typeof Object.create === "undefined") {
Object.create = function (d) {
function c() {}
c.prototype = d;
return new c()
}
}
this.displayOnPan = a.displayOnPan || false;
this._map = a.map;
this._dojoMap = a.dojoMap;
this.zoomhandler = dojo.connect(this._map, "onZoomStart", dojo.hitch(this, this.handleMapZoomStart));
this.handleMapExtentChange = dojo.connect(this._map, "onExtentChange", dojo.hitch(this, this.handleMapExtentChange));
this.spatialReference = new esri.SpatialReference({
wkid: 102100
});
this.initialExtent = (this.fullExtent = new esri.geometry.Extent(-20037507.0671618, -19971868.8804086, 20037507.0671618, 19971868.8804086, this.spatialReference));
this.levelPointTileSpace = [];
this._features = [];
try {
this.setFeatures(a.features)
} catch (b) {}
dojo.connect(this, "onLoad", this.handleLayerLoaded);
dojo.connect(this, "onMouseOver", this.handleMouseOver);
dojo.connect(this, "onMouseOut", this.handleMouseOut);
dojo.connect(this, "onMouseClick", this.handleMouseClick);
this.symbolBank = a.symbolBank;
this._flareDistanceFromCenter = a.flareDistanceFromCenter || 20;
this._flareLimit = a.flareLimit || 20;
this._infoTemplate = a.infoWindow.template || null;
this._infoWindowWidth = a.infoWindow.width || 150;
this._infoWindowHeight = a.infoWindow.height || 100;
this.loaded = true;
this.onLoad(this)
},
handleMapZoomStart: function () {
this.clear()
},
handleMapExtentChange: function (b, d, a, c) {
this.clusterFeatures()
},
setFeatures: function (a) {
this._features = [];
var b = a[0].geometry.spatialReference.wkid;
if (b != 102100) {
if (b == 4326 || b == 4269 || b == 4267) {
dojo.forEach(a, function (c) {
point = esri.geometry.geographicToWebMercator(c.geometry);
point.attributes = c.attributes;
this._features.push(point)
}, this)
} else {
throw "Input Spatial Reference Must Be in Either WKID: 102110 or WKID: 4326";
return
}
} else {
dojo.forEach(a, function (c) {
point = c.geometry;
point.attributes = c.attributes;
this._features.push(point)
}, this)
}
},
handleLayerLoaded: function (a) {
this.clusterFeatures()
},
disconnect: function () {
dojo.disconnect(this.zoomhandler);
dojo.disconnect(this.handleMapExtentChange)
},
handleMouseOver: function (m) {
this._map.infoWindow.hide();
var k = m.graphic;
if (k.symbol.type == "textsymbol" || k.symbol.type == "simplelinesymbol") {
if (k.attributes) {
if (k.attributes.baseGraphic && k.attributes.baseGraphic.task) {
k.attributes.baseGraphic.task.cancel()
}
}
return
}
if (k.attributes.isCluster) {
if (k.attributes.clustered) {
if (k.task) {
k.task.cancel()
}
return
}
} else {
if (k.attributes.baseGraphic) {
if (k.attributes.id) {
baseGraphic = k.attributes.baseGraphic;
var r = this._dojoMap.getContent(k.attributes, baseGraphic);
k.setAttributes(r);
k.attributes.baseGraphic.task.cancel()
}
} else {
if (k.attributes.id) {
var r = this._dojoMap.getContent(k.attributes, null);
k.setAttributes(r)
}
}
this.showInfoWindow(k);
return
}
k.clusterGraphics = [];
var w = k.attributes.clusterSize;
var d = new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([0, 0, 0, 1]), 1);
var h = new esri.geometry.Polyline(this._map.spatialReference);
h.addPath([k.geometry, new esri.geometry.Point(0, 0)]);
var c = new esri.Graphic(h, d);
if (w > 1 && w <= this._flareLimit) {
var A = k.attributes.clusterSize;
var a = this.getPixelDistanceFromCenter(k.geometry);
var t = k.geometry;
var z, b, g, e, o, f, n, s;
for (var v = 0; v < A; v++) {
z = Math.sin((Math.PI * 2) * (v / A));
b = Math.cos((Math.PI * 2) * (v / A));
g = t.x + a * b;
e = t.y + a * z;
o = new esri.geometry.Point(g, e, this._map.spatialReference);
var u;
if (this.symbolBank[k.attributes[v].Code] != null) {
u = this.symbolBank[k.attributes[v].Code]
} else {
u = this.symbolBank.single
}
f = new esri.Graphic(o, u, dojo.mixin(k.attributes[v], {
baseGraphic: k
}), this._infoTemplate);
var q = k.attributes[v];
var j = this.symbolBank.single;
if (typeof (q.color) != "undefined") {
console.log(q.color);
j = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_CIRCLE, 10, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color(q.color), 1), new dojo.Color(q.color))
}
f = new esri.Graphic(o, j, dojo.mixin(k.attributes[v], {
baseGraphic: k
}), this._infoTemplate);
n = this.add(f);
n.getDojoShape().moveToFront();
h.setPoint(0, 1, o);
c = new esri.Graphic(h, d, {
baseGraphic: k
});
s = this.add(c);
s.getDojoShape().moveToBack();
k.clusterGraphics.push(n);
k.clusterGraphics.push(s)
}
k.attributes.clustered = true
}
},
getPixelDistanceFromCenter: function (b) {
var e = this._flareDistanceFromCenter;
var c = esri.geometry.toScreenGeometry(this._map.extent, this._map.width, this._map.height, b);
c.x = c.x + e;
c.y = c.y + e;
var a = esri.geometry.toMapGeometry(this._map.extent, this._map.width, this._map.height, c);
var d = esri.geometry.getLength(b, a);
return d
},
handleMouseOut: function (a) {
var c = a.graphic,
b;
if (c.symbol.type == "textsymbol") {
return
}
if (c.attributes.isCluster) {
b = new DelayedTask(function (d) {
this.removeFlareGraphics(d.clusterGraphics);
delete d.clusterGraphics;
d.attributes.clustered = false
}, this, [c]);
b.delay(900);
c.task = b
} else {
if (c.attributes.baseGraphic) {
b = new DelayedTask(function (d) {
this.removeFlareGraphics(d.attributes.baseGraphic.clusterGraphics);
delete d.attributes.baseGraphic.clusterGraphics;
d.attributes.baseGraphic.attributes.clustered = false
}, this, [c]);
b.delay(900);
c.attributes.baseGraphic.task = b
}
}
},
handleMouseClick: function (a) {
var b = a.graphic;
this.keepinfowindow = true
},
removeFlareGraphics: function (a) {
if (a && a.length) {
for (var b = 0; b < a.length; b++) {
this.remove(a[b])
}
}
},
showInfoWindow: function (b) {
if (this._map.infoWindow.isShowing) {
this._map.infoWindow.hide()
}
this._map.infoWindow.setContent(b.getContent());
this._map.infoWindow.setTitle(b.getTitle());
this._map.infoWindow.resize(this._infoWindowWidth, this._infoWindowHeight);
var a = esri.geometry.toScreenGeometry(this._map.extent, this._map.width, this._map.height, b.geometry);
this._map.infoWindow.show(a, this._map.getInfoWindowAnchor(a))
},
clusterFeatures: function (q) {
try {
this.clear();
var t = dojox.lang.functional,
u = this._map,
a = this._map.getLevel() + 2,
l = this._map.extent;
var r = u.getLayer(u.layerIds[0]).tileInfo;
var p = t.lambda("point, tileWidth,tileHeight,oPoint -> [Math.floor((oPoint.y - point.y)/tileHeight),Math.floor((point.x-oPoint.x)/tileWidth), point]");
var d = customLods[a].resolution;
var o = d * r.width;
var m = d * r.height;
var j = t.partial(p, t.arg, o, m, r.origin);
var i = t.map([new esri.geometry.Point(l.xmin, l.ymin), new esri.geometry.Point(l.xmax, l.ymax)], j);
var g = i[1][0];
var b = i[0][0];
var f = i[0][1];
var n = i[1][1];
if (!this.levelPointTileSpace[a] || q) {
var h = t.map(this._features, j);
var c = [];
dojo.forEach(h, function (v, e) {
if (c[v[0]]) {
var w = c[v[0]];
if (w[v[1]]) {
w[v[1]].push(v[2])
} else {
w[v[1]] = v[1];
w[v[1]] = [v[2]]
}
} else {
var w = c[v[0]] = [];
w[v[1]] = v[1];
w[v[1]] = [v[2]]
}
});
this.levelPointTileSpace[a] = c
}
var k = t.lambda("cPt,nextPt->{x:(cPt.x+nextPt.x)/2,y:(cPt.y+nextPt.y)/2}");
dojo.forEach(this.levelPointTileSpace[a], function (e, v) {
if ((v >= g) & (v <= b)) {
dojo.forEach(e, function (y, E) {
if (y) {
if ((E >= f) & (E <= n)) {
var B = [];
if (y.length > 1) {
var z = t.reduce(y, k);
var w;
if (y.length <= 20) {
w = this.symbolBank.less16
} else {
if (y.length > 20 && y.length <= 30) {
w = this.symbolBank.less30
} else {
if (y.length > 30 && y.length <= 50) {
w = this.symbolBank.less50
} else {
w = this.symbolBank.over50
}
}
}
var A = dojo.map(y, function (F) {
return F.attributes
});
var D = dojo.mixin(A, {
isCluster: true,
clusterSize: y.length
});
if (y.length <= 1) {
var C = 12;
dojo.forEach(y, function (F) {
var G;
if (F.attributes.Code) {
G = Object.create(this.symbolBank[F.attributes.Code]);
G.size = G.size + C;
C = C - 4
}
this.add(new esri.Graphic(new esri.geometry.Point(z.x, z.y), G, D))
}, this)
} else {
this.add(new esri.Graphic(new esri.geometry.Point(z.x, z.y), w, D))
}
var x = new esri.symbol.Font("10pt", esri.symbol.Font.STYLE_NORMAL, esri.symbol.Font.VARIANT_NORMAL, esri.symbol.Font.WEIGHT_NORMAL, "Trebuchet MS");
this.add(new esri.Graphic(new esri.geometry.Point(z.x, z.y), new esri.symbol.TextSymbol(y.length, x, new dojo.Color("#000000")).setOffset(0, -5)))
} else {
dojo.forEach(y, function (F) {
var G;
if (F.attributes.Code) {
G = this.symbolBank[F.attributes.Code]
} else {
G = this.symbolBank.single
} if (F.attributes.color) {
G = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_CIRCLE, 10, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([0, 0, 0, 0]), 1), new dojo.Color(F.attributes.color))
}
this.add(new esri.Graphic(F, G, dojo.mixin(F.attributes, {
isCluster: false
}), this._infoTemplate))
}, this)
}
}
}
}, this)
}
}, this)
} catch (s) {
console.log(this.name)
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment