Vue js : window.addEventListener ne se trigger pas - vue.js

My problem is that I am trying to get an access token from Spotify, but my window.addEventListener("message, function() {...}") is never triggered. Refer to the code below:
mounted(){
this.$nextTick(function() {
function login(callback) {
var CLIENT_ID = 'd3ebae5610894ca48c9f66794214252b';
var REDIRECT_URI = 'http://localhost:8080/spotify';
function getLoginURL(scopes) {
console.log('url')
return 'https://accounts.spotify.com/authorize?client_id=' + CLIENT_ID +
'&redirect_uri=' + encodeURIComponent(REDIRECT_URI) +
'&scope=' + encodeURIComponent(scopes.join(' ')) +
'&response_type=token';
}
var url = getLoginURL([
'user-read-email'
]);
var width = 450,
height = 730,
left = (screen.width / 2) - (width / 2),
top = (screen.height / 2) - (height / 2);
var w = window.open(url,
'Spotify',
'menubar=no,location=no,resizable=no,scrollbars=no,status=no, width=' + width + ', height=' + height + ', top=' + top + ', left=' + left
);
window.addEventListener("message", function(event) {
var hash = JSON.parse(event.data);
console.log(JSON.parse(event.data))
if (hash.type == 'access_token') {
callback(hash.access_token);
}
}, false);
}
var loginButton = document.getElementById('btn-login');
loginButton.addEventListener('click', function() {
console.log('click the button')
login(function(accessToken) {
console.log(accessToken)
});
});
})}

Related

zoomable bar chart using d3.js

Trying to apply the following: https://bl.ocks.org/mbostock/4015254, on to my dataset. I have changed the variables to fit my dataset.
My code is the following:
<script>
var svg = d3.select("svg"),
margin = {top: 20, right: 20, bottom: 30, left: 60},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom,
g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var parseDate = d3.timeParse("%Y-%m-%d"),
formatDate = d3.timeFormat("%Y");
var x = d3.scaleTime()
.domain([new Date(2002, 0, 1), new Date(2003, 0, 1)])
.range([0, width]);
var y = d3.scaleLinear()
.range([height, 0]);
var xAxis = d3.axisBottom(x);
var yAxis = d3.axisLeft(y);
var area = d3.area()
.curve(d3.curveStepAfter)
.y0(y(0))
.y1(function(d) { return y(d.value); });
var areaPath = g.append("path")
.attr("clip-path", "url(#clip)")
.attr("fill", "steelblue");
var yGroup = g.append("g");
var xGroup = g.append("g")
.attr("transform", "translate(0," + height + ")");
var zoom = d3.zoom()
.scaleExtent([1 / 4, 8])
.translateExtent([[-width, -Infinity], [2 * width, Infinity]])
.on("zoom", zoomed);
var zoomRect = svg.append("rect")
.attr("width", width)
.attr("height", height)
.attr("fill", "none")
.attr("pointer-events", "all")
.call(zoom);
g.append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
d3.json("api.php", function(d) {
d.date = parseDate(d.date);
d.value = +d.close;
return d;
}, function(error, data) {
if (error) throw error;
var xExtent = d3.extent(data, function(d) { return d.date; });
zoom.translateExtent([[x(xExtent[0]), -Infinity], [x(xExtent[1]), Infinity]])
y.domain([0, d3.max(data, function(d) { return d.value; })]);
yGroup.call(yAxis).select(".domain").remove();
areaPath.datum(data);
zoomRect.call(zoom.transform, d3.zoomIdentity);
});
function zoomed() {
var xz = d3.event.transform.rescaleX(x);
xGroup.call(xAxis.scale(xz));
areaPath.attr("d", area.x(function(d) { return xz(d.date); }));
}
</script>
Yet I am getting an error on my console with the following error message:
d3.v4.min.js:2 Uncaught TypeError: Cannot read property 'length' of undefined
at SVGPathElement.t (d3.v4.min.js:2)
at SVGPathElement.<anonymous> (d3.v4.min.js:2)
at ut.each (d3.v4.min.js:2)
at ut.attr (d3.v4.min.js:2)
at SVGRectElement.zoomed (research.php:123)
at k.apply (d3.v4.min.js:2)
at it (d3.v4.min.js:2)
at a.emit (d3.v4.min.js:2)
at a.zoom (d3.v4.min.js:2)
at d3.v4.min.js:2
An excerpt of my dataset looks like this:
[{"id":"1","exchange_symbol":"TSE","currency":"JPY","stock_id":"1","stock_name":"KYOKUYO CO.,LTD.","stock_symbol":"1301.T","date":"2006-12-29","time":"15:00:00.000000","close":"2388.023438000000000000","volume":"23700.000000000000000000","active":"1","exchange_id":"0"},{"id":"2","exchange_symbol":"TSE","currency":"JPY","stock_id":"1","stock_name":"KYOKUYO CO.,LTD.","stock_symbol":"1301.T","date":"2007-01-04","time":"15:00:00.000000","close":"2416.452637000000000000","volume":"16500.000000000000000000","active":"1","exchange_id":"0"},{"id":"3","exchange_symbol":"TSE","currency":"JPY","stock_id":"1","stock_name":"KYOKUYO CO.,LTD.","stock_symbol":"1301.T","date":"2007-01-05","time":"15:00:00.000000","close":"2369.071045000000000000","volume":"45400.000000000000000000","active":"1","exchange_id":"0"},{"id":"4","exchange_symbol":"TSE","currency":"JPY","stock_id":"1","stock_name":"KYOKUYO CO.,LTD.","stock_symbol":"1301.T","date":"2007-01-09","time":"15:00:00.000000","close":"2388.023438000000000000","volume":"28800.000000000000000000","active":"1","exchange_id":"0"},{"id":"5","exchange_symbol":"TSE","currency":"JPY","stock_id":"1","stock_name":"KYOKUYO CO.,LTD.","stock_symbol":"1301.T","date":"2007-01-10","time":"15:00:00.000000","close":"2369.071045000000000000","volume":"27800.000000000000000000","active":"1","exchange_id":"0"},{"id":"6","exchange_symbol":"TSE","currency":"JPY","stock_id":"1","stock_name":"KYOKUYO CO.,LTD.","stock_symbol":"1301.T","date":"2007-01-11","time":"15:00:00.000000","close":"2369.071045000000000000","volume":"25500.000000000000000000","active":"1","exchange_id":"0"},{"id":"7","exchange_symbol":"TSE","currency":"JPY","stock_id":"1","stock_name":"KYOKUYO CO.,LTD.","stock_symbol":"1301.T","date":"2007-01-12","time":"15:00:00.000000","close":"2378.546875000000000000","volume":"28100.000000000000000000","active":"1","exchange_id":"0"},{"id":"8","exchange_symbol":"TSE","currency":"JPY","stock_id":"1","stock_name":"KYOKUYO CO.,LTD.","stock_symbol":"1301.T","date":"2007-01-15","time":"15:00:00.000000","close":"2397.500244000000000000","volume":"23400.000000000000000000","active":"1","exchange_id":"0"}]
It consists of 2831 records. I don't understand why even my x and y axes aren't printing correctly. Thanks in advance.
The bl.ocks that you refer to uses a d3.csv which (if you look at the docs) has an accessor function that is passed each row of the data and then the whole date is accessed in the callback. Here's the accessor function:
function(d) {
d.date = parseDate(d.date);
d.value = +d.value;
return d;
}
But in case of d3.json, there's no such accessor: d3.json(url[, callback]) which means you'll have to parse each row within the callback. Here's how:
d3.json("test.json", function(data) {
data.forEach(e => {
e.date = parseDate(e.date);
e.value = +e.close;
});
var xExtent = d3.extent(data, function(d) { return d.date; });
.....
Here's a fork of your code (I'm not sure why you have the file named as "api.php" when it is a JSON file. I've used a "test.json" file.
https://bl.ocks.org/shashank2104/21358032ac5507f7a6b7d620b1a4ef69/12b6089547e3b07edeca6214834d7e7a340be6a7
If you're unable to view that or if you're looking for a code snippet, here's one:
var svg = d3.select("svg"),
margin = {top: 20, right: 20, bottom: 30, left: 60},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom,
g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var parseDate = d3.timeParse("%Y-%m-%d"),
formatDate = d3.timeFormat("%Y");
var x = d3.scaleTime()
.domain([new Date(2006, 12, 1), new Date(2007, 1, 1)])
.range([0, width]);
var y = d3.scaleLinear()
.range([height, 0]);
var xAxis = d3.axisBottom(x);
var yAxis = d3.axisLeft(y);
var area = d3.area()
.curve(d3.curveStepAfter)
.y0(y(0))
.y1(function(d) { return y(d.value); });
var areaPath = g.append("path")
.attr("clip-path", "url(#clip)")
.attr("fill", "steelblue");
var yGroup = g.append("g");
var xGroup = g.append("g")
.attr("transform", "translate(0," + height + ")");
var zoom = d3.zoom()
.scaleExtent([1 / 4, 8])
.translateExtent([[-width, -Infinity], [2 * width, Infinity]])
.on("zoom", zoomed);
var zoomRect = svg.append("rect")
.attr("width", width)
.attr("height", height)
.attr("fill", "none")
.attr("pointer-events", "all")
.call(zoom);
g.append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
var data = [{"id":"1","exchange_symbol":"TSE","currency":"JPY","stock_id":"1","stock_name":"KYOKUYO CO.,LTD.","stock_symbol":"1301.T","date":"2006-12-29","time":"15:00:00.000000","close":"2388.023438000000000000","volume":"23700.000000000000000000","active":"1","exchange_id":"0"},{"id":"2","exchange_symbol":"TSE","currency":"JPY","stock_id":"1","stock_name":"KYOKUYO CO.,LTD.","stock_symbol":"1301.T","date":"2007-01-04","time":"15:00:00.000000","close":"2416.452637000000000000","volume":"16500.000000000000000000","active":"1","exchange_id":"0"},{"id":"3","exchange_symbol":"TSE","currency":"JPY","stock_id":"1","stock_name":"KYOKUYO CO.,LTD.","stock_symbol":"1301.T","date":"2007-01-05","time":"15:00:00.000000","close":"2369.071045000000000000","volume":"45400.000000000000000000","active":"1","exchange_id":"0"},{"id":"4","exchange_symbol":"TSE","currency":"JPY","stock_id":"1","stock_name":"KYOKUYO CO.,LTD.","stock_symbol":"1301.T","date":"2007-01-09","time":"15:00:00.000000","close":"2388.023438000000000000","volume":"28800.000000000000000000","active":"1","exchange_id":"0"},{"id":"5","exchange_symbol":"TSE","currency":"JPY","stock_id":"1","stock_name":"KYOKUYO CO.,LTD.","stock_symbol":"1301.T","date":"2007-01-10","time":"15:00:00.000000","close":"2369.071045000000000000","volume":"27800.000000000000000000","active":"1","exchange_id":"0"},{"id":"6","exchange_symbol":"TSE","currency":"JPY","stock_id":"1","stock_name":"KYOKUYO CO.,LTD.","stock_symbol":"1301.T","date":"2007-01-11","time":"15:00:00.000000","close":"2369.071045000000000000","volume":"25500.000000000000000000","active":"1","exchange_id":"0"},{"id":"7","exchange_symbol":"TSE","currency":"JPY","stock_id":"1","stock_name":"KYOKUYO CO.,LTD.","stock_symbol":"1301.T","date":"2007-01-12","time":"15:00:00.000000","close":"2378.546875000000000000","volume":"28100.000000000000000000","active":"1","exchange_id":"0"},{"id":"8","exchange_symbol":"TSE","currency":"JPY","stock_id":"1","stock_name":"KYOKUYO CO.,LTD.","stock_symbol":"1301.T","date":"2007-01-15","time":"15:00:00.000000","close":"2397.500244000000000000","volume":"23400.000000000000000000","active":"1","exchange_id":"0"}];
data.forEach(e => {
e.date = parseDate(e.date);
e.value = +e.close;
});
var xExtent = d3.extent(data, function(d) { return d.date; });
x.domain(xExtent);
zoom.translateExtent([[x(xExtent[0]), -Infinity], [x(xExtent[1]), Infinity]])
y.domain([0, d3.max(data, function(d) { return d.value; })]);
yGroup.call(yAxis).select(".domain").remove();
areaPath.datum(data);
zoomRect.call(zoom.transform, d3.zoomIdentity);
function zoomed() {
var xz = d3.event.transform.rescaleX(x);
xGroup.call(xAxis.scale(xz));
areaPath.attr("d", area.x(function(d) { return xz(d.date); }));
}
<svg width="960" height="500"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
Hope this makes sense. Also, I'm setting the x domain to the xExtent that is computed from the data. Play around with it to see the difference.
Somehow the load function is of a different type and uses the following format.
d3.json("api.php", function(data) {
data.forEach(e => {
e.date = parseDate(e.date);
e.value = +e.close;
});
var xExtent = d3.extent(data, function(d) { return d.date; });
zoom.translateExtent([[x(xExtent[0]), -Infinity], [x(xExtent[1]), Infinity]])
y.domain([0, d3.max(data, function(d) { return d.value; })]);
yGroup.call(yAxis).select(".domain").remove();
areaPath.datum(data);
zoomRect.call(zoom.transform, d3.zoomIdentity);
});

Loading webpage incompletely Phantomjs

I have problems capturing and loading the webpage:
https://myaccount.nytimes.com/auth/login
The username and password fields as well as the submit button are missing. What could be the reason? Thanks
As you can see the code listed below waits for each and all the resources to be loaded, one by one.
I did not write the code, however it is excellent and tested by many. The original can be found here:
https://gist.github.com/cjoudrey/1341747
(ALL the credits to the guy who wrote it.)
var resourceWait = 3000,
maxRenderWait = 30000,
url = 'https://myaccount.nytimes.com/auth/login'; //'https://twitter.com/#!/nodejs';
var page = require('webpage').create(),
count = 0,
forcedRenderTimeout,
renderTimeout;
page.viewportSize = { width: 1280, height : 1024 };
function doRender() {
page.render('twitter.png');
phantom.exit();
}
page.onResourceRequested = function (req) {
count += 1;
console.log('> ' + req.id + ' - ' + req.url);
clearTimeout(renderTimeout);
};
page.onResourceReceived = function (res) {
if (!res.stage || res.stage === 'end') {
count -= 1;
console.log(res.id + ' ' + res.status + ' - ' + res.url);
if (count === 0) {
renderTimeout = setTimeout(doRender, resourceWait);
}
}
};
page.open(url, function (status) {
if (status !== "success") {
console.log('Unable to load url');
phantom.exit();
} else {
forcedRenderTimeout = setTimeout(function () {
console.log(count);
doRender();
}, maxRenderWait);
}
});

Vue js, cant pass data

I have simple deposit calc. Here is the code.
app.js:
el: '#calcbox',
data: {
newCalc: {
summ: '50000',
currency: 'USD',
duration: '',
percents: '',
},
calcResult: '',
},
computed: {
percents() {
var id = $("#deposit_id").val();
var url = "/get_percent/"+ id + '/' + this.newCalc.currency + '/' + this.newCalc.duration;
this.$http.get(url, function(response){
return this.newCalc.percents = response;
});
},
calcResult() {
var deposit_id = $("#deposit_id").val();
var url = "/api/calc/"+ deposit_id + '/' + this.newCalc.summ + '/' + this.newCalc.currency + '/' + this.newCalc.duration;
this.$http.get(url, function(response){
return this.calcResult = response;
});
}
},
frontend:
<span>#{{newCalc.percents}}%:</span>
<span>#{{calcResult}}:</span>
So the problem is that result isn't appears in frontend, console.log shows the correct result.
Percentage value is showing well.
calcResult() {
var deposit_id = $("#deposit_id").val();
var url = "/api/calc/"+ deposit_id + '/' + this.newCalc.summ + '/' + this.newCalc.currency + '/' + this.newCalc.duration;
this.$http.get(url, function(response){
return this.calcResult = response;
});
}
add .bind(this)
calcResult() {
var deposit_id = $("#deposit_id").val();
var url = "/api/calc/"+ deposit_id + '/' + this.newCalc.summ + '/' + this.newCalc.currency + '/' + this.newCalc.duration;
this.$http.get(url, function(response){
return this.calcResult = response;
}.bind(this));
}
Or use fat arrow notation since you're using ES6 syntax
calcResult() {
var deposit_id = $("#deposit_id").val();
var url = "/api/calc/"+ deposit_id + '/' + this.newCalc.summ + '/' + this.newCalc.currency + '/' + this.newCalc.duration;
this.$http.get(url, response => {
return this.calcResult = response;
});
}
the this in the .then callback is not the same context as the one outside or within your vue method

Raphael-js drag and click events inaccurate after browser resize

I've created a radial dial using the Raphael-js library and it works as should on page load. It's embedded in a responsive layout so I want it to resize according to it's container, which it does. However, the new container size makes the mouse events inaccurate. When I resize it back to what it was on page load, it works fine.
function RadialDial(paperId, opts) {
var thisObj = this;
this.dialParent = document.querySelector(paperId);
this.divPaper = this.dialParent.querySelector('.radialDial');
this.divPaperW = this.divPaper.clientWidth;
this.scaleRatio = this.divPaperW / 250;
this.outputEle = this.dialParent.querySelector('.dialOutput .val');
this.btnPlus = this.dialParent.querySelector('.btnPlus');
this.btnMinus = this.dialParent.querySelector('.btnMinus');
this.debug = this.dialParent.querySelector('.debug');
this.opts = {
dialCenter: this.divPaperW / 2,
dialRadius: this.divPaperW / 2,
startA: 155,
endA: 25,
arcCentralA: 230,
maxRange: 12,
minRange: 3,
postText: false,
rangeSteps: 3
}
this.currNeedleA;
this.rangeAngles = [];
this.setOptions(opts);
this.paper = Raphael(this.divPaper, this.opts.dialRadius * 2, this.opts.dialRadius * 2);
this.rangeDivisions = Raphael.rad(this.opts.arcCentralA / (this.opts.maxRange - this.opts.minRange));
this.arcStartX = (this.opts.dialCenter + ((this.opts.dialRadius - (30 * this.scaleRatio)) * Math.cos(Raphael.rad(this.opts.startA)))).toString();
this.arcStartY = (this.opts.dialCenter + ((this.opts.dialRadius - (30 * this.scaleRatio)) * Math.sin(Raphael.rad(this.opts.startA)))).toString();
var currSectorX = this.arcStartX;
var currSectorY = this.arcStartY;
var dialFaceAtts = (Raphael.svg) ? {fill: "r#ffffff-#ffffff:85-#999999:75-#cccccc:57-#999999", stroke: "none"} : {fill: "#ffffff", stroke: "#999999", "stroke-width": (1 * this.scaleRatio)};
this.dialFace = this.paper.circle(this.opts.dialCenter, this.opts.dialCenter, this.opts.dialRadius).attr(dialFaceAtts);
var dialFaceRim = this.paper.circle(this.opts.dialCenter, this.opts.dialCenter, (102 * this.scaleRatio)).attr({fill: "none", "stroke-width": (8 * this.scaleRatio), stroke: "#eeeeee", "stroke-opacity": 0.4});
var currSectorAngle = Raphael.rad(this.opts.startA);
var rangeSet = this.paper.set();
for (var i = this.opts.minRange; i <= (this.opts.maxRange); i++) {
currSectorX = (this.opts.dialCenter + ((this.opts.dialRadius - (40 * this.scaleRatio)) * Math.cos(currSectorAngle))).toString();
currSectorY = (this.opts.dialCenter + ((this.opts.dialRadius - (40 * this.scaleRatio)) * Math.sin(currSectorAngle))).toString();
if (i % this.opts.rangeSteps == 0) {
var rangeTxt = this.paper.text(currSectorX, currSectorY, i).attr({fill: "#00a2d8", "font-size": (22 * this.scaleRatio).toString()});
rangeSet.push(rangeTxt);
this.rangeAngles[i] = Raphael.deg(this.rangeDivisions * (i - (this.opts.minRange)));
}
currSectorAngle = currSectorAngle + this.rangeDivisions;
}
this.clickArea = this.paper.circle(this.opts.dialCenter, this.opts.dialCenter, this.opts.dialRadius).attr({fill: "red", "fill-opacity": 0, stroke: "none"});
this.needle = this.paper.path("M" + (this.arcStartX).toString() + "," + (this.arcStartY).toString() +
"L" + (this.opts.dialCenter * (138.89401 / this.opts.dialCenter) * this.scaleRatio).toString() + "," + (this.opts.dialCenter * (107.45764 / this.opts.dialCenter) * this.scaleRatio).toString() +
"L" + (this.opts.dialCenter * (147.34637 / this.opts.dialCenter) * this.scaleRatio).toString() + "," + (this.opts.dialCenter * (125.5838 / this.opts.dialCenter) * this.scaleRatio).toString() + "z").attr({fill: '#0058b6', stroke: "none"});/* */
var needleLine = this.paper.path("M" + (this.opts.dialCenter + (18 * this.scaleRatio)).toString() + ' ' + (this.opts.dialCenter - (8 * this.scaleRatio)).toString() + ", L" + this.arcStartX + "," + this.arcStartY).attr({stroke: "#ffffff", "stroke-width": .7});
var centerCircle = this.paper.circle(this.opts.dialCenter, this.opts.dialCenter, (12 * this.scaleRatio)).attr({fill: "#0058b6", stroke: "none"});
this.needleSet = this.paper.set();
this.needleSet.push(this.needle, needleLine);
this.dialSet = this.paper.set();
this.dialSet.push(dialFaceRim, this.dialFace, this.clickArea, this.needleSet, rangeSet, centerCircle, needleLine);
this.paper.setViewBox(0, 0, this.opts.dialRadius * 2, this.opts.dialRadius * 2, true);
this.paper.canvas.setAttribute('preserveAspectRatio', 'none');
this.needleSet.push(this.needle);
this.needleSet.data('thisObj', thisObj);
this.needleSet.data('paperObj', this.paper.canvas);
this.setNeedleDrag();
this.dialFaceClick();
}
RadialDial.prototype = {
constructor: RadialDial,
setOptions: function (opts) {
for (key in opts) {
if (!opts.hasOwnProperty(key)) {
continue;
}
this.opts[key] = opts[key];
}
},
drawDial: function () {
},
elePosition: function (ele) {
var eleX = 0;
var eleY = 0;
while (ele) {
eleX += (ele.offsetLeft - ele.scrollLeft + ele.clientLeft);
eleY += (ele.offsetTop - ele.scrollTop + ele.clientTop);
ele = ele.offsetParent;
}
return {x: eleX, y: eleY};
},
moveNeedle: function (dx, dy, x, y, e) {
var classObj = this.data('thisObj');
var rectObject = classObj.divPaper.getBoundingClientRect();
var paperXY = classObj.elePosition(classObj.divPaper);
var mouseX, mouseY;
mouseX = e.clientX - rectObject.left;
mouseY = e.clientY - rectObject.top;
var needleA = Raphael.angle(classObj.opts.dialCenter, classObj.opts.dialCenter, classObj.needle.getPointAtLength(classObj.needle.getTotalLength())['x'], classObj.needle.getPointAtLength(classObj.needle.getTotalLength())['y']);
var newA = Raphael.angle(classObj.opts.dialCenter, classObj.opts.dialCenter, mouseX, mouseY);
var rotateAngle = (360 - needleA) + newA;
if (!(newA > (360 - classObj.opts.startA) && newA < (360 - classObj.opts.endA))) {
classObj.needleSet.transform('r' + rotateAngle + "," + classObj.opts.dialCenter + "," + classObj.opts.dialCenter);
}
},
setNeedleDrag: function () {
var startDrag = function () {
}, dragger = this.moveNeedle,
endDrag = this.findNearestStep;
this.needleSet.drag(dragger, startDrag, endDrag);
},
dialFaceClick: function () {
var classObj = this;
this.clickArea.node.onclick = function (e) {
var e = e || window.event;
var rectObject = classObj.divPaper.getBoundingClientRect();
var mouseX, mouseY;
mouseX = e.clientX - rectObject.left;
mouseY = e.clientY - rectObject.top;
var needleA = Raphael.angle(classObj.opts.dialCenter, classObj.opts.dialCenter, classObj.needle.getPointAtLength(classObj.needle.getTotalLength())['x'], classObj.needle.getPointAtLength(classObj.needle.getTotalLength())['y']);
var newA = Raphael.angle(classObj.opts.dialCenter, classObj.opts.dialCenter, mouseX, mouseY);
var rotateAngle = (360 - needleA) + newA;
if (!(newA > (360 - classObj.opts.startA) && newA < (360 - classObj.opts.endA))) {
classObj.needleSet.transform('r' + rotateAngle + "," + classObj.opts.dialCenter.toString() + "," + classObj.opts.dialCenter.toString());
}
classObj.findNearestStep(classObj);
return false;
}
},
findNearestStep: function (obj) {
var classObj = (obj.target || obj.srcElement) ? this.data('thisObj') : obj;
var currVal = Math.round((Raphael.rad(classObj.needle.matrix.split().rotate) * ((classObj.opts.maxRange - classObj.opts.minRange) / Raphael.rad(classObj.opts.arcCentralA))) + classObj.opts.minRange);
var nextVal = currVal;
var prevVal, newA, index;
if (currVal % classObj.opts.rangeSteps != 0) {
while (nextVal % classObj.opts.rangeSteps != 0) {
nextVal = nextVal + 1;
}
if ((nextVal - currVal) > (classObj.opts.rangeSteps / 2)) {
nextVal = nextVal - classObj.opts.rangeSteps;
}
index = nextVal;
} else {
index = currVal;
}
newA = classObj.rangeAngles[index];
classObj.needleSet.transform('r' + (newA) + "," + classObj.opts.dialCenter + "," + classObj.opts.dialCenter);
}
}
Here is my fiddle, http://jsfiddle.net/fiddle_fish/rvLo1cuy/ , dragging the needle makes it follow the mouse pointer closely. Now click the "Resize container" link, whilst the needle still moves it doesn't follow the pointer closely. It seems the resize has created an offset for the mouse event target area.
I've tried changing the viewbox settings, width/height values,removing events and reapplying them, deleting the dial on resize and redrawing the dial but nothing works.
Tried, raphael js, calculate setViewBox width height to fix window
and, raphael js, resize canvas then setViewBox to show all elements
Neither works. :(
I sussed this out. I've multiplied the mouse x-y coordinates with a ratio based on the paper size onload/resize. Works a treat :)
I just encountered the same issue. Basically, on window resize I recalculate the "scale" i.e. the ratio of the svg element's viewBox to its current height/width.
Here's my solution:
var scale = {
x:1,
y:1
}
$(window).resize(function(){
scale = getScale(paper);
})
function getScale(paper){
var x = paper.canvas.viewBox.baseVal.width/$(paper.canvas).width();
var y = paper.canvas.viewBox.baseVal.height/$(paper.canvas).height();
return {
x:x,
y:y
}
}
and then in my "move" function, I added a multiplier to dx and dy:
var move = function (dx, dy,x,y) {
var X = this.cx + dx * scale.x,
Y = this.cy + dy * scale.y;
this.attr({cx: X, cy: Y});
}
For context, the move function is used like so:
var start = function(){
this.cx = this.attr("cx"),
this.cy = this.attr("cy");
}, move = function (dx, dy,x,y) {
var X = this.cx + dx * scale.x,
Y = this.cy + dy * scale.y;
this.attr({cx: X, cy: Y});
}
raphael_element.drag(move,start);
Note that there's some JQuery thrown in here that you could easily do without.

KineticJs-how to update x and y position of the multiple images after resizing the stage layer

As I am new to KineticJs so, I have tried implementing the functionality using Kinectic js for drawing the multiple image on different- different x and y. Now I wanted to resize the stage layer or canvas. I have done that by using the code given below
window.onresize = function (event) {
stage.setWidth(($('#tab' + tabId).innerWidth() / 100) * 80);
var _images = layer.getChildren();
for (var i = 0; i < _images.length; i++) {
if (typeof _images[i].getId() != 'undefined') {
//alert(stage.getScale().x);
_images[i].setX(_images[i].getX() * stage.getScale().x);
layer.draw();
}
}
}
but now the problem is the are being defined and now if browser resize than stage is resized but the images on the prev x and y are fixed . I would like to keep them fixed on the position on resizing of stage layer or canvas.Here are the link of the image before resize and after resizing.beforeresize and afterResize .
Here is my entire code given below:-
$("#tabs li").each(function () {
$(this).live("click", function () {
clearInterval(_timer);
var tabname = $(this).find("a").attr('name');
tabname = $.trim(tabname.replace("#tab", ""));
var tabId = $(this).find("a").attr('href');
tabId = $.trim(tabId.replace("#", ""));
$.ajax({
url: "/Home/GetTabsDetail",
dataType: 'json',
type: 'GET',
data: { tabId: tabId },
cache: false,
success: function (data) {
var bayStatus = [];
var i = 0;
var image_array = [];
var BayExist = false;
var BayCondition;
var imgSrc;
var CanvasBacgroundImage;
var _X;
var _bayNumber;
var _Y;
var _ZoneName;
$(data).each(function (i, val) {
i = i + 1;
if (!BayExist) {
bayStatus = val.BayStatus;
CanvasBacgroundImage = val.TabImageLocation;
BayExist = true;
}
$.each(val, function (k, v) {
if (k == "BayNumber") {
BayCondition = bayStatus[v];
_bayNumber = v;
if (BayCondition == "O")
imgSrc = "../../images/Parking/OccupiedCar.gif"
else if (BayCondition == "N")
imgSrc = "../../images/Parking/OpenCar.gif";
}
if (k == "BayX")
_X = v;
if (k == "BayY")
_Y = v;
if (k == "ZoneName")
_ZoneName = v;
});
image_array.push({ img: imgSrc, xAxis: _X, yAxis: _Y, toolTip: _bayNumber, ZoneName: _ZoneName });
});
var imageUrl = CanvasBacgroundImage;
if ($('#tab' + tabId).length) {
// $('#tab' + tabId).css('background-image', 'url("../../images/Parking/' + imageUrl + '")');
var stage = new Kinetic.Stage({
container: 'tab' + tabId,
width: ($('#tab' + tabId).innerWidth() / 100) * 80, // 80% width of the window.
height: 308
});
window.onresize = function (event) {
stage.setWidth(($('#tab' + tabId).innerWidth() / 100) * 80);
}
$('#tab' + tabId).find('.kineticjs-content').css({ 'background-image': 'url("../../images/Parking/' + imageUrl + '")', 'background-repeat': ' no-repeat', 'background-size': '100% 100%' });
var layer = new Kinetic.Layer();
var planetOverlay;
function writeMessage(message, _x, _y) {
text.setX(_x + 20);
text.setY(_y + 1);
text.setText(message);
layer.draw();
}
var text = new Kinetic.Text({
fontFamily: 'Arial',
fontSize: 14,
text: '',
fill: '#000',
width: 200,
height: 60,
align: 'center'
});
var opentooltip = new Opentip(
"div#tab" + tabId, //target element
"dummy", // will be replaced
"", // title
{
showOn: null // I'll manually manage the showOn effect
});
Opentip.styles.win = {
borderColor: "black",
shadow: false,
background: "#EAEAEA"
};
Opentip.defaultStyle = "win";
// _timer = setInterval(function () {
for (i = 0; i < image_array.length; i++) {
img = new Image();
img.src = image_array[i].img;
planetOverlay = new Kinetic.Image({
x: image_array[i].xAxis,
y: image_array[i].yAxis,
image: img,
height: 18,
width: 18,
id: image_array[i].toolTip,
name: image_array[i].ZoneName
});
planetOverlay.on('mouseover', function () {
opentooltip.setContent("<span style='color:#87898C;'><b>Bay:</b></span> <span style='color:#25A0D3;'>" + this.getId() + "</span><br> <span style='color:#87898C;'><b>Zone:</b></span><span style='color:#25A0D3;'>" + this.getName() + "</span>");
//writeMessage("Bay: " + this.getId() + " , Zone: " + this.getName(), this.getX(), this.getY());//other way of showing tooltip
opentooltip.show();
$("#opentip-1").offset({ left: this.getX(), top: this.getY() });
});
planetOverlay.on('mouseout', function () {
opentooltip.hide();
// writeMessage('');
});
planetOverlay.createImageHitRegion(function () {
layer.draw();
});
layer.add(planetOverlay);
layer.add(text);
stage.add(layer);
}
// clearInterval(_timer);
//$("#tab3 .kineticjs-content").find("canvas").css('background-image', 'url("' + imageUrl + '")');
// },
// 500)
}
}
,
error: function (result) {
alert('error');
}
});
});
});
I want to keep the icons on the position where they were before resizing. I have tried but could not get the right solution to get this done.
How can How can I update x,y position for the images . Any suggestions would be appreciated.
Thanks is advance.
In window.resize, you're changing the stage width by a scaling factor.
Save that scaling factor.
Then multiply the 'x' coordinate of your images by that scaling factor.
You can reset the 'x' position of your image like this:
yourImage.setX( yourImage.getX() * scalingFactor );
layer.draw();
In the above mentioned code for window.onresize. The code has been modified which as follow:-
window.onresize = function (event) {
_orignalWidth = stage.getWidth();
var _orignalHeight = stage.getHeight();
// alert(_orignalWidth);
// alert($('#tab' + tabId).outerHeight());
stage.setWidth(($('#tab' + tabId).innerWidth() / 100) * 80);
//stage.setHeight(($('#tab' + tabId).outerHeight() / 100) * 80);
_resizedWidth = stage.getWidth();
_resizedHeight = stage.getHeight();
// alert(_resizedWidth);
_scaleFactorX = _resizedWidth / _orignalWidth;
var _scaleFactorY = _resizedHeight / _orignalHeight;
//alert(_scaleFactor);
var _images = layer.getChildren();
for (var i = 0; i < _images.length; i++) {
if (typeof _images[i].getId() != 'undefined') {
//alert(stage.getScale().x);
_images[i].setX(_images[i].getX() * _scaleFactorX);
//_images[i].setY(_images[i].getY() * _scaleFactorY);
layer.draw();
}
}
}