Skip to content

Commit

Permalink
Object Manager added
Browse files Browse the repository at this point in the history
  • Loading branch information
PNKBizz committed Feb 7, 2018
1 parent 15c07ab commit 0b0347b
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 45 deletions.
14 changes: 14 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}\\vue-yandex-maps.js"
}
]
}
7 changes: 6 additions & 1 deletion README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ You can use the CDN: https://unpkg.com/vue-yandex-maps, `yandexMap` is exposed t

Use `<yandex-map>` tag to enable the map instance and use attributes to define map options.

`<yandex-map>` has a class `ymap-container` and child element with class `ymap-body`, where rendering map instance.
`<yandex-map>` has a class `ymap-container` and child element, where rendering map instance. Child class you may define through map attribute `ymap-class`. If you doesn't define this class - child element will have `style` attribute with `width: 100%; height: 100%;`

If you have a lot of markers on your map i strongly recommend you to use map attribute `useObjectManager`. But in this case you can't set callbacks to your markers through marker attribute `callbacks`.

You may define placemarks on your map by using `<ymap-marker>` tag or set an array of objects with placemark options through `<yandex-map>` attribute `placemarks` ([interface description](https://tech.yandex.ru/maps/doc/jsapi/2.0/ref/reference/GeoObject-docpage/)). You also can use both methods together.<br>
The Map instance rerender when changed array with markers in `placemarks` property or marker properties if marker is a component.<br>
Expand Down Expand Up @@ -155,6 +157,9 @@ data() {
| scroll-zoom | Boolean | Set to false to disable zoom map on scroll page |
| zoom-control | Object | Configs for zoomControl of the map. [More](https://tech.yandex.ru/maps/doc/jsapi/2.1/ref/reference/control.ZoomControl-docpage/) |
| placemarks | Array of Objects | Array of config objects with fields: coordinates ([lat, lon]), properties, options. [More](https://tech.yandex.ru/maps/doc/jsapi/2.1/ref/reference/Placemark-docpage/) |
| use-object-manager | Boolean | Defines using Object Mananger in map. Default: false |
| object-manager-clusterize | Boolean | Defines using clusterize in Object Mananger. Default: true |
| ymap-class | String | Defines class for element, where rendering map instance |

## Marker attributes

Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vue-yandex-maps",
"version": "0.6.10",
"version": "0.7.0",
"description": "Yandex Maps component for VueJS.",
"main": "vue-yandex-maps.js",
"jsnext:main": "./src/index.js",
Expand Down
8 changes: 6 additions & 2 deletions src/Marker.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { compareValues, emitter } from './utils';

export default {
data: () => ({
ymapEventBus: emitter
ymapEventBus: emitter,
unwatchArr: []
}),
props: {
coords: {
Expand Down Expand Up @@ -34,7 +35,10 @@ export default {
},
mounted() {
for (let prop in this.$props) {
this.$watch(prop, (newVal, oldVal) => compareValues(newVal, oldVal, this.ymapEventBus));
this.unwatchArr.push(this.$watch(prop, (newVal, oldVal) => compareValues(newVal, oldVal, this.ymapEventBus)));
}
},
beforeDestroy() {
this.unwatchArr.forEach(f => f());
}
}
59 changes: 31 additions & 28 deletions src/YMap.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ export default {
return {
ymapEventBus: utils.emitter,
ymapId: 'yandexMap' + Math.round(Math.random() * 100000),
myMap: {}
myMap: {},
style: this.ymapClass ? '' : 'width: 100%; height: 100%;'
}
},
props: {
Expand Down Expand Up @@ -65,7 +66,16 @@ export default {
default() {
return [];
}
}
},
useObjectManager: {
type: Boolean,
default: false
},
objectManagerClusterize: {
type: Boolean,
default: true
},
ymapClass: String
},
computed: {
coordinates() {
Expand All @@ -75,8 +85,8 @@ export default {
methods: {
init() {
if (!window.ymaps || !ymaps.GeoObjectCollection) return; // if ymap isn't initialized;
this.$emit('map-initialization-started');
let markers = [];
let myGeoObjects = new ymaps.GeoObjectCollection();

this.myMap = new ymaps.Map(this.ymapId, {
center: this.coordinates,
Expand Down Expand Up @@ -140,13 +150,14 @@ export default {
}
return marker
}).filter(marker => marker && marker.markerType) || [];

for (let i = 0; i < myMarkers.length; i++) {
const m = myMarkers[i];
const markerType = utils.setFirstLetterToUppercase(m.markerType);
const markerType = utils.createMarkerType(m.markerType, this.useObjectManager);
let properties = {
hintContent: m.hintContent,
iconContent: m.icon && m.icon.content,
markerId: m.markerId
};

const balloonProps = m.balloon ? {
Expand Down Expand Up @@ -183,42 +194,32 @@ export default {
if (markerType === 'Circle') {
m.coords = [m.coords, m.circleRadius];
}
let marker = new ymaps[markerType](m.coords, properties, options);
utils.createCallbacks(m, marker);
marker.clusterName = m.clusterName;

marker.properties.set('markerId', m.markerId);
const obj = { properties, options, markerType, coords: m.coords, clusterName: m.clusterName, callbacks: m.callbacks }
const marker = utils.createMarker(obj, this.useObjectManager);

markers.push(marker);
myGeoObjects.add(marker);
}

if (this.placemarks) {
this.placemarks.forEach(function(placemark) {
let yplacemark = new ymaps.Placemark (
placemark.coords,
placemark.properties || {},
placemark.options || {}
);

utils.createCallbacks(placemark, yplacemark);

if (placemark.clusterName) {
yplacemark.clusterName = placemark.clusterName;
markers.push(yplacemark);
}
const markerType = this.useObjectManager ? 'Point' : 'Placemark';
this.placemarks.forEach(placemark => {
const { properties, options, coords, clusterName, callbacks } = placemark;
const obj = { properties, options, markerType, coords, clusterName, callbacks }
let yplacemark = utils.createMarker(obj, this.useObjectManager);

myGeoObjects.add(yplacemark);
markers.push(yplacemark);
})
}

this.myMap.geoObjects.add(myGeoObjects);
const config = {
options: this.clusterOptions,
callbacks: this.clusterCallbacks,
map: this.myMap
map: this.myMap,
useObjectManager: this.useObjectManager,
objectManagerClusterize: this.objectManagerClusterize
};
utils.createClusters(markers, config);
utils.addToCart(markers, config);
this.$emit('map-was-initialized', this.myMap);
}
},
Expand All @@ -243,7 +244,8 @@ export default {
{
attrs: {
id: this.ymapId,
class: 'ymap-body'
class: this.ymapClass,
style: this.style
}
}
),
Expand Down Expand Up @@ -298,6 +300,7 @@ export default {
}
},
beforeDestroy() {
this.myMap.GeoObjects && this.myMap.GeoObjects.removeAll();
this.observer.disconnect();
}
}
73 changes: 61 additions & 12 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,46 @@
export function createCallbacks(marker, placemark) {
if (marker.callbacks && typeof marker.callbacks === 'object') {
for (let key in marker.callbacks) {
placemark.events.add(key, marker.callbacks[key]);
export function createCallbacks(callbacks, placemark) {
if (callbacks && typeof callbacks === 'object') {
for (let key in callbacks) {
placemark.events.add(key, callbacks[key]);
}
}
}

export function createClusters(markers, { options, callbacks, map }) {
export function addToCart(markers, { options, callbacks, map, useObjectManager, objectManagerClusterize }) {
let clusters = {};
let unclastered = [];
for (let marker of markers) {
if (!marker.clusterName) continue;
if (!marker.clusterName) {
unclastered.push(marker);
continue;
};
clusters[marker.clusterName] = clusters[marker.clusterName] ? [...clusters[marker.clusterName], marker] : [marker];
}
for (let clusterName in clusters) {
const clusterOptions = options[clusterName] || {};
const clusterCallbacks = callbacks[clusterName] || {};
const layout = clusterOptions.layout;
clusterOptions.clusterBalloonItemContentLayout = ymaps.templateLayoutFactory.createClass(layout);
const clusterer = new ymaps.Clusterer(clusterOptions);
for (let key in clusterCallbacks) {
clusterer.events.add(key, clusterCallbacks[key]);
if (useObjectManager) {
const ObjectManager = new ymaps.ObjectManager(Object.assign({ clusterize: objectManagerClusterize }, clusterOptions));
for (let key in clusterCallbacks) {
ObjectManager.clusters.events.add(key, clusterCallbacks[key]);
}
ObjectManager.add(clusters[clusterName]);
map.geoObjects.add(ObjectManager);
} else {
const clusterer = new ymaps.Clusterer(clusterOptions);
for (let key in clusterCallbacks) {
clusterer.events.add(key, clusterCallbacks[key]);
}
clusterer.add(clusters[clusterName]);
map.geoObjects.add(clusterer);
}
clusterer.add(clusters[clusterName]);
map.geoObjects.add(clusterer);
}
if (unclastered.length) {
const unclasteredMarkers = useObjectManager ? new ymaps.ObjectManager({ clusterize: false }) : new ymaps.GeoObjectCollection();
unclasteredMarkers.add(unclastered);
map.geoObjects.add(unclasteredMarkers);
}
}

Expand Down Expand Up @@ -124,5 +142,36 @@ const CONTROL_TYPES = [

export function controlsTypeValidator(val) {
return val.filter(control => ![...CONTROL_TYPES, 'default'].includes(control)).length === 0
}
}

export function createMarkerType(val, useObjectManager) {
const type = setFirstLetterToUppercase(val);
if (!useObjectManager) return type;
switch(type) {
case 'Placemark':
return 'Point';
case 'Polyline':
return 'LineString';
default:
return type;
}
}

export function createMarker(object, useObjectManager) {
let marker = useObjectManager ? {
type: 'Feature',
id: object.properties.markerId,
geometry: {
type: object.markerType,
coordinates: object.coords
},
properties: object.properties,
options: object.options,
clusterName: object.clusterName
} : new ymaps[markerType](object.coords, object.properties, object.options);

if (!useObjectManager) createCallbacks(object.callbacks, marker);

return marker;
}

0 comments on commit 0b0347b

Please sign in to comment.