I'm trying to get the height of a DOM object but it doesn't show the actualy height. If you refer the below example, the height always some default number on IE8 compatibility view, but on firefox it shows dynamic values.
$("div.span3").each(function() {
var he = $(this).height();
if (he > hie) {
hie = he;
highestempty = $(this);
}
});
Related
I am working on this pie-chart. This is what I would like to happen as the user clicks on a wedge of the pie:
1) An external svg is loaded and inserted in the div on the right (DONE)
1.1) The svg has the following structure
<svg id="Ebene_1">
<circle></circle>
<path></path>
<svg>
2) Change circle's fill according to a color() function which assign a color depending on the wedge's index
2) Change path's fill to white
This is the relevant code I have so far:
descrImg = d3.select("#descrImg"); //select the target div
descrImg.select("svg").remove(); //removes previous image
descrImgURI = d.data.descrImg; //extract svg's URI from data
d3.xml(descrImgURI, "image/svg+xml", function(error, xml) {
if (error) throw error;
var svg= xml.documentElement;
descrImg.node().appendChild(svg); //append svg
var a = document.getElementById("Ebene_1"); //select svg
var b = a.getElementsByTagName("cicle"); //select circle
var c = a.getElementsByTagName("path"); //select path
d3.select(c).attr("fill", "white"); //change path's fill attribute
});
When I click on a wedge, the svg is loaded correctly but the path's fill is not changed. I get the following error (same happens if I use style instead of attr):
TypeError: this.setAttribute is not a function
Other options:
//Option 1
var c = d3.select(document.getElementById("#Ebene_1").contentDocument).selectAll("path");
d3.select(c).attr("fill", "yellow");
//Option 2
var c = d3.select(document.getElementById("Ebene_1").contentDocument).selectAll("path");
d3.select(c).attr("fill", "yellow");
//Both return the error
TypeError: document.getElementById(...) is null
//while Option 3
var c = document.getElementById("Ebene_1").contentDocument.getElementsByTagName("path");
d3.select(c).attr("fill", "yellow");
//Returns
TypeError: document.getElementById(...).contentDocument is undefined
I do not know if this matters, but when I inspect circle or fill I see their attributes are "locked" (a bit hard to see but there is a lock next to attributes)
Any ideas?
I have managed to solve the problem. This is the code that works:
d3.xml(descrImgURI, "image/svg+xml", function(error, xml) {
if (error) throw error;
var svg= xml.documentElement;
descrImg.node().appendChild(svg);
var a = document.getElementById("Ebene_1");
var b = a.getElementsByTagName("circle")[0];
var c = a.getElementsByTagName("path");
// d3.select(b).attr("fill", function (d, i) {
// var scale = colorMap[d.data.categoria];
// if (scale) return scale(d.data.catIndex);
// })
d3.select(b).attr("fill", fillColor);
d3.selectAll(c).attr("fill", "white");
});
getElementsByTagName returns a collection of items, regardless of how many items will be in the collection.
Therefore, in the case of b (i.e. the circle) I had to select the first element of the connection (through index [0]).
The path(s) in c, on the other hand, can be collectively modified by using d3.selectAll. If I use the same method as with b, then only the first set of paths would be modified and, at least in my case, this would leave some drawings partly uncolored.
Hope this helps!
The Firefox drawWindow()-Function expects as first parameter a XUL content-window as provided by the low-level api tab utils.
However with the introduction of the multiprocess architecture in Firefox (codenamed electrolysis or e10s) directly accessing tabs via the low-level api is no longer possible. While there are compatibility shims available, it is explicitly stated that they do not support plattform APIs that expect DOM objects.
On the other hand drawWindow() cannot be used in a content script since it is "chrome only".
So my questions are these:
How am I supposed to use drawWindow() if I cannot use it outside of chrome and cannot get a contentWindow-object within chrome?
What are my other options to let my addon take screenshots of websites within multiprocess Firefox?
Our current approach is based on the answer to this SO question. However it will not work with multiprocess Firefox
The solution to using drawWindow() was indeed to use framescripts as Noitidart suggested in the comments. The framescript I use for the screenshots looks like this:
addMessageListener("fs/make_screenshot_from_rectangle", makeScreenshot);
function makeScreenshot(payload) {
var rectangle = payload.data;
var startX = rectangle.startX || 0;
var startY = rectangle.startY || 0;
var width = rectangle.width || content.innerWidth;
var height = rectangle.height || content.innerHeight;
// Create canvas to draw window unto
var canvas = content.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
canvas.width = width;
canvas.height = height;
// Create context for drawing, draw the old window unto the canvas
var context = canvas.getContext("2d");
context.drawWindow(content, startX, startY, width, height, "rgb(255,255,255)");
// Save context as png
var image = canvas.toDataURL('image/png');
sendAsyncMessage("got-screenshot", image);
}
And it is called from a chrome-script with the following function:
function (rectangle) {
var tab = require("sdk/tabs").activeTab;
var xulTab = require("sdk/view/core").viewFor(tab);
var xulBrowser = require("sdk/tabs/utils").getBrowserForTab(xulTab);
var browserMM = xulBrowser.messageManager;
if ( /* framescript not yet attached to tab */ ) {
browserMM.loadFrameScript(require("sdk/self").data.url("content-scripts/frame-script.js"), false);
... // do something to remember that there is a framescript attached to the tab
browserMM.addMessageListener("got-screenshot", function (payload) {
... // handle the screenshot
});
}
browserMM.sendAsyncMessage('fs/make_screenshot_from_rectangle', rectangle);
}
Relevant reading:
https://developer.mozilla.org/en-US/Add-ons/SDK/Guides/Multiprocess_Firefox_and_the_SDK
https://developer.mozilla.org/en-US/Firefox/Multiprocess_Firefox/Message_Manager/Message_manager_overview#Browser_messa
I've create this scroll panel:
var app = UiApp.createApplication();
var scroll = app.createScrollPanel().setPixelSize(500, 300);
var panel = app.createVerticalPanel();
scroll.add(panel);
app.add(scroll);
spreadsheet.show(app);
But I can't get this scroll panel bigger than setPixelSize(500, 300); because, in this case, the submit button is not shown. How can I increase the size of the panel?
Don't forget you can define the size of the uiApp instance itself, it will probably solve your problem...
function myFunction() {
var spreadsheet = SpreadsheetApp.getActive();
var app = UiApp.createApplication().setHeight(800).setWidth(1500);
var scroll = app.createScrollPanel().setPixelSize(500, 300);
var panel = app.createVerticalPanel();
scroll.add(panel);
app.add(scroll);
spreadsheet.show(app);
}
I have a div, #scrollable, with a scrollbar and I want to scroll to the end.
I can do it by setting the div's "scrollTop" property to the value of the div's "scrollHeight" property thus:
var scrollable = d3.select("#scrollable");
scrollable.property("scrollTop", scrollable.property("scrollHeight"));
but I can't figure out how, if at all, I can tween it.
var scrollheight = scrollable.property("scrollHeight");
d3.select("#scrollable").transition().property("scrollTop", scrollheight);
doesn't work.
Thanks for any ideas.
Regards
You can use a custom d3 tween to transition arbitrary properties like scrollTop.
mbostock's Smooth Scrolling example demonstrates using a custom tween to scroll the entire document.
And here is the example adapted to your context (also viewable interactively on bl.ocks.org):
var scrollable = d3.select("#scrollable");
d3.select("#down").on('click', function() {
var scrollheight = scrollable.property("scrollHeight");
d3.select("#scrollable").transition().duration(3000)
.tween("uniquetweenname", scrollTopTween(scrollheight));
});
function scrollTopTween(scrollTop) {
return function() {
var i = d3.interpolateNumber(this.scrollTop, scrollTop);
return function(t) { this.scrollTop = i(t); };
};
}
So here's what I want to do. I would like to be able to drag an element, and have it dynamically change it's default drag image to a different image when it's over the drop zone.
You are able to set the drag image using dataTransfer.setDragImage method. It exists in the event objects of all of the drag events, including the dragover event.
Some basic code would be:
dropElem.ondragover = function(e) {
if (e.stopPropagation) {
e.stopPropagation(); //Stops some browsers from redirecting.
}
var dragIcon = document.createElement('img');
dragIcon.src = 'image.png';
dragIcon.width = 100;
e.dataTransfer.setDragImage(dragIcon, 0, 0);
};