I tried to fill rectangles with images. While images appear in Chrome, they do not appear in safari. I do not get any error messages. So I am really confused as to why this is the case, please help me! Alternatively, if you can help with filling rectangles with custom pictures, I'd also happy to hear from you!
function initRectElements(svg, data) {
imgUrl = "image/star/5.png";
d3.select(svg).append("defs")
.append("pattern")
.attr("id", "rating")
.attr("width", rectwidth)
.attr("height", rectheight)
.append("image")
.attr("xlink:href", imgUrl)
var sel = d3.select(svg)
.selectAll('rect.token')
.data(data);
sel.enter().append('rect')
.classed('token', true);
sel.exit().remove();
d3.select(svg).selectAll('rect.token')
.attr('x', function (d){return d
.x})
.attr('y', function (d){return d
.y})
.attr("width", rectwidth)
.attr("height", rectheight)
.attr('fill', "url(#rating)")
}
When you are using custom properties with images - Safari interprets images url another way, for example:
Chrome shows all images, but Safari logs "not allowed to load local resource"
Another example:
Chrome doesn't show all images, but Safari works well
The problem is direction, I don't know why but when you using custom properties and set url - safari add one more dot (".") in your url direction.
you can try the things like
1.-- Add the field !DOCTYPE at the top of your html document or
2.-- if you have image with URL like background-image:url("http://adf.co.us/dm/gs.png");
Then you have to add
image:url("http://www.adf.co.us/dm/gs.png");
i hope it can be helpful for you.
Related
I am building a force-directed graph, and as far as I can tell, I have written the code correctly. The DOM looks exactly right after this code runs. And yet, nothing is displayed.
var type_node_list = typeNodes(data);
shuffle(type_node_list);
initializePosition(type_node_list);
var links = typeLinks(type_node_list);
var svg = d3.select('#root');
var link = svg
.append('g')
.attr('id', 'links')
.selectAll('line')
.data(links)
.enter()
.append('line')
.attr('class', 'link');
var type_nodes = svg
.append('g')
.attr('id', 'nodes')
.selectAll('.node')
.data(type_node_list)
.enter()
.append(createTypeNode);
function updateTypeNodeLocations() {
link
.attr("x1", function(d){return d.source.x;})
.attr("y1", function(d){return d.source.y;})
.attr("x2", function(d){return d.target.x;})
.attr("y2", function(d){return d.target.y;});
type_nodes
.attr('x', nodeX)
.attr('y', nodeY);
}
updateTypeNodeLocations();
/*
var position_the_types = d3.forceSimulation()
.nodes( type_node_list )
.force("charge",d3.forceManyBody().strength(-10))
;
position_the_types.on('tick',updateTypeNodeLocations());
*/
The simulation portion is commented out because I'm trying to get the first part working. When I uncomment it, it only calls the 'tick' event once, even though the processing is clearly not complete. And there is nothing in the JavaScript console to explain it.
See http://jsfiddle.net/jarrowwx/gof5knaj/36/ for the full code.
I had things working this morning, and something changed and now nothing I do seems to work. I checked the D3 github, and the last commit appears to have been 11 days ago, so it's not likely caused by a change to the library.
Has anybody experienced something like this before? Any pointers on what I'm doing wrong? Have I uncovered a D3 bug?
The problem lie in my function createTypeNode.
I created the image element via: document.createElement('image'). That doesn't work. To create an image via JavaScript, one must use Namespaces.
See: Programmatically creating an SVG image element with javascript
I have a very strange behave in my angularjs application.
1) I'm using d3js to draw a nice bar chart
graphG.append("rect")
.attr("id", function (d, i) {
return "bar_" + i;
})
.attr("x", 0)
.attr("y", 0)
.attr("height", barHeight - 1)
.attr("width", function (d, i) {
return rectWidth(d, i);
})
.attr("fill", rectColor);
2) After a data update there is a transition
barG.select("#bar_" + i)
.transition()
.duration(duration)
.attr("fill", rectColor(d))
.attr("width", rectWidth(d, i));
So far the width transition works fine. The color transitions with gradient doesn't work, but this is an another question. It changes the color but without smooth transition.
If i reroute to another page and come back the rect will not be rendered any more. The rect is in the dom. Width attribute got changes. No bar.
After F5 reload every thing is fine again.
And more strange behave: it happens in Chrome, it works fine in Firefox.
Anybody some ideas?
I have found the problem:
the error was that the gradient id (return of rectColor function) was same in both directives. So it seems that there is some caching in Chrome.
Rename the gradient id in one directive fixes the issue.
I have a page that includes a dropdown menu to choose one of several bar charts to display. The page improperly reloads when the dropdown selection is changed. I have narrowed the culprit to this line:
$("svg").remove();
When I comment out that line, the HTML changes without the page reloading. But I need that line (or something similar), because I want the previous chart to go away when the new chart is selected.
I've also tried
d3.select("svg").remove();
but the same thing happens.
I've added
event.preventDefault();
but that doesn't help either.
I've made a jsfiddle to show my relevant HTML and JS/d3.
My page is here if seeing the whole thing will help. Note how the page reloads when the dropdown selection is changed.
(Update Jan. 3: I have followed the suggestions in the comments/answers below, but nothing has helped. I'm still having this problem.)
Nope, your page is not reloading. ( If it does reload you will see a spin icon in most of the browsers title). Like #Mansov told in the comment It is the margin that changes when you .remove() and add the svg.
I was having this same problem. Whenever I refreshed my chart, I was doing a .remove() to the entire svg reference, and then calling my build() function again.
In effect, what was happening was the <div> containing the SVG was collapsing to 0 height, causing the page to scroll back up to fit all the remaining content, and then when I rebuilt the chart the page would remain scrolled at the top.
So what I did was make a "frame" for the chart svg to sit on top of:
//===================================================== Initialize build
function initializeBuild() {
bilSVG = this.d3.select(rawSvg)
.append("svg");
calculateMargins();
bilSVG
.attr("width", width)
.attr("height", height)
.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", width)
.attr("height", height)
.style("opacity", .0)
;
}
and then created a group that held the chart:
//===================================================== build
function build() {
chartGroup = bilSVG
.append("g")
.attr("class","bil chartgroup")
.attr("transform", function(d) {
return "translate(" + width / 2 + "," + width / 2 + ")";
})
.attr("x", width / 2)
.attr("y", width / 2)
;
}
Then when I needed to rebuild the chart, I deleted the group, and not the whole SVG:
//===================================================== rebuild
function rebuild() {
chartGroup = bilSVG.select(".chartgroup");
chartGroup.remove();
build();
}
Hope this helps!
I'm trying to open a new window on button click and draw a simple circle on it.
I can open a window but circle won't appear on it with this code. Any ideas on how to solve this.0
Here is my code:
function drawBarChart(newWindowRoot){
var sampleSVG = d3.select(newWindowRoot)
.append("svg")
.attr("width", 100)
.attr("height", 100);
sampleSVG.append("circle")
.style("stroke", "gray")
.style("fill", "white")
.attr("r", 40)
.attr("cx", 50)
.attr("cy", 50)
.on("mouseover", function(){d3.select(this).style("fill", "aliceblue");})
.on("mouseout", function(){d3.select(this).style("fill", "white");});
}
function createNewPage(){
var button = content.append("button")
.attr("class", "button")
.attr("id", "myButton")
.text("Visualize");
document.getElementById("myButton").onclick = function () {
var newWindow = window.open('');
newWindowRoot = d3.select(newWindow.document.body)
.attr("width","1060px")
.attr("margin","50px auto");
drawBarChart(newWindowRoot);
}
}
When you call drawBarChart(newWindowRoot), you're passing a d3 selection — the result of d3.select(newWindow.document.body) — into that function. That makes sense.
However, from within drawBarChart, you call var sampleSVG = d3.select(newWindowRoot), essentially making a d3 selection of a d3 selection. That doesn't work (unlike what you might expect from jQuery). You should skip that latter d3.select and that'll make your code begin to work. More specifically, that'll make the button appear in the new window, but not the circle.
To make the circle appear, you need to fix another issue: Your fiddle attempts to add the circle to the button, instead of to an SVG (this is different than your example above which isn't trying to create a button).
Here's a working fiddle
By the way, the reason the jsFiddle you linked to didn't work is because the link you embedded was using secure protocol (https) and the jsfiddle functionality that was trying to load d3 is insecure (http), which resulted in a failure to load d3 and in turn an error executing your code.
I am creating a streamgraph, having used the example code from http://bl.ocks.org/mbostock/4060954 as a template.
I draw the streamgraph:
var svg = d3.select("#graph_area").append("svg")
.attr("width", width)
.attr("height", height)
....
svg.selectAll("path")
.data(layers)
.enter().append("path")
.attr("d", function (d) {return area(d.layer);})
Now it seems that I am not allowed to choose a different name from "path" for the DOM element here. If I do, then streamgraph no longer plots. Why is that?
Then I want to add a legend with bullets, but they don't plot. The elements show up in my web inspector (firebug), but their graphical representation is just not there. I figured it might be a similar problem with the DOM element name, but I don't actually know. Here is the code for my bullets:
//draw all the legend bullets and effects
svg.selectAll("bullets")
.data(layers)
.enter().append("bullets")
.attr("cx", 200)
.attr("cy", function(d, i) { return 20 + i*10; })
.style("fill", function(d) { return d.color; })
.attr("r", 5)
I briefly looked at API's for paths here and here, but I didn't find my answers there.
The element names you can use are defined in the SVG specification. This is a specific set (e.g. path, circle) -- using anything else will work in terms of appending the element to the DOM, but the browser won't know how to interpret and render it.
It's the same way in HTML -- there's a specific set of defined element names that browsers know how to render.