bmaplib.heatmap
Advanced tools
Comparing version 1.0.0 to 1.0.1
1481
index.js
(function (root, factory) { | ||
if (typeof exports === 'object') { | ||
module.exports = factory(); | ||
} else if (typeof define === 'function' && define.amd) { | ||
define(factory); | ||
} else { | ||
root.BMapLib = root.BMapLib || {}; | ||
root.BMapLib.Heatmap = root.BMapLib.Heatmap || factory(); | ||
} | ||
if (typeof exports === 'object') { | ||
module.exports = factory(); | ||
} else if (typeof define === 'function' && define.amd) { | ||
define(factory); | ||
} else { | ||
root.BMapLib = root.BMapLib || {}; | ||
root.BMapLib.Heatmap = root.BMapLib.Heatmap || factory(); | ||
} | ||
})(this, function() { | ||
function inherits (subClass, superClass, className) { | ||
var key, proto, | ||
selfProps = subClass.prototype, | ||
clazz = new Function(); | ||
function inherits (subClass, superClass, className) { | ||
var key, proto, | ||
selfProps = subClass.prototype, | ||
clazz = new Function(); | ||
clazz.prototype = superClass.prototype; | ||
proto = subClass.prototype = new clazz(); | ||
for (key in selfProps) { | ||
proto[key] = selfProps[key]; | ||
} | ||
subClass.prototype.constructor = subClass; | ||
subClass.superClass = superClass.prototype; | ||
clazz.prototype = superClass.prototype; | ||
proto = subClass.prototype = new clazz(); | ||
for (key in selfProps) { | ||
proto[key] = selfProps[key]; | ||
} | ||
subClass.prototype.constructor = subClass; | ||
subClass.superClass = superClass.prototype; | ||
// 类名标识,兼容Class的toString,基本没用 | ||
if ("string" == typeof className) { | ||
proto._className = className; | ||
} | ||
}; | ||
var heatmapFactory = (function(){ | ||
// 类名标识,兼容Class的toString,基本没用 | ||
if ("string" == typeof className) { | ||
proto._className = className; | ||
} | ||
}; | ||
var heatmapFactory = (function(){ | ||
// store object constructor | ||
// a heatmap contains a store | ||
// the store has to know about the heatmap in order to trigger heatmap updates when datapoints get added | ||
var store = function store(hmap){ | ||
// store object constructor | ||
// a heatmap contains a store | ||
// the store has to know about the heatmap in order to trigger heatmap updates when datapoints get added | ||
var store = function store(hmap){ | ||
var _ = { | ||
// data is a two dimensional array | ||
// a datapoint gets saved as data[point-x-value][point-y-value] | ||
// the value at [point-x-value][point-y-value] is the occurrence of the datapoint | ||
data: [], | ||
// tight coupling of the heatmap object | ||
heatmap: hmap | ||
}; | ||
// the max occurrence - the heatmaps radial gradient alpha transition is based on it | ||
this.max = 1; | ||
var _ = { | ||
// data is a two dimensional array | ||
// a datapoint gets saved as data[point-x-value][point-y-value] | ||
// the value at [point-x-value][point-y-value] is the occurrence of the datapoint | ||
data: [], | ||
// tight coupling of the heatmap object | ||
heatmap: hmap | ||
}; | ||
// the max occurrence - the heatmaps radial gradient alpha transition is based on it | ||
this.max = 1; | ||
this.get = function(key){ | ||
return _[key]; | ||
}; | ||
this.set = function(key, value){ | ||
_[key] = value; | ||
}; | ||
} | ||
this.get = function(key){ | ||
return _[key]; | ||
}; | ||
this.set = function(key, value){ | ||
_[key] = value; | ||
}; | ||
} | ||
store.prototype = { | ||
// function for adding datapoints to the store | ||
// datapoints are usually defined by x and y but could also contain a third parameter which represents the occurrence | ||
addDataPoint: function(x, y){ | ||
if(x < 0 || y < 0) | ||
return; | ||
store.prototype = { | ||
// function for adding datapoints to the store | ||
// datapoints are usually defined by x and y but could also contain a third parameter which represents the occurrence | ||
addDataPoint: function(x, y){ | ||
if(x < 0 || y < 0) | ||
return; | ||
var me = this, | ||
heatmap = me.get("heatmap"), | ||
data = me.get("data"); | ||
var me = this, | ||
heatmap = me.get("heatmap"), | ||
data = me.get("data"); | ||
if(!data[x]) | ||
data[x] = []; | ||
if(!data[x]) | ||
data[x] = []; | ||
if(!data[x][y]) | ||
data[x][y] = 0; | ||
if(!data[x][y]) | ||
data[x][y] = 0; | ||
// if count parameter is set increment by count otherwise by 1 | ||
data[x][y]+=(arguments.length<3)?1:arguments[2]; | ||
me.set("data", data); | ||
// do we have a new maximum? | ||
if(me.max < data[x][y]){ | ||
// max changed, we need to redraw all existing(lower) datapoints | ||
heatmap.get("actx").clearRect(0,0,heatmap.get("width"),heatmap.get("height")); | ||
me.setDataSet({ max: data[x][y], data: data }, true); | ||
return; | ||
} | ||
heatmap.drawAlpha(x, y, data[x][y], true); | ||
}, | ||
setDataSet: function(obj, internal){ | ||
var me = this, | ||
heatmap = me.get("heatmap"), | ||
data = [], | ||
d = obj.data, | ||
dlen = d.length; | ||
// clear the heatmap before the data set gets drawn | ||
heatmap.clear(); | ||
this.max = obj.max; | ||
// if a legend is set, update it | ||
heatmap.get("legend") && heatmap.get("legend").update(obj.max); | ||
if(internal != null && internal){ | ||
for(var one in d){ | ||
// jump over undefined indexes | ||
if(one === undefined) | ||
continue; | ||
for(var two in d[one]){ | ||
if(two === undefined) | ||
continue; | ||
// if both indexes are defined, push the values into the array | ||
heatmap.drawAlpha(one, two, d[one][two], false); | ||
} | ||
} | ||
}else{ | ||
while(dlen--){ | ||
var point = d[dlen]; | ||
heatmap.drawAlpha(point.x, point.y, point.count, false); | ||
if(!data[point.x]) | ||
data[point.x] = []; | ||
// if count parameter is set increment by count otherwise by 1 | ||
data[x][y]+=(arguments.length<3)?1:arguments[2]; | ||
me.set("data", data); | ||
// do we have a new maximum? | ||
if(me.max < data[x][y]){ | ||
// max changed, we need to redraw all existing(lower) datapoints | ||
heatmap.get("actx").clearRect(0,0,heatmap.get("width"),heatmap.get("height")); | ||
me.setDataSet({ max: data[x][y], data: data }, true); | ||
return; | ||
} | ||
heatmap.drawAlpha(x, y, data[x][y], true); | ||
}, | ||
setDataSet: function(obj, internal){ | ||
var me = this, | ||
heatmap = me.get("heatmap"), | ||
data = [], | ||
d = obj.data, | ||
dlen = d.length; | ||
// clear the heatmap before the data set gets drawn | ||
heatmap.clear(); | ||
this.max = obj.max; | ||
// if a legend is set, update it | ||
heatmap.get("legend") && heatmap.get("legend").update(obj.max); | ||
if(internal != null && internal){ | ||
for(var one in d){ | ||
// jump over undefined indexes | ||
if(one === undefined) | ||
continue; | ||
for(var two in d[one]){ | ||
if(two === undefined) | ||
continue; | ||
// if both indexes are defined, push the values into the array | ||
heatmap.drawAlpha(one, two, d[one][two], false); | ||
} | ||
} | ||
}else{ | ||
while(dlen--){ | ||
var point = d[dlen]; | ||
heatmap.drawAlpha(point.x, point.y, point.count, false); | ||
if(!data[point.x]) | ||
data[point.x] = []; | ||
if(!data[point.x][point.y]) | ||
data[point.x][point.y] = 0; | ||
if(!data[point.x][point.y]) | ||
data[point.x][point.y] = 0; | ||
data[point.x][point.y] = point.count; | ||
} | ||
} | ||
heatmap.colorize(); | ||
this.set("data", d); | ||
}, | ||
exportDataSet: function(){ | ||
var me = this, | ||
data = me.get("data"), | ||
exportData = []; | ||
data[point.x][point.y] = point.count; | ||
} | ||
} | ||
heatmap.colorize(); | ||
this.set("data", d); | ||
}, | ||
exportDataSet: function(){ | ||
var me = this, | ||
data = me.get("data"), | ||
exportData = []; | ||
for(var one in data){ | ||
// jump over undefined indexes | ||
if(one === undefined) | ||
continue; | ||
for(var two in data[one]){ | ||
if(two === undefined) | ||
continue; | ||
// if both indexes are defined, push the values into the array | ||
exportData.push({x: parseInt(one, 10), y: parseInt(two, 10), count: data[one][two]}); | ||
} | ||
} | ||
for(var one in data){ | ||
// jump over undefined indexes | ||
if(one === undefined) | ||
continue; | ||
for(var two in data[one]){ | ||
if(two === undefined) | ||
continue; | ||
// if both indexes are defined, push the values into the array | ||
exportData.push({x: parseInt(one, 10), y: parseInt(two, 10), count: data[one][two]}); | ||
} | ||
} | ||
return { max: me.max, data: exportData }; | ||
}, | ||
generateRandomDataSet: function(points){ | ||
var heatmap = this.get("heatmap"), | ||
w = heatmap.get("width"), | ||
h = heatmap.get("height"); | ||
var randomset = {}, | ||
max = Math.floor(Math.random()*1000+1); | ||
randomset.max = max; | ||
var data = []; | ||
while(points--){ | ||
data.push({x: Math.floor(Math.random()*w+1), y: Math.floor(Math.random()*h+1), count: Math.floor(Math.random()*max+1)}); | ||
} | ||
randomset.data = data; | ||
this.setDataSet(randomset); | ||
} | ||
}; | ||
return { max: me.max, data: exportData }; | ||
}, | ||
generateRandomDataSet: function(points){ | ||
var heatmap = this.get("heatmap"), | ||
w = heatmap.get("width"), | ||
h = heatmap.get("height"); | ||
var randomset = {}, | ||
max = Math.floor(Math.random()*1000+1); | ||
randomset.max = max; | ||
var data = []; | ||
while(points--){ | ||
data.push({x: Math.floor(Math.random()*w+1), y: Math.floor(Math.random()*h+1), count: Math.floor(Math.random()*max+1)}); | ||
} | ||
randomset.data = data; | ||
this.setDataSet(randomset); | ||
} | ||
}; | ||
var legend = function legend(config){ | ||
this.config = config; | ||
var legend = function legend(config){ | ||
this.config = config; | ||
var _ = { | ||
element: null, | ||
labelsEl: null, | ||
gradientCfg: null, | ||
ctx: null | ||
}; | ||
this.get = function(key){ | ||
return _[key]; | ||
}; | ||
this.set = function(key, value){ | ||
_[key] = value; | ||
}; | ||
this.init(); | ||
}; | ||
legend.prototype = { | ||
init: function(){ | ||
var me = this, | ||
config = me.config, | ||
title = config.title || "Legend", | ||
position = config.position, | ||
offset = config.offset || 10, | ||
gconfig = config.gradient, | ||
labelsEl = document.createElement("ul"), | ||
labelsHtml = "", | ||
grad, element, gradient, positionCss = ""; | ||
var _ = { | ||
element: null, | ||
labelsEl: null, | ||
gradientCfg: null, | ||
ctx: null | ||
}; | ||
this.get = function(key){ | ||
return _[key]; | ||
}; | ||
this.set = function(key, value){ | ||
_[key] = value; | ||
}; | ||
this.init(); | ||
}; | ||
legend.prototype = { | ||
init: function(){ | ||
var me = this, | ||
config = me.config, | ||
title = config.title || "Legend", | ||
position = config.position, | ||
offset = config.offset || 10, | ||
gconfig = config.gradient, | ||
labelsEl = document.createElement("ul"), | ||
labelsHtml = "", | ||
grad, element, gradient, positionCss = ""; | ||
me.processGradientObject(); | ||
// Positioning | ||
me.processGradientObject(); | ||
// Positioning | ||
// top or bottom | ||
if(position.indexOf('t') > -1){ | ||
positionCss += 'top:'+offset+'px;'; | ||
}else{ | ||
positionCss += 'bottom:'+offset+'px;'; | ||
} | ||
// top or bottom | ||
if(position.indexOf('t') > -1){ | ||
positionCss += 'top:'+offset+'px;'; | ||
}else{ | ||
positionCss += 'bottom:'+offset+'px;'; | ||
} | ||
// left or right | ||
if(position.indexOf('l') > -1){ | ||
positionCss += 'left:'+offset+'px;'; | ||
}else{ | ||
positionCss += 'right:'+offset+'px;'; | ||
} | ||
// left or right | ||
if(position.indexOf('l') > -1){ | ||
positionCss += 'left:'+offset+'px;'; | ||
}else{ | ||
positionCss += 'right:'+offset+'px;'; | ||
} | ||
element = document.createElement("div"); | ||
element.style.cssText = "border-radius:5px;position:absolute;"+positionCss+"font-family:Helvetica; width:256px;z-index:10000000000; background:rgba(255,255,255,1);padding:10px;border:1px solid black;margin:0;"; | ||
element.innerHTML = "<h3 style='padding:0;margin:0;text-align:center;font-size:16px;'>"+title+"</h3>"; | ||
// create gradient in canvas | ||
labelsEl.style.cssText = "position:relative;font-size:12px;display:block;list-style:none;list-style-type:none;margin:0;height:15px;"; | ||
element = document.createElement("div"); | ||
element.style.cssText = "border-radius:5px;position:absolute;"+positionCss+"font-family:Helvetica; width:256px;z-index:10000000000; background:rgba(255,255,255,1);padding:10px;border:1px solid black;margin:0;"; | ||
element.innerHTML = "<h3 style='padding:0;margin:0;text-align:center;font-size:16px;'>"+title+"</h3>"; | ||
// create gradient in canvas | ||
labelsEl.style.cssText = "position:relative;font-size:12px;display:block;list-style:none;list-style-type:none;margin:0;height:15px;"; | ||
// create gradient element | ||
gradient = document.createElement("div"); | ||
gradient.style.cssText = ["position:relative;display:block;width:256px;height:15px;border-bottom:1px solid black; background-image:url(",me.createGradientImage(),");"].join(""); | ||
// create gradient element | ||
gradient = document.createElement("div"); | ||
gradient.style.cssText = ["position:relative;display:block;width:256px;height:15px;border-bottom:1px solid black; background-image:url(",me.createGradientImage(),");"].join(""); | ||
element.appendChild(labelsEl); | ||
element.appendChild(gradient); | ||
me.set("element", element); | ||
me.set("labelsEl", labelsEl); | ||
element.appendChild(labelsEl); | ||
element.appendChild(gradient); | ||
me.set("element", element); | ||
me.set("labelsEl", labelsEl); | ||
me.update(1); | ||
}, | ||
processGradientObject: function(){ | ||
// create array and sort it | ||
var me = this, | ||
gradientConfig = this.config.gradient, | ||
gradientArr = []; | ||
me.update(1); | ||
}, | ||
processGradientObject: function(){ | ||
// create array and sort it | ||
var me = this, | ||
gradientConfig = this.config.gradient, | ||
gradientArr = []; | ||
for(var key in gradientConfig){ | ||
if(gradientConfig.hasOwnProperty(key)){ | ||
gradientArr.push({ stop: key, value: gradientConfig[key] }); | ||
} | ||
} | ||
gradientArr.sort(function(a, b){ | ||
return (a.stop - b.stop); | ||
}); | ||
gradientArr.unshift({ stop: 0, value: 'rgba(0,0,0,0)' }); | ||
for(var key in gradientConfig){ | ||
if(gradientConfig.hasOwnProperty(key)){ | ||
gradientArr.push({ stop: key, value: gradientConfig[key] }); | ||
} | ||
} | ||
gradientArr.sort(function(a, b){ | ||
return (a.stop - b.stop); | ||
}); | ||
gradientArr.unshift({ stop: 0, value: 'rgba(0,0,0,0)' }); | ||
me.set("gradientArr", gradientArr); | ||
}, | ||
createGradientImage: function(){ | ||
var me = this, | ||
gradArr = me.get("gradientArr"), | ||
length = gradArr.length, | ||
canvas = document.createElement("canvas"), | ||
ctx = canvas.getContext("2d"), | ||
grad; | ||
// the gradient in the legend including the ticks will be 256x15px | ||
canvas.width = "256"; | ||
canvas.height = "15"; | ||
me.set("gradientArr", gradientArr); | ||
}, | ||
createGradientImage: function(){ | ||
var me = this, | ||
gradArr = me.get("gradientArr"), | ||
length = gradArr.length, | ||
canvas = document.createElement("canvas"), | ||
ctx = canvas.getContext("2d"), | ||
grad; | ||
// the gradient in the legend including the ticks will be 256x15px | ||
canvas.width = "256"; | ||
canvas.height = "15"; | ||
grad = ctx.createLinearGradient(0,5,256,10); | ||
grad = ctx.createLinearGradient(0,5,256,10); | ||
for(var i = 0; i < length; i++){ | ||
grad.addColorStop(1/(length-1) * i, gradArr[i].value); | ||
} | ||
for(var i = 0; i < length; i++){ | ||
grad.addColorStop(1/(length-1) * i, gradArr[i].value); | ||
} | ||
ctx.fillStyle = grad; | ||
ctx.fillRect(0,5,256,10); | ||
ctx.strokeStyle = "black"; | ||
ctx.beginPath(); | ||
ctx.fillStyle = grad; | ||
ctx.fillRect(0,5,256,10); | ||
ctx.strokeStyle = "black"; | ||
ctx.beginPath(); | ||
for(var i = 0; i < length; i++){ | ||
ctx.moveTo(((1/(length-1)*i*256) >> 0)+.5, 0); | ||
ctx.lineTo(((1/(length-1)*i*256) >> 0)+.5, (i==0)?15:5); | ||
} | ||
ctx.moveTo(255.5, 0); | ||
ctx.lineTo(255.5, 15); | ||
ctx.moveTo(255.5, 4.5); | ||
ctx.lineTo(0, 4.5); | ||
ctx.stroke(); | ||
for(var i = 0; i < length; i++){ | ||
ctx.moveTo(((1/(length-1)*i*256) >> 0)+.5, 0); | ||
ctx.lineTo(((1/(length-1)*i*256) >> 0)+.5, (i==0)?15:5); | ||
} | ||
ctx.moveTo(255.5, 0); | ||
ctx.lineTo(255.5, 15); | ||
ctx.moveTo(255.5, 4.5); | ||
ctx.lineTo(0, 4.5); | ||
ctx.stroke(); | ||
// we re-use the context for measuring the legends label widths | ||
me.set("ctx", ctx); | ||
// we re-use the context for measuring the legends label widths | ||
me.set("ctx", ctx); | ||
return canvas.toDataURL(); | ||
}, | ||
getElement: function(){ | ||
return this.get("element"); | ||
}, | ||
update: function(max){ | ||
var me = this, | ||
gradient = me.get("gradientArr"), | ||
ctx = me.get("ctx"), | ||
labels = me.get("labelsEl"), | ||
labelText, labelsHtml = "", offset; | ||
return canvas.toDataURL(); | ||
}, | ||
getElement: function(){ | ||
return this.get("element"); | ||
}, | ||
update: function(max){ | ||
var me = this, | ||
gradient = me.get("gradientArr"), | ||
ctx = me.get("ctx"), | ||
labels = me.get("labelsEl"), | ||
labelText, labelsHtml = "", offset; | ||
for(var i = 0; i < gradient.length; i++){ | ||
for(var i = 0; i < gradient.length; i++){ | ||
labelText = max*gradient[i].stop >> 0; | ||
offset = (ctx.measureText(labelText).width/2) >> 0; | ||
labelText = max*gradient[i].stop >> 0; | ||
offset = (ctx.measureText(labelText).width/2) >> 0; | ||
if(i == 0){ | ||
offset = 0; | ||
} | ||
if(i == gradient.length-1){ | ||
offset *= 2; | ||
} | ||
labelsHtml += '<li style="position:absolute;left:'+(((((1/(gradient.length-1)*i*256) || 0)) >> 0)-offset+.5)+'px">'+labelText+'</li>'; | ||
} | ||
labels.innerHTML = labelsHtml; | ||
} | ||
}; | ||
if(i == 0){ | ||
offset = 0; | ||
} | ||
if(i == gradient.length-1){ | ||
offset *= 2; | ||
} | ||
labelsHtml += '<li style="position:absolute;left:'+(((((1/(gradient.length-1)*i*256) || 0)) >> 0)-offset+.5)+'px">'+labelText+'</li>'; | ||
} | ||
labels.innerHTML = labelsHtml; | ||
} | ||
}; | ||
// heatmap object constructor | ||
var heatmap = function heatmap(config){ | ||
// private variables | ||
var _ = { | ||
radius : 40, | ||
element : {}, | ||
canvas : {}, | ||
acanvas: {}, | ||
ctx : {}, | ||
actx : {}, | ||
legend: null, | ||
visible : true, | ||
width : 0, | ||
height : 0, | ||
max : false, | ||
gradient : false, | ||
opacity: 180, | ||
premultiplyAlpha: false, | ||
bounds: { | ||
l: 1000, | ||
r: 0, | ||
t: 1000, | ||
b: 0 | ||
}, | ||
debug: false | ||
}; | ||
// heatmap store containing the datapoints and information about the maximum | ||
// accessible via instance.store | ||
this.store = new store(this); | ||
// heatmap object constructor | ||
var heatmap = function heatmap(config){ | ||
// private variables | ||
var _ = { | ||
radius : 40, | ||
element : {}, | ||
canvas : {}, | ||
acanvas: {}, | ||
ctx : {}, | ||
actx : {}, | ||
legend: null, | ||
visible : true, | ||
width : 0, | ||
height : 0, | ||
max : false, | ||
gradient : false, | ||
opacity: 180, | ||
premultiplyAlpha: false, | ||
bounds: { | ||
l: 1000, | ||
r: 0, | ||
t: 1000, | ||
b: 0 | ||
}, | ||
debug: false | ||
}; | ||
// heatmap store containing the datapoints and information about the maximum | ||
// accessible via instance.store | ||
this.store = new store(this); | ||
this.get = function(key){ | ||
return _[key]; | ||
}; | ||
this.set = function(key, value){ | ||
_[key] = value; | ||
}; | ||
// configure the heatmap when an instance gets created | ||
this.configure(config); | ||
// and initialize it | ||
this.init(); | ||
}; | ||
this.get = function(key){ | ||
return _[key]; | ||
}; | ||
this.set = function(key, value){ | ||
_[key] = value; | ||
}; | ||
// configure the heatmap when an instance gets created | ||
this.configure(config); | ||
// and initialize it | ||
this.init(); | ||
}; | ||
// public functions | ||
heatmap.prototype = { | ||
configure: function(config){ | ||
var me = this, | ||
rout, rin; | ||
// public functions | ||
heatmap.prototype = { | ||
configure: function(config){ | ||
var me = this, | ||
rout, rin; | ||
me.set("radius", config["radius"] || 40); | ||
me.set("element", (config.element instanceof Object)?config.element:document.getElementById(config.element)); | ||
me.set("visible", (config.visible != null)?config.visible:true); | ||
me.set("max", config.max || false); | ||
me.set("gradient", config.gradient || { 0.45: "rgb(0,0,255)", 0.55: "rgb(0,255,255)", 0.65: "rgb(0,255,0)", 0.95: "yellow", 1.0: "rgb(255,0,0)"}); // default is the common blue to red gradient | ||
me.set("opacity", parseInt(255/(100/config.opacity), 10) || 180); | ||
me.set("width", config.width || 0); | ||
me.set("height", config.height || 0); | ||
me.set("debug", config.debug); | ||
me.set("radius", config["radius"] || 40); | ||
me.set("element", (config.element instanceof Object)?config.element:document.getElementById(config.element)); | ||
me.set("visible", (config.visible != null)?config.visible:true); | ||
me.set("max", config.max || false); | ||
me.set("gradient", config.gradient || { 0.45: "rgb(0,0,255)", 0.55: "rgb(0,255,255)", 0.65: "rgb(0,255,0)", 0.95: "yellow", 1.0: "rgb(255,0,0)"}); // default is the common blue to red gradient | ||
me.set("opacity", parseInt(255/(100/config.opacity), 10) || 180); | ||
me.set("width", config.width || 0); | ||
me.set("height", config.height || 0); | ||
me.set("debug", config.debug); | ||
if(config.legend){ | ||
var legendCfg = config.legend; | ||
legendCfg.gradient = me.get("gradient"); | ||
me.set("legend", new legend(legendCfg)); | ||
} | ||
}, | ||
resize: function () { | ||
var me = this, | ||
element = me.get("element"), | ||
canvas = me.get("canvas"), | ||
acanvas = me.get("acanvas"); | ||
canvas.width = acanvas.width = me.get("width") || element.style.width.replace(/px/, "") || me.getWidth(element); | ||
this.set("width", canvas.width); | ||
canvas.height = acanvas.height = me.get("height") || element.style.height.replace(/px/, "") || me.getHeight(element); | ||
this.set("height", canvas.height); | ||
}, | ||
if(config.legend){ | ||
var legendCfg = config.legend; | ||
legendCfg.gradient = me.get("gradient"); | ||
me.set("legend", new legend(legendCfg)); | ||
} | ||
}, | ||
resize: function () { | ||
var me = this, | ||
element = me.get("element"), | ||
canvas = me.get("canvas"), | ||
acanvas = me.get("acanvas"); | ||
canvas.width = acanvas.width = me.get("width") || element.style.width.replace(/px/, "") || me.getWidth(element); | ||
this.set("width", canvas.width); | ||
canvas.height = acanvas.height = me.get("height") || element.style.height.replace(/px/, "") || me.getHeight(element); | ||
this.set("height", canvas.height); | ||
}, | ||
init: function(){ | ||
var me = this, | ||
canvas = document.createElement("canvas"), | ||
acanvas = document.createElement("canvas"), | ||
ctx = canvas.getContext("2d"), | ||
actx = acanvas.getContext("2d"), | ||
element = me.get("element"); | ||
init: function(){ | ||
var me = this, | ||
canvas = document.createElement("canvas"), | ||
acanvas = document.createElement("canvas"), | ||
ctx = canvas.getContext("2d"), | ||
actx = acanvas.getContext("2d"), | ||
element = me.get("element"); | ||
me.initColorPalette(); | ||
me.initColorPalette(); | ||
me.set("canvas", canvas); | ||
me.set("ctx", ctx); | ||
me.set("acanvas", acanvas); | ||
me.set("actx", actx); | ||
me.set("canvas", canvas); | ||
me.set("ctx", ctx); | ||
me.set("acanvas", acanvas); | ||
me.set("actx", actx); | ||
me.resize(); | ||
canvas.style.cssText = acanvas.style.cssText = "position:absolute;top:0;left:0;z-index:10000000;"; | ||
if(!me.get("visible")) | ||
canvas.style.display = "none"; | ||
me.resize(); | ||
canvas.style.cssText = acanvas.style.cssText = "position:absolute;top:0;left:0;z-index:10000000;"; | ||
if(!me.get("visible")) | ||
canvas.style.display = "none"; | ||
element.appendChild(canvas); | ||
if(me.get("legend")){ | ||
element.appendChild(me.get("legend").getElement()); | ||
} | ||
// debugging purposes only | ||
if(me.get("debug")) | ||
document.body.appendChild(acanvas); | ||
actx.shadowOffsetX = 15000; | ||
actx.shadowOffsetY = 15000; | ||
actx.shadowBlur = 15; | ||
}, | ||
initColorPalette: function(){ | ||
element.appendChild(canvas); | ||
if(me.get("legend")){ | ||
element.appendChild(me.get("legend").getElement()); | ||
} | ||
// debugging purposes only | ||
if(me.get("debug")) | ||
document.body.appendChild(acanvas); | ||
actx.shadowOffsetX = 15000; | ||
actx.shadowOffsetY = 15000; | ||
actx.shadowBlur = 15; | ||
}, | ||
initColorPalette: function(){ | ||
var me = this, | ||
canvas = document.createElement("canvas"), | ||
gradient = me.get("gradient"), | ||
ctx, grad, testData; | ||
var me = this, | ||
canvas = document.createElement("canvas"), | ||
gradient = me.get("gradient"), | ||
ctx, grad, testData; | ||
canvas.width = "1"; | ||
canvas.height = "256"; | ||
ctx = canvas.getContext("2d"); | ||
grad = ctx.createLinearGradient(0,0,1,256); | ||
canvas.width = "1"; | ||
canvas.height = "256"; | ||
ctx = canvas.getContext("2d"); | ||
grad = ctx.createLinearGradient(0,0,1,256); | ||
// Test how the browser renders alpha by setting a partially transparent pixel | ||
// and reading the result. A good browser will return a value reasonably close | ||
// to what was set. Some browsers (e.g. on Android) will return a ridiculously wrong value. | ||
testData = ctx.getImageData(0,0,1,1); | ||
testData.data[0] = testData.data[3] = 64; // 25% red & alpha | ||
testData.data[1] = testData.data[2] = 0; // 0% blue & green | ||
ctx.putImageData(testData, 0, 0); | ||
testData = ctx.getImageData(0,0,1,1); | ||
me.set("premultiplyAlpha", (testData.data[0] < 60 || testData.data[0] > 70)); | ||
for(var x in gradient){ | ||
grad.addColorStop(x, gradient[x]); | ||
} | ||
// Test how the browser renders alpha by setting a partially transparent pixel | ||
// and reading the result. A good browser will return a value reasonably close | ||
// to what was set. Some browsers (e.g. on Android) will return a ridiculously wrong value. | ||
testData = ctx.getImageData(0,0,1,1); | ||
testData.data[0] = testData.data[3] = 64; // 25% red & alpha | ||
testData.data[1] = testData.data[2] = 0; // 0% blue & green | ||
ctx.putImageData(testData, 0, 0); | ||
testData = ctx.getImageData(0,0,1,1); | ||
me.set("premultiplyAlpha", (testData.data[0] < 60 || testData.data[0] > 70)); | ||
for(var x in gradient){ | ||
grad.addColorStop(x, gradient[x]); | ||
} | ||
ctx.fillStyle = grad; | ||
ctx.fillRect(0,0,1,256); | ||
ctx.fillStyle = grad; | ||
ctx.fillRect(0,0,1,256); | ||
me.set("gradient", ctx.getImageData(0,0,1,256).data); | ||
}, | ||
getWidth: function(element){ | ||
var width = element.offsetWidth; | ||
if(element.style.paddingLeft){ | ||
width+=element.style.paddingLeft; | ||
} | ||
if(element.style.paddingRight){ | ||
width+=element.style.paddingRight; | ||
} | ||
me.set("gradient", ctx.getImageData(0,0,1,256).data); | ||
}, | ||
getWidth: function(element){ | ||
var width = element.offsetWidth; | ||
if(element.style.paddingLeft){ | ||
width+=element.style.paddingLeft; | ||
} | ||
if(element.style.paddingRight){ | ||
width+=element.style.paddingRight; | ||
} | ||
return width; | ||
}, | ||
getHeight: function(element){ | ||
var height = element.offsetHeight; | ||
if(element.style.paddingTop){ | ||
height+=element.style.paddingTop; | ||
} | ||
if(element.style.paddingBottom){ | ||
height+=element.style.paddingBottom; | ||
} | ||
return width; | ||
}, | ||
getHeight: function(element){ | ||
var height = element.offsetHeight; | ||
if(element.style.paddingTop){ | ||
height+=element.style.paddingTop; | ||
} | ||
if(element.style.paddingBottom){ | ||
height+=element.style.paddingBottom; | ||
} | ||
return height; | ||
}, | ||
colorize: function(x, y){ | ||
// get the private variables | ||
var me = this, | ||
width = me.get("width"), | ||
radius = me.get("radius"), | ||
height = me.get("height"), | ||
actx = me.get("actx"), | ||
ctx = me.get("ctx"), | ||
x2 = radius * 3, | ||
premultiplyAlpha = me.get("premultiplyAlpha"), | ||
palette = me.get("gradient"), | ||
opacity = me.get("opacity"), | ||
bounds = me.get("bounds"), | ||
left, top, bottom, right, | ||
image, length, alpha, offset, finalAlpha; | ||
if(x != null && y != null){ | ||
if(x+x2>width){ | ||
x=width-x2; | ||
} | ||
if(x<0){ | ||
x=0; | ||
} | ||
if(y<0){ | ||
y=0; | ||
} | ||
if(y+x2>height){ | ||
y=height-x2; | ||
} | ||
left = x; | ||
top = y; | ||
right = x + x2; | ||
bottom = y + x2; | ||
return height; | ||
}, | ||
colorize: function(x, y){ | ||
// get the private variables | ||
var me = this, | ||
width = me.get("width"), | ||
radius = me.get("radius"), | ||
height = me.get("height"), | ||
actx = me.get("actx"), | ||
ctx = me.get("ctx"), | ||
x2 = radius * 3, | ||
premultiplyAlpha = me.get("premultiplyAlpha"), | ||
palette = me.get("gradient"), | ||
opacity = me.get("opacity"), | ||
bounds = me.get("bounds"), | ||
left, top, bottom, right, | ||
image, length, alpha, offset, finalAlpha; | ||
if(x != null && y != null){ | ||
if(x+x2>width){ | ||
x=width-x2; | ||
} | ||
if(x<0){ | ||
x=0; | ||
} | ||
if(y<0){ | ||
y=0; | ||
} | ||
if(y+x2>height){ | ||
y=height-x2; | ||
} | ||
left = x; | ||
top = y; | ||
right = x + x2; | ||
bottom = y + x2; | ||
}else{ | ||
if(bounds['l'] < 0){ | ||
left = 0; | ||
}else{ | ||
left = bounds['l']; | ||
} | ||
if(bounds['r'] > width){ | ||
right = width; | ||
}else{ | ||
right = bounds['r']; | ||
} | ||
if(bounds['t'] < 0){ | ||
top = 0; | ||
}else{ | ||
top = bounds['t']; | ||
} | ||
if(bounds['b'] > height){ | ||
bottom = height; | ||
}else{ | ||
bottom = bounds['b']; | ||
} | ||
} | ||
}else{ | ||
if(bounds['l'] < 0){ | ||
left = 0; | ||
}else{ | ||
left = bounds['l']; | ||
} | ||
if(bounds['r'] > width){ | ||
right = width; | ||
}else{ | ||
right = bounds['r']; | ||
} | ||
if(bounds['t'] < 0){ | ||
top = 0; | ||
}else{ | ||
top = bounds['t']; | ||
} | ||
if(bounds['b'] > height){ | ||
bottom = height; | ||
}else{ | ||
bottom = bounds['b']; | ||
} | ||
} | ||
image = actx.getImageData(left, top, right-left, bottom-top); | ||
length = image.data.length; | ||
// loop thru the area | ||
for(var i=3; i < length; i+=4){ | ||
image = actx.getImageData(left, top, right-left, bottom-top); | ||
length = image.data.length; | ||
// loop thru the area | ||
for(var i=3; i < length; i+=4){ | ||
// [0] -> r, [1] -> g, [2] -> b, [3] -> alpha | ||
alpha = image.data[i], | ||
offset = alpha*4; | ||
// [0] -> r, [1] -> g, [2] -> b, [3] -> alpha | ||
alpha = image.data[i], | ||
offset = alpha*4; | ||
if(!offset) | ||
continue; | ||
if(!offset) | ||
continue; | ||
// we ve started with i=3 | ||
// set the new r, g and b values | ||
finalAlpha = (alpha < opacity)?alpha:opacity; | ||
image.data[i-3]=palette[offset]; | ||
image.data[i-2]=palette[offset+1]; | ||
image.data[i-1]=palette[offset+2]; | ||
if (premultiplyAlpha) { | ||
// we ve started with i=3 | ||
// set the new r, g and b values | ||
finalAlpha = (alpha < opacity)?alpha:opacity; | ||
image.data[i-3]=palette[offset]; | ||
image.data[i-2]=palette[offset+1]; | ||
image.data[i-1]=palette[offset+2]; | ||
if (premultiplyAlpha) { | ||
// To fix browsers that premultiply incorrectly, we'll pass in a value scaled | ||
@@ -555,280 +554,298 @@ // appropriately so when the multiplication happens the correct value will result. | ||
image.data[i-1] /= 255/finalAlpha; | ||
} | ||
// we want the heatmap to have a gradient from transparent to the colors | ||
// as long as alpha is lower than the defined opacity (maximum), we'll use the alpha value | ||
image.data[i] = finalAlpha; | ||
} | ||
// the rgb data manipulation didn't affect the ImageData object(defined on the top) | ||
// after the manipulation process we have to set the manipulated data to the ImageData object | ||
// image.data = imageData; | ||
ctx.putImageData(image, left, top); | ||
}, | ||
drawAlpha: function(x, y, count, colorize){ | ||
// storing the variables because they will be often used | ||
var me = this, | ||
radius = me.get("radius"), | ||
ctx = me.get("actx"), | ||
max = me.get("max"), | ||
bounds = me.get("bounds"), | ||
xb = x - (1.5 * radius) >> 0, yb = y - (1.5 * radius) >> 0, | ||
xc = x + (1.5 * radius) >> 0, yc = y + (1.5 * radius) >> 0; | ||
} | ||
// we want the heatmap to have a gradient from transparent to the colors | ||
// as long as alpha is lower than the defined opacity (maximum), we'll use the alpha value | ||
image.data[i] = finalAlpha; | ||
} | ||
// the rgb data manipulation didn't affect the ImageData object(defined on the top) | ||
// after the manipulation process we have to set the manipulated data to the ImageData object | ||
// image.data = imageData; | ||
ctx.putImageData(image, left, top); | ||
}, | ||
drawAlpha: function(x, y, count, colorize){ | ||
// storing the variables because they will be often used | ||
var me = this, | ||
radius = me.get("radius"), | ||
ctx = me.get("actx"), | ||
max = me.get("max"), | ||
bounds = me.get("bounds"), | ||
xb = x - (1.5 * radius) >> 0, yb = y - (1.5 * radius) >> 0, | ||
xc = x + (1.5 * radius) >> 0, yc = y + (1.5 * radius) >> 0; | ||
ctx.shadowColor = ('rgba(0,0,0,'+((count)?(count/me.store.max):'0.1')+')'); | ||
ctx.shadowColor = ('rgba(0,0,0,'+((count)?(count/me.store.max):'0.1')+')'); | ||
ctx.shadowOffsetX = 15000; | ||
ctx.shadowOffsetY = 15000; | ||
ctx.shadowBlur = 15; | ||
ctx.shadowOffsetX = 15000; | ||
ctx.shadowOffsetY = 15000; | ||
ctx.shadowBlur = 15; | ||
ctx.beginPath(); | ||
ctx.arc(x - 15000, y - 15000, radius, 0, Math.PI * 2, true); | ||
ctx.closePath(); | ||
ctx.fill(); | ||
if(colorize){ | ||
// finally colorize the area | ||
me.colorize(xb,yb); | ||
}else{ | ||
// or update the boundaries for the area that then should be colorized | ||
if(xb < bounds["l"]){ | ||
bounds["l"] = xb; | ||
} | ||
if(yb < bounds["t"]){ | ||
bounds["t"] = yb; | ||
} | ||
if(xc > bounds['r']){ | ||
bounds['r'] = xc; | ||
} | ||
if(yc > bounds['b']){ | ||
bounds['b'] = yc; | ||
} | ||
} | ||
}, | ||
toggleDisplay: function(){ | ||
var me = this, | ||
visible = me.get("visible"), | ||
canvas = me.get("canvas"); | ||
ctx.beginPath(); | ||
ctx.arc(x - 15000, y - 15000, radius, 0, Math.PI * 2, true); | ||
ctx.closePath(); | ||
ctx.fill(); | ||
if(colorize){ | ||
// finally colorize the area | ||
me.colorize(xb,yb); | ||
}else{ | ||
// or update the boundaries for the area that then should be colorized | ||
if(xb < bounds["l"]){ | ||
bounds["l"] = xb; | ||
} | ||
if(yb < bounds["t"]){ | ||
bounds["t"] = yb; | ||
} | ||
if(xc > bounds['r']){ | ||
bounds['r'] = xc; | ||
} | ||
if(yc > bounds['b']){ | ||
bounds['b'] = yc; | ||
} | ||
} | ||
}, | ||
toggleDisplay: function(){ | ||
var me = this, | ||
visible = me.get("visible"), | ||
canvas = me.get("canvas"); | ||
if(!visible) | ||
canvas.style.display = "block"; | ||
else | ||
canvas.style.display = "none"; | ||
if(!visible) | ||
canvas.style.display = "block"; | ||
else | ||
canvas.style.display = "none"; | ||
me.set("visible", !visible); | ||
}, | ||
// dataURL export | ||
getImageData: function(){ | ||
return this.get("canvas").toDataURL(); | ||
}, | ||
clear: function(){ | ||
var me = this, | ||
w = me.get("width"), | ||
h = me.get("height"); | ||
me.set("visible", !visible); | ||
}, | ||
// dataURL export | ||
getImageData: function(){ | ||
return this.get("canvas").toDataURL(); | ||
}, | ||
clear: function(){ | ||
var me = this, | ||
w = me.get("width"), | ||
h = me.get("height"); | ||
me.store.set("data",[]); | ||
// @TODO: reset stores max to 1 | ||
//me.store.max = 1; | ||
me.get("ctx").clearRect(0,0,w,h); | ||
me.get("actx").clearRect(0,0,w,h); | ||
}, | ||
cleanup: function(){ | ||
var me = this; | ||
me.get("element").removeChild(me.get("canvas")); | ||
} | ||
}; | ||
me.store.set("data",[]); | ||
// @TODO: reset stores max to 1 | ||
//me.store.max = 1; | ||
me.get("ctx").clearRect(0,0,w,h); | ||
me.get("actx").clearRect(0,0,w,h); | ||
}, | ||
cleanup: function(){ | ||
var me = this; | ||
me.get("element").removeChild(me.get("canvas")); | ||
} | ||
}; | ||
return { | ||
create: function(config){ | ||
return new heatmap(config); | ||
}, | ||
util: { | ||
mousePosition: function(ev){ | ||
// this doesn't work right | ||
// rather use | ||
/* | ||
// this = element to observe | ||
var x = ev.pageX - this.offsetLeft; | ||
var y = ev.pageY - this.offsetTop; | ||
return { | ||
create: function(config){ | ||
return new heatmap(config); | ||
}, | ||
util: { | ||
mousePosition: function(ev){ | ||
// this doesn't work right | ||
// rather use | ||
/* | ||
// this = element to observe | ||
var x = ev.pageX - this.offsetLeft; | ||
var y = ev.pageY - this.offsetTop; | ||
*/ | ||
var x, y; | ||
*/ | ||
var x, y; | ||
if (ev.layerX) { // Firefox | ||
x = ev.layerX; | ||
y = ev.layerY; | ||
} else if (ev.offsetX) { // Opera | ||
x = ev.offsetX; | ||
y = ev.offsetY; | ||
} | ||
if(typeof(x)=='undefined') | ||
return; | ||
if (ev.layerX) { // Firefox | ||
x = ev.layerX; | ||
y = ev.layerY; | ||
} else if (ev.offsetX) { // Opera | ||
x = ev.offsetX; | ||
y = ev.offsetY; | ||
} | ||
if(typeof(x)=='undefined') | ||
return; | ||
return [x,y]; | ||
} | ||
} | ||
}; | ||
})(); | ||
return [x,y]; | ||
} | ||
} | ||
}; | ||
})(); | ||
var HeatmapOverlay = function(opts) { | ||
try { | ||
BMap; | ||
} catch (e) { | ||
throw Error('Baidu Map JS API is not ready yet!'); | ||
} | ||
inherits(HeatmapOverlay, BMap.Overlay, "HeatmapOverlay"); | ||
// HeatmapOverlay.prototype = new BMap.Overlay(); | ||
this.conf = opts; | ||
this.heatmap = null; | ||
this.latlngs = []; | ||
this.bounds = null; | ||
} | ||
var HeatmapOverlay = function(opts) { | ||
try { | ||
BMap; | ||
} catch (e) { | ||
throw Error('Baidu Map JS API is not ready yet!'); | ||
} | ||
inherits(HeatmapOverlay, BMap.Overlay, "HeatmapOverlay"); | ||
// HeatmapOverlay.prototype = new BMap.Overlay(); | ||
this.conf = opts; | ||
this.heatmap = null; | ||
this.latlngs = []; | ||
this.bounds = null; | ||
this._moveendHandler = this._moveendHandler.bind(this); | ||
} | ||
HeatmapOverlay.prototype.initialize = function(map) { | ||
this._map = map; | ||
var el = document.createElement("div"); | ||
el.style.position = "absolute"; | ||
el.style.top = 0; | ||
el.style.left = 0; | ||
el.style.border = 0; | ||
el.style.width = this._map.getSize().width + "px"; | ||
el.style.height = this._map.getSize().height + "px"; | ||
this.conf.element = el; | ||
map.getPanes().mapPane.appendChild(el); | ||
this.heatmap = heatmapFactory.create(this.conf); | ||
this._div = el; | ||
return el; | ||
} | ||
HeatmapOverlay.prototype.initialize = function(map) { | ||
this._map = map; | ||
var el = document.createElement("div"); | ||
el.style.position = "absolute"; | ||
el.style.top = 0; | ||
el.style.left = 0; | ||
el.style.border = 0; | ||
el.style.width = this._map.getSize().width + "px"; | ||
el.style.height = this._map.getSize().height + "px"; | ||
this.conf.element = el; | ||
map.getPanes().mapPane.appendChild(el); | ||
this.heatmap = heatmapFactory.create(this.conf); | ||
this._div = el; | ||
return el; | ||
} | ||
HeatmapOverlay.prototype.draw = function() { | ||
var currentBounds = this._map.getBounds(); | ||
HeatmapOverlay.prototype.draw = function() { | ||
var currentBounds = this._map.getBounds(); | ||
if (currentBounds.equals(this.bounds)) { | ||
return; | ||
} | ||
this.bounds = currentBounds; | ||
if (currentBounds.equals(this.bounds)) { | ||
return; | ||
} | ||
this.bounds = currentBounds; | ||
var ne = this._map.pointToOverlayPixel(currentBounds.getNorthEast()), | ||
sw = this._map.pointToOverlayPixel(currentBounds.getSouthWest()), | ||
topY = ne.y, | ||
leftX = sw.x, | ||
h = sw.y - ne.y, | ||
w = ne.x - sw.x; | ||
var ne = this._map.pointToOverlayPixel(currentBounds.getNorthEast()), | ||
sw = this._map.pointToOverlayPixel(currentBounds.getSouthWest()); | ||
if (!ne || !sw) { | ||
return | ||
} | ||
var topY = ne.y, | ||
leftX = sw.x, | ||
h = sw.y - ne.y, | ||
w = ne.x - sw.x; | ||
this.conf.element.style.left = leftX + 'px'; | ||
this.conf.element.style.top = topY + 'px'; | ||
this.conf.element.style.width = w + 'px'; | ||
this.conf.element.style.height = h + 'px'; | ||
this.heatmap.store.get("heatmap").resize(); | ||
this.conf.element.style.left = leftX + 'px'; | ||
this.conf.element.style.top = topY + 'px'; | ||
this.conf.element.style.width = w + 'px'; | ||
this.conf.element.style.height = h + 'px'; | ||
this.heatmap.store.get("heatmap").resize(); | ||
if (this.latlngs.length > 0) { | ||
this.heatmap.clear(); | ||
if (this.latlngs.length > 0) { | ||
this.heatmap.clear(); | ||
var len = this.latlngs.length; | ||
var d = { | ||
max: this.heatmap.store.max, | ||
data: [] | ||
}; | ||
var len = this.latlngs.length; | ||
var d = { | ||
max: this.heatmap.store.max, | ||
data: [] | ||
}; | ||
while (len--) { | ||
var latlng = this.latlngs[len].latlng; | ||
while (len--) { | ||
var latlng = this.latlngs[len].latlng; | ||
if (!currentBounds.containsPoint(latlng)) { | ||
continue; | ||
} | ||
if (!currentBounds.containsPoint(latlng)) { | ||
continue; | ||
} | ||
var divPixel = this._map.pointToOverlayPixel(latlng), | ||
screenPixel = new BMap.Pixel(divPixel.x - leftX, divPixel.y - topY); | ||
var roundedPoint = this.pixelTransform(screenPixel); | ||
d.data.push({ | ||
x: roundedPoint.x, | ||
y: roundedPoint.y, | ||
count: this.latlngs[len].c | ||
}); | ||
} | ||
this.heatmap.store.setDataSet(d); | ||
} | ||
} | ||
var divPixel = this._map.pointToOverlayPixel(latlng), | ||
screenPixel = new BMap.Pixel(divPixel.x - leftX, divPixel.y - topY); | ||
var roundedPoint = this.pixelTransform(screenPixel); | ||
d.data.push({ | ||
x: roundedPoint.x, | ||
y: roundedPoint.y, | ||
count: this.latlngs[len].c | ||
}); | ||
} | ||
this.heatmap.store.setDataSet(d); | ||
} | ||
} | ||
HeatmapOverlay.prototype.pixelTransform = function(p) { | ||
var w = this.heatmap.get("width"), | ||
h = this.heatmap.get("height"); | ||
HeatmapOverlay.prototype.pixelTransform = function(p) { | ||
var w = this.heatmap.get("width"), | ||
h = this.heatmap.get("height"); | ||
while (p.x < 0) { | ||
p.x += w; | ||
} | ||
while (p.x < 0) { | ||
p.x += w; | ||
} | ||
while (p.x > w) { | ||
p.x -= w; | ||
} | ||
while (p.x > w) { | ||
p.x -= w; | ||
} | ||
while (p.y < 0) { | ||
p.y += h; | ||
} | ||
while (p.y < 0) { | ||
p.y += h; | ||
} | ||
while (p.y > h) { | ||
p.y -= h; | ||
} | ||
while (p.y > h) { | ||
p.y -= h; | ||
} | ||
p.x = (p.x >> 0); | ||
p.y = (p.y >> 0); | ||
p.x = (p.x >> 0); | ||
p.y = (p.y >> 0); | ||
return p; | ||
} | ||
return p; | ||
} | ||
HeatmapOverlay.prototype.setDataSet = function(data) { | ||
if (!this._map) { | ||
return; | ||
} | ||
var currentBounds = this._map.getBounds(); | ||
var mapdata = { | ||
max: data.max, | ||
data: [] | ||
}; | ||
var d = data.data, | ||
dlen = d.length; | ||
HeatmapOverlay.prototype._moveendHandler = function (e) { | ||
this.setDataSet(this._data); | ||
delete this._data; | ||
this._map.removeEventListener('moveend', this._moveendHandler); | ||
} | ||
HeatmapOverlay.prototype.setDataSet = function(data) { | ||
if (!this._map) { | ||
return; | ||
} | ||
var currentBounds = this._map.getBounds(); | ||
this.latlngs = []; | ||
var ne = this._map.pointToOverlayPixel(currentBounds.getNorthEast()), | ||
sw = this._map.pointToOverlayPixel(currentBounds.getSouthWest()); | ||
if (!ne || !sw) { | ||
this._data = data | ||
this._map.addEventListener('moveend', this._moveendHandler); | ||
} | ||
while (dlen--) { | ||
var latlng = new BMap.Point(d[dlen].lng, d[dlen].lat); | ||
if (!currentBounds.containsPoint(latlng)) { | ||
continue; | ||
} | ||
this.latlngs.push({ | ||
latlng: latlng, | ||
c: d[dlen].count | ||
}); | ||
var mapdata = { | ||
max: data.max, | ||
data: [] | ||
}; | ||
var d = data.data, | ||
dlen = d.length; | ||
var divPixel = this._map.pointToOverlayPixel(latlng), | ||
leftX = this._map.pointToOverlayPixel(currentBounds.getSouthWest()).x, | ||
topY = this._map.pointToOverlayPixel(currentBounds.getNorthEast()).y, | ||
screenPixel = new BMap.Pixel(divPixel.x - leftX, divPixel.y - topY); | ||
var point = this.pixelTransform(screenPixel); | ||
mapdata.data.push({ | ||
x: point.x, | ||
y: point.y, | ||
count: d[dlen].count | ||
}); | ||
} | ||
this.heatmap.clear(); | ||
this.heatmap.store.setDataSet(mapdata); | ||
} | ||
this.latlngs = []; | ||
HeatmapOverlay.prototype.addDataPoint = function(lng, lat, count) { | ||
var latlng = new BMap.Point(lng, lat), | ||
point = this.pixelTransform(this._map.pointToOverlayPixel(latlng)); | ||
while (dlen--) { | ||
var latlng = new BMap.Point(d[dlen].lng, d[dlen].lat); | ||
if (!currentBounds.containsPoint(latlng)) { | ||
continue; | ||
} | ||
this.latlngs.push({ | ||
latlng: latlng, | ||
c: d[dlen].count | ||
}); | ||
this.heatmap.store.addDataPoint(point.x, point.y, count); | ||
this.latlngs.push({ | ||
latlng: latlng, | ||
c: count | ||
}); | ||
} | ||
var divPixel = this._map.pointToOverlayPixel(latlng), | ||
leftX = this._map.pointToOverlayPixel(currentBounds.getSouthWest()).x, | ||
topY = this._map.pointToOverlayPixel(currentBounds.getNorthEast()).y, | ||
screenPixel = new BMap.Pixel(divPixel.x - leftX, divPixel.y - topY); | ||
var point = this.pixelTransform(screenPixel); | ||
HeatmapOverlay.prototype.toggle = function() { | ||
this.heatmap.toggleDisplay(); | ||
} | ||
mapdata.data.push({ | ||
x: point.x, | ||
y: point.y, | ||
count: d[dlen].count | ||
}); | ||
} | ||
this.heatmap.clear(); | ||
this.heatmap.store.setDataSet(mapdata); | ||
} | ||
return HeatmapOverlay; | ||
HeatmapOverlay.prototype.addDataPoint = function(lng, lat, count) { | ||
var latlng = new BMap.Point(lng, lat), | ||
point = this.pixelTransform(this._map.pointToOverlayPixel(latlng)); | ||
this.heatmap.store.addDataPoint(point.x, point.y, count); | ||
this.latlngs.push({ | ||
latlng: latlng, | ||
c: count | ||
}); | ||
} | ||
HeatmapOverlay.prototype.toggle = function() { | ||
this.heatmap.toggleDisplay(); | ||
} | ||
return HeatmapOverlay; | ||
}); |
{ | ||
"name": "bmaplib.heatmap", | ||
"version": "1.0.0", | ||
"version": "1.0.1", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Found 1 instance in 1 package
34449
5
738
1
40