1 (function ($, undefined) {
3 var _ieVersion = (function () {
4 var v = 5, div = document.createElement("div"), a = div.all || [];
5 while (div.innerHTML = "<!--[if gt IE " + (++v) + "]><br><![endif]-->", a[0]) { }
9 $.widget("geo.geographics", {
19 _$labelsContainer: undefined,
32 visibility: "visible",
37 _create: function () {
38 this._$elem = this.element;
39 this._options = this.options;
41 this._$elem.css({ display: "inline-block", overflow: "hidden", textAlign: "left" });
43 if (this._$elem.css("position") == "static") {
44 this._$elem.css("position", "relative");
47 this._$elem.addClass( "geo-graphics" );
49 this._width = this._$elem.width();
50 this._height = this._$elem.height();
52 if (!(this._width && this._height)) {
53 this._width = parseInt(this._$elem.css("width"));
54 this._height = parseInt(this._$elem.css("height"));
57 var posCss = 'position:absolute;left:0;top:0;margin:0;padding:0;',
58 sizeCss = 'width:' + this._width + 'px;height:' + this._height + 'px;',
59 sizeAttr = 'width="' + this._width + '" height="' + this._height + '"';
61 if (document.createElement('canvas').getContext) {
62 this._$elem.append('<canvas ' + sizeAttr + ' style="' + posCss + '"></canvas>');
63 this._$canvas = this._$elem.children(':last');
64 this._context = this._$canvas[0].getContext("2d");
65 } else if (_ieVersion <= 8) {
66 this._trueCanvas = false;
67 this._$elem.append( '<div ' + sizeAttr + ' style="' + posCss + sizeCss + '"></div>');
68 this._$canvas = this._$elem.children(':last');
70 G_vmlCanvasManager.initElement(this._$canvas[0]);
71 this._context = this._$canvas[0].getContext("2d");
72 this._$canvas.children().css({ backgroundColor: "transparent", width: this._width, height: this._height });
75 this._$elem.append('<div class="geo-labels-container" style="' + posCss + sizeCss + '"></div>');
76 this._$labelsContainer = this._$elem.children(':last');
79 _setOption: function (key, value) {
81 value = $.extend({}, this._options.style, value);
83 $.Widget.prototype._setOption.apply(this, arguments);
86 destroy: function () {
87 $.Widget.prototype.destroy.apply(this, arguments);
89 this._$elem.removeClass( "geo-graphics" );
93 this._context.clearRect(0, 0, this._width, this._height);
94 this._$labelsContainer.html("");
97 drawArc: function (coordinates, startAngle, sweepAngle, style) {
98 style = this._getGraphicStyle(style);
100 if (style.visibility != "hidden" && style.opacity > 0 && style.widthValue > 0 && style.heightValue > 0) {
101 var r = Math.min(style.widthValue, style.heightValue) / 2;
103 startAngle = (startAngle * Math.PI / 180);
104 sweepAngle = (sweepAngle * Math.PI / 180);
106 this._context.save();
107 this._context.translate(coordinates[0], coordinates[1]);
108 if (style.widthValue > style.heightValue) {
109 this._context.scale(style.widthValue / style.heightValue, 1);
111 this._context.scale(1, style.heightValue / style.widthValue);
114 this._context.beginPath();
115 this._context.arc(0, 0, r, startAngle, sweepAngle, false);
117 if (this._trueCanvas) {
118 this._context.restore();
122 this._context.fillStyle = style.fill;
123 this._context.globalAlpha = style.opacity * style.fillOpacity;
124 this._context.fill();
127 if (style.doStroke) {
128 this._context.lineJoin = "round";
129 this._context.lineWidth = style.strokeWidthValue;
130 this._context.strokeStyle = style.stroke;
132 this._context.globalAlpha = style.opacity * style.strokeOpacity;
133 this._context.stroke();
136 if (!this._trueCanvas) {
137 this._context.restore();
142 drawPoint: function (coordinates, style) {
143 var style = this._getGraphicStyle(style);
144 if (style.widthValue == style.heightValue && style.heightValue == style.borderRadiusValue) {
145 this.drawArc(coordinates, 0, 360, style);
146 } else if (style.visibility != "hidden" && style.opacity > 0) {
147 style.borderRadiusValue = Math.min(Math.min(style.widthValue, style.heightValue) / 2, style.borderRadiusValue);
148 coordinates[0] -= style.widthValue / 2;
149 coordinates[1] -= style.heightValue / 2;
150 this._context.beginPath();
151 this._context.moveTo(coordinates[0] + style.borderRadiusValue, coordinates[1]);
152 this._context.lineTo(coordinates[0] + style.widthValue - style.borderRadiusValue, coordinates[1]);
153 this._context.quadraticCurveTo(coordinates[0] + style.widthValue, coordinates[1], coordinates[0] + style.widthValue, coordinates[1] + style.borderRadiusValue);
154 this._context.lineTo(coordinates[0] + style.widthValue, coordinates[1] + style.heightValue - style.borderRadiusValue);
155 this._context.quadraticCurveTo(coordinates[0] + style.widthValue, coordinates[1] + style.heightValue, coordinates[0] + style.widthValue - style.borderRadiusValue, coordinates[1] + style.heightValue);
156 this._context.lineTo(coordinates[0] + style.borderRadiusValue, coordinates[1] + style.heightValue);
157 this._context.quadraticCurveTo(coordinates[0], coordinates[1] + style.heightValue, coordinates[0], coordinates[1] + style.heightValue - style.borderRadiusValue);
158 this._context.lineTo(coordinates[0], coordinates[1] + style.borderRadiusValue);
159 this._context.quadraticCurveTo(coordinates[0], coordinates[1], coordinates[0] + style.borderRadiusValue, coordinates[1]);
160 this._context.closePath();
163 this._context.fillStyle = style.fill;
164 this._context.globalAlpha = style.opacity * style.fillOpacity;
165 this._context.fill();
168 if (style.doStroke) {
169 this._context.lineJoin = "round";
170 this._context.lineWidth = style.strokeWidthValue;
171 this._context.strokeStyle = style.stroke;
173 this._context.globalAlpha = style.opacity * style.strokeOpacity;
175 this._context.stroke();
180 drawLineString: function (coordinates, style) {
181 this._drawLines([coordinates], false, style);
184 drawPolygon: function (coordinates, style) {
185 this._drawLines(coordinates, true, style);
188 drawBbox: function (bbox, style) {
198 drawLabel: function( coordinates, label ) {
199 this._$labelsContainer.append( '<div class="geo-label" style="position:absolute; left:' + coordinates[ 0 ] + 'px; top:' + coordinates[ 1 ] + 'px;">' + label + '</div>');
202 resize: function( ) {
203 this._width = this._$elem.width();
204 this._height = this._$elem.height();
206 if (!(this._width && this._height)) {
207 this._width = parseInt(this._$elem.css("width"));
208 this._height = parseInt(this._$elem.css("height"));
211 if ( this._trueCanvas ) {
212 this._$canvas[0].width = this._width;
213 this._$canvas[0].height = this._height;
217 this._$labelsContainer.css( {
223 _getGraphicStyle: function (style) {
224 function safeParse(value) {
225 value = parseInt(value);
226 return (+value + '') === value ? +value : value;
229 style = $.extend({}, this._options.style, style);
230 style.borderRadiusValue = safeParse(style.borderRadius);
231 style.fill = style.fill || style.color;
232 style.doFill = style.fill && style.fillOpacity > 0;
233 style.stroke = style.stroke || style.color;
234 style.strokeWidthValue = safeParse(style.strokeWidth);
235 style.doStroke = style.stroke && style.strokeOpacity > 0 && style.strokeWidthValue > 0;
236 style.widthValue = safeParse(style.width);
237 style.heightValue = safeParse(style.height);
241 _drawLines: function (coordinates, close, style) {
242 if (!coordinates || !coordinates.length || coordinates[0].length < 2) {
246 var style = this._getGraphicStyle(style),
249 if (style.visibility != "hidden" && style.opacity > 0) {
250 this._context.beginPath();
251 this._context.moveTo(coordinates[0][0][0], coordinates[0][0][1]);
253 for (i = 0; i < coordinates.length; i++) {
254 for (j = 0; j < coordinates[i].length; j++) {
255 this._context.lineTo(coordinates[i][j][0], coordinates[i][j][1]);
260 this._context.closePath();
263 if (close && style.doFill) {
264 this._context.fillStyle = style.fill;
265 this._context.globalAlpha = style.opacity * style.fillOpacity;
266 this._context.fill();
269 if (style.doStroke) {
270 this._context.lineCap = this._context.lineJoin = "round";
271 this._context.lineWidth = style.strokeWidthValue;
272 this._context.strokeStyle = style.stroke;
274 this._context.globalAlpha = style.opacity * style.strokeOpacity;
275 this._context.stroke();