From 14174136d839ec63df422d8614cbb97f6c639636 Mon Sep 17 00:00:00 2001 From: rolux Date: Sun, 29 May 2011 12:42:38 +0200 Subject: [PATCH] some support for async listmaps --- demos/listmap2/index.html | 3 +- demos/listmap2/js/listmap.js | 162 +++++++++++++++++++++++------- source/Ox.UI/js/Map/Ox.ListMap.js | 15 +-- 3 files changed, 136 insertions(+), 44 deletions(-) diff --git a/demos/listmap2/index.html b/demos/listmap2/index.html index 9454896e..5ddfb269 100644 --- a/demos/listmap2/index.html +++ b/demos/listmap2/index.html @@ -1,10 +1,9 @@ - ox.js listmap demoOxJS ListMap Demo (async) - diff --git a/demos/listmap2/js/listmap.js b/demos/listmap2/js/listmap.js index c6771c4b..5a2e812a 100644 --- a/demos/listmap2/js/listmap.js +++ b/demos/listmap2/js/listmap.js @@ -7,41 +7,123 @@ Ox.load('Geo', function() { Ox.getJSON('json/cities100000.json', function(cities) { - var listmap = new Ox.ListMap({ + var places = cities.map(function(city, i) { + var countryCode = city.country_code == 'XK' ? 'RS-KO' : city.country_code, + marker = city.population > 20000000 ? {size: 24, color: [255, 0, 0]} : + city.population > 10000000 ? {size: 22, color: [255, 32, 0]} : + city.population > 5000000 ? {size: 20, color: [255, 64, 0]} : + city.population > 2000000 ? {size: 18, color: [255, 96, 0]} : + city.population > 1000000 ? {size: 16, color: [255, 128, 0]} : + city.population > 500000 ? {size: 14, color: [255, 160, 0]} : + city.population > 200000 ? {size: 12, color: [255, 192, 0]} : + city.population > 100000 ? {size: 10, color: [255, 224, 0]} : + {size: 8, color: [255, 255, 0]}, + area = Math.sqrt(Math.max(city.population, 1) * 100), + latSize = area / Ox.EARTH_CIRCUMFERENCE * 360, + lngSize = area * Ox.getDegreesPerMeter(city.latitude); + return { + alternativeNames: [], + area: city.population * 100, + countryCode: countryCode, + editable: true, + flag: countryCode, + geoname: city.name + ', ' + Ox.getCountryByCode(countryCode).name, + geonameSort: getGeonameSort(city.name + ', ' + Ox.getCountryByCode(countryCode).name), + id: Ox.encodeBase32(i), + markerColor: marker.color, + markerSize: marker.size, + name: city.name, + type: 'city', + lat: city.latitude, + lng: city.longitude, + south: city.latitude - latSize / 2, + west: city.longitude - lngSize / 2, + north: city.latitude + latSize / 2, + east: city.longitude + lngSize / 2 + }; + }); + + var $listmap = new Ox.ListMap({ height: window.innerHeight, - places: Ox.map(cities, function(city, id) { - var countryCode = city.country_code == 'XK' ? 'RS-KO' : city.country_code, - marker = city.population > 20000000 ? {size: 24, color: [255, 0, 0]} : - city.population > 10000000 ? {size: 22, color: [255, 32, 0]} : - city.population > 5000000 ? {size: 20, color: [255, 64, 0]} : - city.population > 2000000 ? {size: 18, color: [255, 96, 0]} : - city.population > 1000000 ? {size: 16, color: [255, 128, 0]} : - city.population > 500000 ? {size: 14, color: [255, 160, 0]} : - city.population > 200000 ? {size: 12, color: [255, 192, 0]} : - city.population > 100000 ? {size: 10, color: [255, 224, 0]} : - {size: 8, color: [255, 255, 0]}, - area = Math.sqrt(city.population * 100), - latSize = area / Ox.EARTH_CIRCUMFERENCE * 360, - lngSize = area * Ox.getDegreesPerMeter(city.latitude); - return city.population > 400000/*400000*/ ? { - area: city.population * 100, - countryCode: countryCode, - editable: true, - flag: countryCode, - geoname: city.name + ', ' + Ox.getCountryByCode(countryCode).name, - id: Ox.encodeBase32(id), - markerColor: marker.color, - markerSize: marker.size, - name: city.name, - type: 'city', - lat: city.latitude, - lng: city.longitude, - south: city.latitude - latSize / 2, - west: city.longitude - lngSize / 2, - north: city.latitude + latSize / 2, - east: city.longitude + lngSize / 2 - } : null; - }), + places: function(options, callback) { + // this simulates a remote API + Ox.print('OPTIONS', options) + var data = {}; + // query, sort, range, area + if (Ox.isEmpty(options)) { + data = { + items: places.length, + south: 90, + west: 180, + north: -90, + east: -180 + }; + places.forEach(function(place) { + ['south', 'west', 'north', 'east'].forEach(function(v) { + if ( + ((v == 'south' || v == 'west') && place[v] < data[v]) + || ((v == 'north' || v == 'east') && place[v] > data[v]) + ) { + data[v] = place[v]; + } + }); + }); + } else { + data.items = places; + if (options.query) { + + } + if (options.area) { + data.items = data.items.filter(function(place) { + // fixme: fails if crosses dateline + return place.lat > options.area.south + && place.lat < options.area.north + && place.lng > options.area.west + && place.lng < options.area.east; + }); + } + data.items.sort(function(a, b) { + if (options.sort[0].key == 'geoname') { + aValue = a.geonameSort; + bValue = b.geonameSort; + } else { + aValue = a[options.sort[0].key]; + bValue = b[options.sort[0].key]; + } + var ret = 0; + if ( + (options.sort[0].operator == '+' && aValue < bValue) + || (options.sort[0].operator == '-' && aValue > bValue) + ) { + ret = -1; + } else if ( + (options.sort[0].operator == '+' && aValue > bValue) + || (options.sort[0].operator == '-' && aValue < bValue) + ) { + ret = 1; + } + return ret; + }); + if (options.ids) { + data.positions = {}; + data.items.forEach(function(place, i) { + if (options.ids.indexOf(place.id) > -1) { + data.positions[place.id] = i; + } + }); + delete data.items; + } else if (options.range) { + data.items = data.items.filter(function(place, i) { + return i >= options.range[0] && i < options.range[1]; + }); + } + } + Ox.print('DATA', data) + callback({ + data: data, + result: {code: 200, text: 'OK'} + }); + }, width: window.innerWidth }) .bindEvent({ @@ -54,13 +136,21 @@ Ox.load('Geo', function() { $(window).resize(function() { Ox.print('RESIZE', window.innerHeight) - listmap.options({ + $listmap.options({ height: window.innerHeight, width: window.innerWidth }); }); - window.listmap = listmap; + window.$listmap = $listmap; + + function getGeonameSort(geoname) { + var names = geoname.split(', '); + if (!Ox.getCountryByGeoname(names[names.length - 1])) { + names.push('~'); + } + return names.reverse().join(', '); + } }); diff --git a/source/Ox.UI/js/Map/Ox.ListMap.js b/source/Ox.UI/js/Map/Ox.ListMap.js index 1c62d8d9..cebdafcf 100644 --- a/source/Ox.UI/js/Map/Ox.ListMap.js +++ b/source/Ox.UI/js/Map/Ox.ListMap.js @@ -23,8 +23,10 @@ Ox.ListMap = function(options, self) { addPlace: null, height: 256, labels: false, + pageLength: 100, places: null, selected: [], + sort: [{key: 'geoname', operator: '+'}], width: 256 }) .addClass('OxListMap') @@ -34,6 +36,8 @@ Ox.ListMap = function(options, self) { height: self.options.height + 'px' }); + self.isAsync = Ox.isFunction(self.options.places); + self.columns = [ { addable: false, // fixme: implement @@ -243,11 +247,9 @@ Ox.ListMap = function(options, self) { columnsVisible: true, //items: Ox.clone(self.options.places), items: self.options.places, - pageLength: 100, + pageLength: self.options.pageLength, scrollbarVisible: true, - sort: [ - {key: 'name', operator: '+'} - ] + sort: self.options.sort }) .bindEvent({ 'delete': removeItem, @@ -455,7 +457,7 @@ Ox.ListMap = function(options, self) { ]; */ - if (Ox.isArray(self.options.places)) { + if (!self.isAsync) { init(self.options.places) } else { self.options.places({}, function(result) { @@ -464,7 +466,8 @@ Ox.ListMap = function(options, self) { keys: self.columns.map(function(column) { return column.id }), - range: [0, result.data.items] + range: [0, result.data.items], + sort: self.options.sort, }, function(result) { Ox.print('DATA', result) init(result.data.items);