Dynamically change zoom - angularjs

I need to change zoom of Google Maps. Code:
function _initMap(vm) {
vm.windowOptions = {
show: false
};
var latSum = 0;
var longSum = 0;
for (var i = 0, length = vm.markers.length; i < length; i++) {
//calculate center of map (1st part)
latSum += vm.markers[i].coords.latitude;
longSum += vm.markers[i].coords.longitude;
//assign an icon
vm.markers[i].iconUrl = getIconUrl(vm.markers[i].deviceType);
}
var centeredLatitude = latSum / vm.markers.length;
var centeredLongitude = longSum / vm.markers.length;
vm.control = {};
vm.map = {
center: setCenterMap(),
options: getMapOptions(),
zoom: setMapZoom(),
events: {
click: function (mapModel, eventName, originalEventArgs) {
var e = originalEventArgs[0];
$log.log('gz', e.latLng.lat() + ' ' + e.latLng.lng());
console.log('xxx', mapModel);
}
},
show: true,
refresh: function (a, b, c, d) {
vm.map.control.refresh();
}
};
vm.clusterOptions = {
minimumClusterSize: 2,
zoomOnClick: true,
styles: [{
url: 'assets/images/markers/m1.png',
width: 53,
height: 53,
textColor: 'white',
textSize: 17,
fontFamily: 'Open Sans'
}],
averageCenter: true,
clusterClass: 'cluster-icon'
};
vm.window = {
location: undefined,
templateUrl: 'app/components/maps/maps.info.template.html',
show: false,
options: getMapWindowOptions()
};
vm.clickMarker = function (marker, event, object) {
vm.window.show = false;
vm.window.details = object.details;
vm.window.location = object.coords;
vm.window.show = true;
vm.sendChoosenDeviceToController(object);
angular.element('#right-menu').focus();
};
vm.closeClick = function () {
vm.window.show = false;
}
}
but the code:
center: setCenterMap()
zoom: setMapZoom()
when I call the methods center and zoom does not change center and zoom. How to update center and zoom dynamically ? The methods are properly exectued during initiation of map but after initialization does not want to change.

The solution was just simply:
scope.map.center = {
'latitude': scope.markers[i].coords.latitude,
'longitude': scope.markers[i].coords.longitude
};
GoogleMaps knows about that change and works nice.

Related

Dots persist on D3 graph for angularjs

I am using NVD3 for my graphs and I have this issue where the dots that show up on hover will start to persist as you over over the line. Does anyone have any idea on how to make sure these disappear when the move moves away from them?
Here is the component:
;(function() {
angular.module('canopy.common.components.largeStandardChart')
.component('largeStandardChart', {
templateUrl: 'app/common/components/chart-components/large-standard-chart/large-standard-chart.html',
controller: LargeStandardChartController,
controllerAs: 'vm',
bindings: {
kpi: "<",
updateGraph: '=',
frequency: '<'
}
});
LargeStandardChartController.$inject = ['$rootScope', 'BanyanUtilsService', 'ConfigurationService', '$timeout'];
function LargeStandardChartController($rootScope, UtilsService, CS, $timeout) {
var vm = this;
vm.kpiTrend = [];
vm.kpiTargetTrend = [];
vm.kpiProjectedTrend = [];
vm.predictedDate = null;
var allTrends = vm.kpi.trend.length && vm.kpi.trend[0].values.length ? vm.kpi.trend[0].values : [];
vm.chart = {
chartOptions: {
chart: {
type: 'lineChart',
height: 250,
area: CS.getOrgConfig().graph.general.fillArea,
margin : {
top: 15,
right: 40,
bottom: 50,
left: 70
},
x: (function(d) { return d.time }),
y: (function(d) { return d.value }),
clipVoronoi: false,
xAxis: {
showMaxMin: false,
staggerLabels: vm.frequency === 'DAY' ? false : true,
tickFormat: function(d) {
return vm.frequency === 'DAY'
? d3.time.format(CS.getOrgConfig().dateTime.d3DateFormat)(new Date(d))
: d3.time.format(CS.getOrgConfig().dateTime.d3DateTimeFormat)(new Date(d));
}
},
yAxis: {
showMaxMin: true,
tickFormat: function (d) {
return vm.kpi.kpiMeasure === 'NUMBER' && d ? d.toFixed(1) : UtilsService.getFormattedData(d, vm.kpi.kpiMeasure);
}
},
tooltip: {
hideDelay: 0
},
showXAxis: CS.getOrgConfig().graph.xAxis.showXAxis,
showYAxis: CS.getOrgConfig().graph.yAxis.showYAxis,
showLegend: false,
transitionDuration: 350,
useInteractiveGuideline: false
}
}
};
vm.$onInit = function() {
if(vm.updateGraph) { vm.updateGraph.handler = vm.updateGraphData; }
if (!vm.kpi) { vm.kpi = { trend: vm.kpiTrend, kpiMeasure: "PERCENTAGE" } }
setTrends();
d3.select(window).on('mouseout', function () {
d3.selectAll('.nvtooltip').style('opacity', '0');
});
};
function setTrends() {
_.set(vm.chart, 'chartData', []);
vm.kpiTrend = [];
vm.kpiProjectedTrend = [];
_.forEach(allTrends, function(kpi) {
if (_.has(kpi, 'predict')) {
vm.kpiProjectedTrend.push(kpi);
} else {
if (CS.getOrgConfig().graph.general.showNullValues) {
vm.kpiTrend.push(kpi);
} else {
if (kpi.value) { vm.kpiTrend.push(kpi) }
}
}
});
if (!vm.kpi.hideTarget && !vm.kpiProjectedTrend.length) {
vm.chart.chartData.push({
key: CS.getOrgConfig().labels.target.single,
classed: "dashed",
color: $rootScope.branding.canopyBrandColor,
seriesIndex: 2,
strokeWidth: 1,
values: getTargetValues()
});
}
if (vm.kpiTrend.length) {
vm.chart.chartData.push({
key: 'Value',
classed: "solid",
area: CS.getOrgConfig().graph.general.fillArea,
color: $rootScope.branding.canopyBrandColor,
seriesIndex: 0,
strokeWidth: 2,
values: vm.kpiTrend
});
}
if (vm.kpiProjectedTrend.length) {
vm.chart.chartOptions.chart.useInteractiveGuideline = false;
var lastCurrentValue = angular.copy(vm.kpiTrend).pop();
var firstPredictedValue = angular.copy(vm.kpiTrend).pop();
vm.kpiProjectedTrend.unshift(firstPredictedValue);
vm.endDate = moment.unix(allTrends[ allTrends.length - 1 ].time / 1000).format(CS.getOrgConfig().dateTime.dateFormat); // Divide by 1000 for miliseconds coming from server
vm.chart.chartData.push({
key:'Projected',
classed: "dashed",
color: $rootScope.branding.canopyBrandColor,
strokeWidth: 1,
seriesIndex: 3,
values: vm.kpiProjectedTrend
});
var top = 0, bottom = 0;
if (allTrends.length) {
var top = _.maxBy(allTrends, function(tr) { return tr.value }).value;
var bottom = _.minBy(allTrends, function(tr) { return tr.value }).value;
}
var yTop = vm.kpi.kpiMeasure === 'PERCENTAGE' ? 103 : top + ((top - bottom) * 0.07);
var yBottom = vm.kpi.kpiMeasure === 'PERCENTAGE' ? 0 : bottom - ((top - bottom) * 0.04);
vm.chart.chartData.push({
classed: "solid",
strokeWidth: 1,
seriesIndex: 4,
values: [
{time: lastCurrentValue.time, value: yTop},
{time: lastCurrentValue.time, value: yBottom},
],
color: '#ff0005'
});
}
setDomain();
}
function setDomain () {
var top = 0, bottom = 0;
if (allTrends.length) {
top = _.maxBy(allTrends, function(tr) { return tr.value }).value;
bottom = _.minBy(allTrends, function(tr) { return tr.value }).value;
}
bottom = bottom < 1 && bottom > 0 ? 0 : bottom;
if (top === bottom) { bottom = top - bottom; }
if (top + bottom === 0) { top = 1; }
var yTop = vm.kpi.kpiMeasure === 'PERCENTAGE' ? 103 : top + ((top - bottom) * 0.05);
var yBottom = vm.kpi.kpiMeasure === 'PERCENTAGE' ? 0 : bottom - ((top - bottom) * 0.05);
vm.chart.chartOptions.chart.yDomain = [yBottom, yTop];
}
vm.updateGraphData = function(trend) {
allTrends = trend.length && trend[0].values.length ? trend[0].values : [];
setTrends();
vm.api.updateWithOptions(vm.chart.chartOptions);
vm.api.updateWithData(trend);
vm.api.refresh();
};
function getTargetValues() {
var trend = angular.copy(allTrends);
_.forEach(trend, function(t) {
t.value = vm.kpi.targetValue;
});
return trend;
}
}
})();
and here is what it looks like when I hover:
For anyone having this issue I have finally found the solution. I had to add a listener on the mouseout event and remove the hover class that is added to the .nv-point which is the dot. It looks like this:
d3.select(window).on('mouseout', function () {
d3.selectAll('.nv-point').classed('hover', false);
});

Load from JSON with dynamic patterns, patternSourceCanvas is not defined error return by the serialize JSON data

I am trying to save Fabric.js canvas and reload it using loadFromJson. But I am getting error patternSourceCanvas is not defined. I thought I should make it global so I removed var.
How to set the global variable in Fabric JS and use var patternSourceCanvas?
When I use the code below, then everything is working fine and the JSON is loaded easily.
var t = https://image.freepik.com/free-photo/roof-texture_21206171.jpg
fabric.util.loadImage(t, function(t) {
var svg_width = i.width;
console.log('svg widh' + i.width + 'svg height' + i.height);
console.log('img width t'+ t.width + ' img height' + t.height);
if(svg_width >= 300){
if (i.isSameColor && i.isSameColor() || !i.paths) {
i.setPatternFill({
source: t, repeat: 'repeat', offsetX:200 , offsetY : -110 // working
}), e.fabric.renderAll();
console.log('in if image 300 up ', t);
} else if (i.paths){
for (var r = 0; r < i.paths.length; r++)
i.paths[r].setPatternFill({
source: t, repeat: 'repeat' , offsetX: -100 , offsetY:-110
}), e.fabric.renderAll();
console.log('in image elseeee 300 up ', t);
}
}
})
But when I fill some other new shape with the new patternSourceCanvas variable then it's not working. Kindly help me with dynamic patterns.
var t = https://image.freepik.com/free-photo/roof-texture_21206171.jpg
fabric.Image.fromURL(t, function (img) {
img.scaleToHeight(200);
var patternSourceCanvas = new fabric.StaticCanvas();
patternSourceCanvas.add(img);
patternSourceCanvas.renderAll();
var pattern = new fabric.Pattern({
source: function() {
patternSourceCanvas.setDimensions({
width: img.getScaledWidth() ,
height: img.getScaledHeight()
});
patternSourceCanvas.renderAll();
return patternSourceCanvas.getElement();
},
repeat: r
});
console.log('pattern', pattern);
//p.set('fill', pattern);
canvas.renderAll();
if (i.isSameColor && i.isSameColor() || !i.paths) {
i.setPatternFill(pattern);
} else if(i.paths) {
for (var r = 0; r < i.paths.length; r++) {
i.paths[r].setPatternFill(pattern);
}
}
e.fabric.renderAll();
});
You need to put patternSourceCanvas to global scope/ scope where loadFromJSON can access patternSourceCanvas. Else you can use cors enabled image directly.
DEMO
var imageUrl = 'https://upload.wikimedia.org/wikipedia/commons/2/22/Wikimapia_logotype.svg';
var canvas = new fabric.Canvas('canvas');
var rect = new fabric.Rect({
width: 200,
height: 200,
strokeWidth: 2,
stroke: '#000'
})
canvas.add(rect);
fabric.Image.fromURL(imageUrl, function(img) {
img.scaleToHeight(200);
var patternSourceCanvas = new fabric.StaticCanvas();
patternSourceCanvas.add(img);
patternSourceCanvas.setDimensions({
width: img.getScaledWidth(),
height: img.getScaledHeight()
});
patternSourceCanvas.renderAll();
var pattern = new fabric.Pattern({
source: patternSourceCanvas.getElement()
},
function(patternObj) {
rect.fill = patternObj;
rect.dirty = true;
canvas.renderAll();
});
}, {
crossOrigin: 'annonymous'
});
function loadfromjson() {
var json = canvas.toJSON();
canvas.clear();
setTimeout(function() {
canvas.loadFromJSON(json, canvas.renderAll.bind(canvas));
}, 1000)
}
canvas{
border:2px solid #000;
}
<canvas id="canvas" width="300" height="300"></canvas><br>
<button onclick="loadfromjson()">loadfromjson </button>
<script src='https://rawgit.com/kangax/fabric.js/master/dist/fabric.js'></script>

how can i draw dynamic highchart. the y-axis and the number of charts are dynamic from json

im new in angular js and i need to use highchart in my angular page . the problem is that i must draw chart with dynamic data from json and the number of charts will be dynamic too , maybe it should draw 3 or 4 different chart from one json . I searched alot but couldnt solve my problem.
this code works but show the data in one chart in different series. I need to show each series in different charts, and in this case the json send 4 data but it will be changed .
1. List item
$scope.draw_chart = function(){
Highcharts.chart('container2', {
chart:{
type: 'spline',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
load: function () {
var this_chart = this;
$scope.ws = ngSocket('ws://#');
$scope.ws.onOpen(function () {
});
var k = 0 ;
var time=0;
$scope.points_avarage = [];
$scope.ws.onMessage(function (message) {
listener(JSON.parse(message.data));
var z = JSON.parse(message.data);
var line_to_draw = z.result.length;
var j = 0 ;
for(i=0 ; i < line_to_draw*2 ; i+=2)
{
$scope.data_to_draw[i] = {
name : z.result[j][0]['name'] ,
y : z.result[j][0]['rx-bits-per-second']
}
$scope.data_to_draw[i+1] = {
name : z.result[j][0]['name'] ,
y : z.result[j][0]['tx-bits-per-second']
}
j++;
}
this_chart.series[0].name= $scope.data_to_draw[0].name;
this_chart.series[1].name= $scope.data_to_draw[1].name;
this_chart.series[2].name= $scope.data_to_draw[2].name;
this_chart.series[3].name= $scope.data_to_draw[3].name;
for(i=0; i < line_to_draw*2; i++) {
var x = (new Date()).getTime(); // current time
var y = parseInt($scope.data_to_draw[i].y);
this_chart.series[i].addPoint([x, y], true, true);
}
});
var d = new Date().toTimeString();
}
}
},
global: {
useUTC: false
},
title: {
text: 'Live data'
},
xAxis: {
type: 'datetime'//,
},
yAxis: {
title: {
text: 'Value'
},
plotLines: [{
width: 1,
color: '#808080'
}
]
}
plotOptions: {
series: {
marker: {
enabled: false
}
}
},
series: [{
data: (function () {
var data = [],
time = (new Date()).getTime(),
i;
for (i = -5; i <= 0; i += 1) {
data.push({
x: time ,
y: 0
});
}
return data;
}())
},
{
data: (function () {
var data = [],
time = (new Date()).getTime(),
i;
for (i = -5; i <= 0; i += 1) {
data.push({
x: time ,
y: 0
});
}
return data;
}())
},
{
data: (function () {
var data = [],
time = (new Date()).getTime(),
i;
for (i = -5; i <= 0; i += 1) {
data.push({
x: time ,
y: 0
});
}
return data;
}())
},
{
data: (function () {
var data = [],
time = (new Date()).getTime(),
i;
for (i = -5; i <= 0; i += 1) {
data.push({
x: time ,
y: 0
});
}
return data;
}())
}
]
});
};
<div id="containet" ng-init="draw_chart()"></div>

Add html to a map marker angular Google maps

I need a way to customize the map marker in Angular with Google maps. I searched many places, but found only icons which can be added.
So please help me out to add HTML to my marker(HTML to be shown as a marker).
function getMap(form,scope) {
scope.map = {
center: {
latitude: 40.1451,
longitude: -99.6680
},
zoom: 4
};
scope.options = {
scrollwheel: true
};
function createRandomMarker(i, data, idKey) {
// var infoWindow = new google.maps.InfoWindow();
if (idKey == null) {
idKey = "id";
}
var ret = {
latitude: data.latitude,
longitude: data.longitude,
title: 'm' + i,
icon: {
url: 'http://www.google.com/mapfiles/markerA.png',
scaledSize: { width: 36, height: 48 }
}
};
ret[idKey] = i;
return ret;
}
scope.randomMarkers = [];
for (var i = 0; i < (form.length); i++) {
console.log(form[i].latitude+","+form[i].list_id)
if ((form[i].latitude != null) && (form[i].longitude != null))
{
scope.randomMarkers.push(createRandomMarker(i, form[i]))
}
}
return scope.randomMarkers
}
I need HTML, in place of that icon on the marker creation. Thank you in advance.

angular-google-maps not showing infowindow on mouseover event

I am using angularjs-google-map http://angular-ui.github.io/angular-google-maps/#!/api
I can add multiple markers with showing infoWindow by cliking on a marker, but now I need to show the marker infoWindow when the mouse enters the area of the marker icon and hide it when the mouse leaves the area of the marker icon instead of using the click event.
You can look on this example on Jsfiddle https://jsfiddle.net/meher12/bgb36q7b/ to get idea about my purpose !
My HTML code:
<ui-gmap-google-map center="map.center" zoom="map.zoom" dragging="map.dragging" bounds="map.bounds"
events="map.events" options="map.options" pan="true" control="map.control">
<ui-gmap-markers models="map.randomMarkers" coords="'self'" icon="'icon'"
doCluster="map.doClusterRandomMarkers" clusterOptions="map.clusterOptions" modelsbyref="true"
events="map.markersEvents" options="'options'"
>
<ui-gmap-windows show="'showWindow'" ng-cloak>
<div>
<p>This is an info window</p>
</div>
</ui-gmap-windows>
</ui-gmap-markers>
</ui-gmap-google-map>
</div>
My JS code:
myApp.controller('MainController', function ($scope,uiGmapGoogleMapApi) {
$scope.numOfMarkers = 25;
uiGmapGoogleMapApi.then(function(maps) { $scope.googleVersion = maps.version; });
$scope.map = {
center: {
latitude: 45,
longitude: -73
},
zoom: 10,
options: {
streetViewControl: false,
panControl: false,
maxZoom: 20,
minZoom: 3
},
dragging: false,
bounds: {},
randomMarkers: [],
doClusterRandomMarkers: true,
currentClusterType: 'standard',
clusterOptions: {
title: 'Hi I am a Cluster!', gridSize: 60, ignoreHidden: true, minimumClusterSize: 2
}
};
$scope.map.markersEvents = {
mouseover: function (marker, eventName, model, args) {
model.options.labelContent = "Position - lat: " + model.latitude + " lon: " + model.longitude;
marker.showWindow = true;
$scope.$apply();
},
mouseout: function (marker, eventName, model, args) {
model.options.labelContent = " ";
marker.showWindow = false;
$scope.$apply();
}
};
var genRandomMarkers = function (numberOfMarkers, scope) {
var markers = [];
for (var i = 0; i < numberOfMarkers; i++) {
markers.push(createRandomMarker(i, scope.map.bounds))
}
scope.map.randomMarkers = markers;
};
var createRandomMarker = function (i, bounds, idKey) {
var lat_min = bounds.southwest.latitude,
lat_range = bounds.northeast.latitude - lat_min,
lng_min = bounds.southwest.longitude,
lng_range = bounds.northeast.longitude - lng_min;
if (idKey == null)
idKey = "id";
var latitude = lat_min + (Math.random() * lat_range);
var longitude = lng_min + (Math.random() * lng_range);
var ret = {
latitude: latitude,
longitude: longitude,
title: 'm' + i,
showWindow: false,
options: {
labelContent: ' ',
labelAnchor: "22 0",
labelClass: "marker-labels",
draggable: true
}
};
ret[idKey] = i;
return ret;
};
$scope.genRandomMarkers = function (numberOfMarkers) {
genRandomMarkers(numberOfMarkers, $scope);
};
$scope.removeMarkers = function () {
$scope.map.randomMarkers = [];
};
});
Like you see on my JS code I have created markerEvents and I can get the marker label changed on mouse events but still not showing the infoWindow attached to each marker on the map when the mouse Event is fired, despite its value is changing and take the correct value.
Someone Have an idea to resolve this issue ?
Feel free to put your changes to my Jsfiddle code :)
You must set model.showWindow instead of marker.showWindow
You can set model.show = true instead of model.showWindow, in html remove show =showWindow.

Resources