application not working after chrome update to version 66 but works in firefox and edge - angularjs

link to error message2 days back google chrome automatically updated to version 66. Since then my site which was running perfectly stopped working in google chrome. But it works perfectly in firefox and edge. So i started debugging in google chrome, then i found that the problem is with ajax calls. So initially for the main page, many ajax call will be hit. in that list of calls ,the last call executes the success part more than once. So when the susscess of response is executing for the second time it throws aw snap,page cannot be displayed error in chrome. Then i restricted the success call to once using some flag,then the main page was loading. But after submitting in left panel,the same ajax call will get hit, so now at this point i'm getting the same aw snap error. i'm using angularjs ajax. So please help me with this. when i debug i get below error message in console
error message in console
As discussed in comment this function of d3.js code causes the application to crash.So when i commented this except this chart all other things are working
var carbon = new Charts();
var chart = d3.select(this.selector);
var width = carbon.pixToVal(chart.style("width"));
var height = carbon.pixToVal(chart.style("height"));
/*var width=475;
var height=133;*/
/*var maxVal =100;*/
var maxVal =d3.max(jsonData,function(d){return d.current;})+ 15;
var length1=jsonData.length;
var newWidthParts=newWidth/10;
/*console.log(length1);
console.log(newWidth);*/
var newHeightParts=height/10;
var conatinerRectHt=newHeightParts*6.5;
/*var boxHeight=(newHeightParts*9-newHeightParts*2.5)/5;*/
var margin={
top: 15, left:15,right:15,bottom:20
}
var availableWidth = width - margin.left - margin. right;
var newWidth= availableWidth/length1;
var availableHeight = height - margin.top - margin.bottom;
var HeightForTopLabel =15;
var HeightForBottomLabel = 15;
var HeightOfAbsValue = 15;
var HeightForMidLabel = 15;
var OuterRectHeight= availableHeight - (HeightForBottomLabel) - HeightForTopLabel; /*- HeightOfAbsValue;*/
/* var BottomTextYPosition = margin.top + HeightForTopLabel + OuterRectHeight + HeightForBottomLabel ;
*/
var outerRectBottomYPosition = margin.top + HeightForTopLabel +OuterRectHeight;
//outerRectTopYPosition + OuterRectHeight
var outerRectTopYPosition = margin.top + HeightForTopLabel;
var BottomTextYPosition = height - margin.bottom;
var outerRectWidth = 50;
var innerRectWidth =8;
var outerRectDistFromLeft = newWidth/2 - outerRectWidth/2 + margin.left ;
var innerRectDistFromLeft = newWidth/2 - innerRectWidth/2 + margin.left ;
var creatSvg = chart.append("div").attr("class", "chartBox9")
.style("position", "absolute")
.style("height", "100%")
.style("width", "100%")
.append("svg").attr('id','defsGrad')
.attr("width", width)
.attr("height", height);
d3.select("#defsGrad")
.append("text").attr("x",availableWidth - 1.8*(margin.left + margin.right) )
.attr("y",height-5)
.attr("id","shareContritext")
.text("% Room Revenue")
.attr("font-size",10.5);
d3.select("#defsGrad").append("defs").append("linearGradient").attr('id','grad1')
.attr({'x1':'0%','y1':'100%','x2':'0%' ,'y2':'0%'}).append('stop')
.attr('offset',"0%").style({'stop-color':'rgb(215,214,214)','stop-opacity':'0.7'});
d3.select('#grad1').append('stop')
.attr('offset',"100%").style({'stop-color':'rgb(249,249,249)','stop-opacity':'0.9'});
svgContainer=creatSvg.selectAll('g')
.data(jsonData).enter()
.append("g")
.attr("transform",function(d,i){
var res = "translate(";
var val = i*newWidth;
return res+val+" 0)";
});
svgContainer.append("text")
.attr("y", margin.top)
.attr("font-size",fontsize)
.text(function(d) {
if( d.current == null){
d3.select(this).attr("x",outerRectDistFromLeft + outerRectWidth/5 + 5);
return "N/A";
}else
{
var xposition = outerRectDistFromLeft + (outerRectWidth/5+4);
var nbr = d.current;
// var decimals = (nbr!=Math.floor(nbr))?(nbr.toString()).split('.')[0].length:0;
var decimals;
if(nbr % 1 !== 0)
{
decimals = (nbr!=Math.floor(nbr))?(nbr.toString()).split('.')[0].length:0;
}else
{
decimals = nbr.toString().length;
}
d3.select(this).attr("x",xposition-(decimals-1)*4);
if(d.change==null)
{
d3.select(this).attr("x",outerRectDistFromLeft + outerRectWidth/5 + 5);
}
return d.current_prefix + d.current.toFixed(1) + d.current_suffix;}
});
var rectangle1 = svgContainer.append("rect")
.attr("class","outerRect9")
.attr("x", outerRectDistFromLeft)
.attr("y",outerRectTopYPosition)
.attr("width", outerRectWidth)
.attr("height", OuterRectHeight)
.attr("fill", "url(#grad1)");
svgContainer.append("text")
.attr("y", margin.top + HeightForTopLabel -2 )
.attr("fill",
function(d){
var colorChange="";
if(d.change>=0.0)
colorChange="#06C10C";
else
colorChange="#F7063A";
return colorChange;
}
)
.attr("font-size",fontsize)
.text(function(d) {
if( d.change == null){
d3.select(this).attr("fill","black");
d3.select(this).attr("x",outerRectDistFromLeft + outerRectWidth/5 + 7);
return "N/A";
}else{
var pre ="";
if(d.change>=0.0)
pre="+";
/*if(d.current!=null)
{
d3.select(this).attr("x", outerRectDistFromLeft + outerRectWidth/5+3 );
}*/
var xposition = outerRectDistFromLeft + outerRectWidth/5;
/* if(d.current =! null){
d3.select(this).attr("x", xposition);
}
else
{
d3.select(this).attr("x", xposition);
}*/
d3.select(this).attr("x", xposition);
return pre+d.change.toFixed(1)/*+d.change_suffix*/;}
});
var rectangle0=svgContainer.append('rect') .attr("x", innerRectDistFromLeft)
.attr("y",outerRectTopYPosition).attr('width',8).attr('height',OuterRectHeight)
.attr('fill','#BDBDB7').attr('opacity',0.5);
var rectangle2=svgContainer.append('rect') .attr("x", innerRectDistFromLeft)
.attr("y", function(d) {
if(d.current == null){return (margin.top + HeightForTopLabel +OuterRectHeight);}
else{ return (margin.top + HeightForTopLabel +OuterRectHeight) - ((d.current/maxVal)*OuterRectHeight);}
}).attr('width',8).attr('height',function(d) {
if(d.current == null){
return 0;
}
else{ return ((d.current/maxVal)*OuterRectHeight);}
}).attr('fill',function(d,i){return d.color_code;});
var data1 = d3.range(5)
var c = d3.scale.ordinal()
.domain(data1)
.rangeBands([outerRectBottomYPosition + 1.5 ,outerRectTopYPosition ])
var innerRect= svgContainer.selectAll('.inners')
.data(data1)
.enter()
.append('rect').attr('class','inners')
.attr('y',function(d) { return (c(d));/*return Math.round(c(d))*/ })
.attr('x',innerRectDistFromLeft )
.attr('width',8)
.attr('height',(OuterRectHeight/5) )/*+ (1.5*3)*/
.style('stroke','#F6F6F6')
.style('stroke-width','1.2')
.style('fill', "none");
svgContainer.append("text")
.attr("x",function(d,i){
var name =d.name;
var lengthOfText = name.length;
if(lengthOfText > 2){
return outerRectDistFromLeft + outerRectWidth/3 - lengthOfText*2;
}
else {
return outerRectDistFromLeft + outerRectWidth/3;
}
} )
.attr("y", BottomTextYPosition)
.attr("font-size",fontsize)
.text(function(d) {
return d.name;
})
.on("mouseover", handleMouseOver)
.on("mouseout", handleMouseOut);
function handleMouseOver(d, i) {
creatSvg.append("rect").attr({
id: "tooltipvaluebox",
y: BottomTextYPosition,
height: 20,
fill:"#CACACE",
})
.attr("x",function(){
var len = (d.fullName.length*10)+20;
var val = newWidth*i;
if((val+len)>width){
var diff = (val+len) - width;
val = val - (diff+5);
}
return val+8;
} )
.attr("width",function(){
var len = d.fullName.length;
return (len*10)+20;
});
creatSvg.append("text").attr({
id: "tooltipvalue",
y: BottomTextYPosition+15
})
.attr("x",function(){
var len = (d.fullName.length*10)+20;
var val = newWidth*i;
if((val+len)>width){
var diff = (val+len) - width;
val = val - (diff+5);
}
return val+8;
} )
.text(function() {
return d.fullName ;
})
.attr('fill','black')
.style("font-family", "roboto");
};
function handleMouseOut(d, i) {
d3.select("#tooltipvaluebox").remove();
d3.select("#tooltipvalue").remove();
};

Chrome Version 66 for Windows seems to have a critical Bug in the DEV Engine. I think it's related to the meltdown hotfix in version 66. Its already fixed in Dev Channel V 68.x

Related

Angularjs: ReferenceError: function is not defined at Channel.onDeviceReady

This is my second question today. I am using Cordova + angular (1).
I am trying to compare two geolocation with the help of distanceInKmBetweenCoordinates function.
I am getting this error while running the app.
angular.min.js:101 ReferenceError: distanceInKmBetweenCoordinates is
not defined
at Channel.onDeviceReady
Here is the code.
document.addEventListener('deviceready', function onDeviceReady() {
angular.bootstrap(document, ['formApp']);
}, false);
var formApp = angular.module('formApp', []);
// define angular module/app
var formApp = angular.module('formApp', []);
formApp.controller('formProfile1', function($scope,$http,$location, $timeout){
function degreesToRadians(degrees) {
return degrees * Math.PI / 180;
}
function distanceInKmBetweenEarthCoordinates(lat1, lon1, lat2, lon2) {
var earthRadiusKm = 6371;
var dLat = degreesToRadians(lat2-lat1);
var dLon = degreesToRadians(lon2-lon1);
lat1 = degreesToRadians(lat1);
lat2 = degreesToRadians(lat2);
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return earthRadiusKm * c;
}
I am using Cordova geolocation plugin to get the current location.
navigator.geolocation.getCurrentPosition(function(position) {
$scope.userlongitude = position.coords.longitude;
$scope.userlatitude = position.coords.latitude;
Below are some ajax request to get the data from the database including geolocation to compare.
$http({
url: 'https://www.abcd.xyz/get_info.php',
method: "GET",
params: {
tn_id: $scope.tn_id
}
})
.success(function(data) {
if (data.success) {
$scope.longitude = data.longitude;
$scope.latitude = data.latitude;
}
$scope.distance = distanceInKmBetweenCoordinates($scope.userlatitude, $scope.userlongitude, $scope.latitude, $scope.longitude);
In the end, I am comparing the geolocation.
Can you advise me what am I doing wrong? If I just do the compare only in angular then it is showing me correct value but along with Cordova, it is broken.
I also made changes in the body section as follows.
<!--<body id="home" ng-app="formApp"> --> Previous one
<body id="home">
Edit 1
I changed the code like this.
degreesToRadians = function(degrees) {
return degrees * Math.PI / 180;
}
distanceInKmBetweenEarthCoordinates= function(lat1, lon1, lat2, lon2) {
var earthRadiusKm = 6371;
var dLat = degreesToRadians(lat2-lat1);
var dLon = degreesToRadians(lon2-lon1);
lat1 = degreesToRadians(lat1);
lat2 = degreesToRadians(lat2);
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return earthRadiusKm * c;
}
$scope.distance = distanceInKmBetweenEarthCoordinates(43, 44,44,55);
alert($scope.distance);
and when I test it is giving me correct value but when I test it like this.
distanceInKmBetweenCoordinates($scope.userlatitude, $scope.userlongitude, 44,55);
then it is giving me the same error.
I used $timeout function to delay the loading but the error is same.
$timeout(function() {
$scope.distance = distanceInKmBetweenCoordinates($scope.userlatitude, $scope.userlongitude, 44,55);
alert($scope.distance);
console.log($scope.distance);
}, 5000);
As you suggested, place your code once you get the response from the ajax call,
if (data.success) {
$scope.longitude = data.longitude;
$scope.latitude = data.latitude;
$scope.distance = distanceInKmBetweenCoordinates($scope.userlatitude, $scope.userlongitude, $scope.latitude, $scope.longitude);
}
Try to assign the function to a local var in controller scope, maybe it's loosing reference:
formApp.controller('formProfile1', function($scope,$http,$location){
var degreesToRadians = function(degrees) {
return degrees * Math.PI / 180;
}
var distanceInKmBetweenEarthCoordinates = function(lat1, lon1, lat2, lon2) {
var earthRadiusKm = 6371;
var dLat = degreesToRadians(lat2-lat1);
var dLon = degreesToRadians(lon2-lon1);
lat1 = degreesToRadians(lat1);
lat2 = degreesToRadians(lat2);
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) *
Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return earthRadiusKm * c;
}

Google Maps - Fixed source and draggable destination in website

I`m using the API to integrate Google Maps in our website. But we did not met the requirement by using them.
I tried using different options. Our requirement is that - the source is set to fixed location(should not be dragged) and the accurate destination is to be entered in the text area and the end user should have an option to point out the exact location(may be near to the location entered in the destination text area).
calculation of distance and the remaining part is working fine for me. Pointing the exact location in the destination also achieved.
Only thing to be worked on is that fixing the source location(End user should not drag/move the source location).
<script type="text/javascript">
var source, destination;
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
google.maps.event.addDomListener(window, 'load', function () {
new google.maps.places.SearchBox(document.getElementById('txtSource'));
new google.maps.places.SearchBox(document.getElementById('txtDestination'));
directionsDisplay = new google.maps.DirectionsRenderer({ 'draggable': true });
});
function GetRoute() {
var mapOptions = {
zoom: 4,
};
map = new google.maps.Map(document.getElementById('dvMap'), mapOptions);
directionsDisplay.setMap(map);
directionsDisplay.setPanel(document.getElementById('dvPanel'));
//*********DIRECTIONS AND ROUTE**********************//
source = document.getElementById("txtSource").value;
destination = document.getElementById("txtDestination").value;
var request = {
origin: source,
destination: destination,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function (response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
//*********DISTANCE AND DURATION**********************//
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix({
origins: [source],
destinations: [destination],
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.METRIC,
avoidHighways: false,
avoidTolls: false
}, function (response, status) {
if (status == google.maps.DistanceMatrixStatus.OK && response.rows[0].elements[0].status != "ZERO_RESULTS") {
var distance = response.rows[0].elements[0].distance.text;
var duration = response.rows[0].elements[0].duration.text;
var dvDistance = document.getElementById("dvDistance");
dvDistance.innerHTML = "";
dvDistance.innerHTML += "Distance: " + distance + "<br />";
dvDistance.innerHTML += "Duration:" + duration;
} else {
alert("Unable to find the distance via road.");
}
});
}
</script>
By using above code, Both the source and destination are draggable.
Google maps marker are not moveable by default, I think, when you set their coordinates on map they stay on the same location.
If still moving you can remove the event listener on the marker
<script type="text/javascript">
google.maps.event.addDomListener(window, 'load', function () {
new google.maps.places.SearchBox(document.getElementById('txtSource'));
new google.maps.places.SearchBox(document.getElementById('txtDestination'));
});
var gmarkers = [];
var map = null;
var startLocation = null;
var endLocation = null;
var directionsService = null;
var polyline = new google.maps.Polyline({
path: [],
strokeColor: '#FF0000',
strokeWeight: 3
});
function initialize() {
map = new google.maps.Map(document.getElementById('map_canvas'), {
zoom: 4,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
//google.maps.event.addListener(map, 'click', function () {
// infowindow.close();
//});
directionsService = new google.maps.DirectionsService();
var request = {
origin: document.getElementById("txtSource").value,
destination: document.getElementById("txtDestination").value,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, RenderCustomDirections);
}
function RenderCustomDirections(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
var bounds = new google.maps.LatLngBounds();
var route = response.routes[0];
var summaryPanel = document.getElementById("directions_panel");
startLocation = new Object();
endLocation = new Object();
summaryPanel.innerHTML = "";
// For each route, display summary information.
for (var i = 0; i < route.legs.length; i++) {
var routeSegment = i + 1;
summaryPanel.innerHTML += route.legs[i].start_address + "<br />" + " to " + "<br />";
summaryPanel.innerHTML += route.legs[i].end_address + "<br />";
summaryPanel.innerHTML += route.legs[i].distance.text + "<br /><br />";
}
var path = response.routes[0].overview_path;
var legs = response.routes[0].legs;
for (i = 0; i < legs.length; i++) {
if (i == 0) {
startLocation.latlng = legs[i].start_location;
startLocation.address = legs[i].start_address;
startLocation.marker = createMarker(legs[i].start_location, "start", legs[i].start_address, "green", false);
}
endLocation.latlng = legs[i].end_location;
endLocation.address = legs[i].end_address;
var steps = legs[i].steps;
for (j = 0; j < steps.length; j++) {
var nextSegment = steps[j].path;
var dist_dur = "";
if (steps[j].distance && steps[j].distance.text) dist_dur += " " + steps[j].distance.text;
if (steps[j].duration && steps[j].duration.text) dist_dur += " " + steps[j].duration.text;
for (k = 0; k < nextSegment.length; k++) {
polyline.getPath().push(nextSegment[k]);
bounds.extend(nextSegment[k]);
}
}
}
polyline.setMap(map);
map.fitBounds(bounds);
endLocation.marker = createMarker(endLocation.latlng, "end", endLocation.address, "red", true);
}
else alert("Please try again " + status);
}
function createMarker(latlng, label, html, color, draggable) {
//alert("createMarker(" + latlng + "," + label + "," + html + "," + color + ")");
var contentString = '<b>' + label + '</b><br>' + html;
var marker = new google.maps.Marker({
position: latlng,
draggable: draggable,
map: map,
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.setContent(contentString);
infowindow.open(map, marker);
});
google.maps.event.addListener(marker, 'dragend', function () {
var request = {
origin: startLocation.marker.getPosition(),
destination: endLocation.marker.getPosition(),
travelMode: google.maps.DirectionsTravelMode.WALKING
};
startLocation.marker.setMap(null);
endLocation.marker.setMap(null);
gmarkers = [];
polyline.setMap(null);
polyline = new google.maps.Polyline({
path: [],
strokeColor: '#FF0000',
strokeWeight: 3
});
directionsService.route(request, RenderCustomDirections);
});
return marker;
}
</script>

AngularJS Update value in scope object inside foreach

I need to recalculate some values inside scope object on form submit.
So i've got:
$scope.submit = function() {
if ($scope.searchPlace) {
var address = $scope.searchPlace + ', ' $scope.land;
geocodeAddress(address, function(latLng){
angular.forEach($scope.places,function(value,key){
var distance = getDistance(value.latitude,value.longitude,latLng.lat(),latLng.lng())
value.distance = distance;
});
});
}
};
$scope.places is something like [{'name':'place_a', 'distance': 0}, {'name':'place_b', 'distance': 0}]
But I can not see any changes to scope object in frontend. What am I missing?
Here are both functions used above
var getDistance = function(lat1,lon1,lat2,lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2-lat1); // deg2rad below
var dLon = deg2rad(lon2-lon1);
var a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2)
;
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c; // Distance in km
return d;
}
var geocodeAddress = function(address, callback) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
callback(results[0].geometry.location);
} else {
console.log("Geocode was not successful for the following reason: " + status);
}
});
};
If getDistance function returns a promise, you should use it like this :
getDistance(value.latitude,value.longitude,latLng.lat(),latLng.lng()).then(function(response){
var distance = response.data;
value.distance = distance;
});

SVGPathSeg is deprecated and will be removed in Chrome 48. See https://www.chromestatus.com/feature/5708851034718208 [duplicate]

I'm writing a Leaflet plugin that extends the polyline functionality. In the my plugin I'm accessing the path segments using the SVGPathSegList interface. But according to the Chrome DevTools the interface will be removed in Chrome 48. I'm seeking for another possibility to access the the path segments.
Here's my fiddle.
(function () {
var __onAdd = L.Polyline.prototype.onAdd,
__onRemove = L.Polyline.prototype.onRemove,
__updatePath = L.Polyline.prototype._updatePath,
__bringToFront = L.Polyline.prototype.bringToFront;
L.Polyline.include({
onAdd: function (map) {
__onAdd.call(this, map);
this._textRedraw();
},
onRemove: function (map) {
__onRemove.call(this, map);
},
bringToFront: function () {
__bringToFront.call(this);
this._textRedraw();
},
_textRedraw: function () {
var textNodes = this._path.parentElement.getElementsByTagName('text'),
tnIndex;
if (textNodes.length > 0) {
for (tnIndex = textNodes.length - 1; tnIndex >= 0; tnIndex -= 1) {
textNodes[tnIndex].parentNode.removeChild(textNodes[tnIndex]);
}
}
if (this.options.measurements) {
this.setText();
}
},
setText: function () {
var path = this._path,
points = this.getLatLngs(),
pathSeg,
prevPathSeg,
center,
angle,
rotation,
textNode;
/*
* If not in SVG mode or Polyline not added to map yet return
* setText will be called by onAdd, using value stored in this._text
*/
if (!L.Browser.svg || typeof this._map === 'undefined') {
return this;
}
for (pathSeg = 0; pathSeg < path.pathSegList.length; pathSeg += 1) {
if (pathSeg > 0) {
prevPathSeg = path.pathSegList[pathSeg - 1];
center = this._calcCenter(
prevPathSeg.x,
prevPathSeg.y,
path.pathSegList[pathSeg].x,
path.pathSegList[pathSeg].y
);
angle = this._calcAngle(
prevPathSeg.x,
prevPathSeg.y,
path.pathSegList[pathSeg].x,
path.pathSegList[pathSeg].y
);
rotation = 'rotate(' + angle + ' ' +
center.x + ',' + center.y + ')';
debugger;
textNode = document
.createElementNS('http://www.w3.org/2000/svg', 'text');
textNode.setAttribute('text-anchor', 'middle');
textNode.setAttribute('x', center.x);
textNode.setAttribute('y', center.y);
textNode.setAttribute('transform', rotation);
textNode.textContent = points[pathSeg - 1]
.distanceTo(points[pathSeg]);
this._path.parentElement.appendChild(textNode);
} else {
continue;
}
}
},
_calcCenter: function (x1, y1, x2, y2) {
return {
x: (x1 + x2) / 2,
y: (y1 + y2) / 2
}
},
_calcAngle: function (x1, y1, x2, y2) {
return Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;
},
_updatePath: function () {
__updatePath.call(this);
this._textRedraw();
}
});
})();
#holger-will gave some very useful links.
You can modify your js code to use the new API.
for example:
Use var pathData = path.getPathData() instead of old var segs = path.pathSegList;
Use pathData[1].values[4] instead of old path.pathSegList.getItem(1).x
Use path.setPathData(pathData) to update the path element instead of old path.pathSegList.appendItem/insertItem/removeItem
Include the path-data-polyfill.js for browsers which have not supported the new API.
(Chrome 50 still has not implemented getPathData and setPathData. There may be a long way...)
Here is a code sample:
//svg code:
//...
//<path d="M0,0 L100,50" id="mypath"></path>
//<script href="/js/path-data-polyfill.js"></script>
//...
//js code:
var path = document.getElementById('mypath');
var pathdata = path.getPathData();
console.log(pathdata);
console.log(pathdata.length); //2
console.log(pathdata[0].type); //"M"
console.log(pathdata[0].values); //[0,0]
console.log(pathdata[1].type); //"L"
console.log(pathdata[1].values); //[100,50]
pathdata.push({type: "C", values: [100,-50,200,150,200,50]}); //add path segment
path.setPathData(pathdata); //set new path data
console.log(path.getAttribute('d')); //"M0,0 L100,50 C100,-50,200,150,200,50"
path data polyfill: https://github.com/jarek-foksa/path-data-polyfill

extjs draggable panel d3js pan zoom don't work

#mbostock
I have a draggable panel Extjs and i have included a graph d3js, customized drag and drop and added the zoom function.
In a simple html page all work fine, but in Extjs panel when drag a node in addition to move that, also activates pan, i would not disable the pan.
where I'm wrong?
This is the ExtjsPanel:
Ext.namespace("libs");
CSP.prj.tresprj.trestest.libs.MainPanel = Ext.extend(Ext.Panel, {
initComponent : function(){
this.addEvents({
'afterrender': true
});
Ext.apply(this,{title:'My Custom Panel2'});
Ext.apply(this,{html:'<div id="content"><div id="buttonDiv"><p>Selezionare il test da effettuare</p></div><!--buttonDiv--><div id="svgContent"></div><!--svgContent--></div><!--content-->'});
this.addListener('afterrender',function(){
Xxx.createButton("buttonDiv");
});
libs.MainPanel.superclass.initComponent.call(this);
}
});
and this is the Graph code:
var initSvg = function (target) {
//Activate context menu on right click
d3.select("body").attr("oncontextmenu", "return true");
//Create SVG element
if (jQuery(target + " svg").length) {
clearSvgDiv();
}
var svg = d3.select(target)
.append("svg")
.attr("width", width)
.attr("height", heigth)
.attr("id", "drawSvg")
.attr('preserveAspectRatio', 'xMinYMin slice')
.append('g');
return svg;
};
var clearSvgDiv = function () {
d3.select("svg")
.remove();
};
// Init force layout
var initLayout = function (svg) {
svg.append('svg:rect')
.attr('width', width)
.attr('height', heigth)
.attr('fill', 'white');
force = d3.layout.force()
.nodes(graph.getNodes())
.links(graph.getEdges())
.size([width, heigth])
.linkDistance([50])
.charge([-300])
.start();
};
// Creates nodes and edge to draw them on the page, calculated positions and repulsions.
var createNodesEdges = function (svg) {
var x = d3.scale.linear()
.domain([0, width])
.range([0, width]);
var y = d3.scale.linear()
.domain([0, heigth])
.range([heigth, 0]);
svg.call(d3.behavior.zoom().x(x).y(y).scaleExtent([1, 8]).on("zoom", rescale));
var path = svg.append("svg:g").selectAll("path")
.data(graph.getEdges())
.enter()
.insert("svg:path")
.attr("class", "line")
.style("stroke", "#ccc");
var node_drag = d3.behavior.drag()
.on("dragstart", dragstart)
.on("drag", dragmove)
.on("dragend", dragend);
var nodes = svg.selectAll("circle")
.data(graph.getNodes(), function (d) { return d.id; })
.enter()
.append("circle")
.attr("id", function (d) { return d.id; })
.attr("r", 5)
.call(node_drag);
force.on("tick", tick);
function tick() {
path.attr("d", function (d) {
var coordinatesP = findEdgeControlPoints(d);
return "M" + d.source.x + "," + d.source.y + "S" + coordinatesP.xp + "," + coordinatesP.yp + " " + d.target.x + "," + d.target.y;
});
nodes.attr("cx", function (d) { return d.x; })
.attr("cy", function (d) { return d.y; });
}
function dragstart(d, i) {
force.stop(); // stops the force auto positioning before you start dragging
}
function dragmove(d, i) {
d.px += d3.event.dx;
d.py += d3.event.dy;
d.x += d3.event.dx;
d.y += d3.event.dy;
tick();
}
function dragend(d, i) {
d.fixed = true; // of course set the node to fixed so the force doesn't include the node in its auto positioning stuff
tick();
force.resume();
}
};
var rescale = function () {
var trans = d3.event.translate;
var scale = d3.event.scale;
svg.attr("transform","translate(" + trans + ")" + " scale(" + scale + ")");
};
i've found the problem, isn't extjs but minified version of d3js library downloaded by http://d3js.org/, with extended version i've no problem.

Resources