svg.append("defs")
.append("filter").attr("id", "blur")
.attr("x", "-50%").attr("y", "-50%")
.attr("height", "200%").attr("width", "200%")
.append("feGaussianBlur").attr("in", "SourceGraphic").attr("stdDeviation", 10);
I saw these code in javascript. I try to google, but still can not understand what is a "defs" in js.
BTW, can anyone explain what is a "filter"?
Many thanks!
Looks to me like your code is some implementation of a Gaussian blur filter using SVG. So defs and filter there are really SVG concepts, not so much JavaScript.
defs
SVG allows graphical objects to be defined for later reuse. It is
recommended that, wherever possible, referenced elements be defined
inside of a defs element. Defining these elements inside of a defs
element promotes understandability of the SVG content and thus
promotes accessibility. Graphical elements defined in a defs will not
be directly rendered. You can use a element to render those
elements wherever you want on the viewport.
filter
The filter element serves as container for atomic filter operations.
It is never rendered directly. A filter is referenced by using the
filter attribute on the target SVG element.
feGaussianBlur
The filter blurs the input image by the amount specified in
stdDeviation, which defines the bell-curve.
Documentation from Mozilla
https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs
https://developer.mozilla.org/en-US/docs/Web/SVG/Element/filter
https://developer.mozilla.org/en-US/docs/Web/SVG/Element/feGaussianBlur
Related
I'm using d3 to create an Org Chart, which has some nodes with longer names.
I've managed to modify the width of longer nodes, but have trouble properly placing their children and the lines (paths) to their children.
I tried calculating myself with determineChildXValue(), but that didn't work properly.
Is there a way to initialize the tree with variable widths so it will take care of the calculations of translations for child nodes?
Currently, I'm initializing it with hard-coded node sizes:
var tree = d3.layout.tree().nodeSize([70, 40]);
I've replicated the behavior in this example - expand Departments, then DEPARTMENT STORES to see the overlap.
Thanks in advance!
I consulted a colleague who was able to build a proper fix:
Define the source and target properties (before the projection is set) for the diagonal (paths)
Track the tierDisplacementX and cumulativeDisplacementX
Use these when translating the positions of the child nodes and their paths
See this fiddle to see the working code.
To select all type of "rect" within an svg element we write this
svg.selectAll('rect')
But, here if i want to select everything within a SVG element including rect and circle and images etc and perform some common operation on all of them, how can I do that?
d3 uses css selectors so you want use an * (universal selector):
svg.selectAll('*')
If there's no existing tutorial/wiki, then I'm willing to create one. I've seen the d3.js examples of scatterplot, the 3d cubes, the awesome 3d svg example, 3d force layout and 3d bar graph, but am having a hard time figuring out how to get x3dom syntax translated to d3 syntax.
I've tried making the 3d bar graph an emissive surface like so and it works:
shapesEnter
.append("appearance")
.append("material")
//.attr("diffuseColor", '0.41 0.39 0.03' )
.attr("emissiveColor", '0.41 0.39 0.03')
//.attr("ambientIntensity", '0.0243902' )
.attr("shininess", '0.12' )
.attr("specularColor", '0.94 0.72 0' );
But when trying to apply textures (after commenting out the above code), it doesn't work:
shapesEnter.append("ImageTexture").attr("url", "file:///image1.png").attr("repeatS", "true").attr("repeatT", "true");
My questions are:
1. About how to figure out the x3dom equivalent syntax in d3?
2. How do I get a texture onto the 3d bar? (objective is to have a colour gradient on the bar, and texture seems to be the only way to do it)
D3 is a library to create and manipulate DOM elements based on data. Other libraries can manipulate DOM elements as well, the difference between D3 and other libraries is that D3 bind data elements to DOM elements. If you have a div with ID chart, you can append a x3d element to it and set its attributes:
var div = d3.select('#chart'),
chart = div.append('x3d')
.attr('width', '500px')
.attr('height', '400px');
This will modify the DOM structure of the page:
<div id='chart'>
<x3d width="500px" height="400px"></x3d>
</div>
You can append scenes and transformations using the reference to chart:
// Create the scene ans transform, and set their attributes
var scene = chart.append('scene'),
transform = scene.append('transform');
Until now, you have just manipulated the DOM, but D3 becomes more interesting when you bind selections to data. Let's say we have an array with the definitions for some shapes:
var deg = ['boxShape', 'sphereShape', 'cylinderShape'];
// Create a selection for the shapes that will be created and bind the selection
// to the array of colors
var shapes = transform.selectAll('shape.main-shape')
.data(colors);
// Append the shapes on enter and set some attributes
shapes.enter().append('shape')
.attr('class', 'main-shape');
// Update the 'def' attribute of the shapes, using the contents of the bound array
shapes.attr('def', function(d) { return d; });
I don't know the details about why the texture is not working, but I would recommend to inspect the generated code using the Web Developer Tools of the browser and see if the generated markup is different that you expect. If you can create a jsFiddle with a simple example, it would be easier to help you with the textures. There is a great tutorial on D3 by Scott Murray, to learn the details on data binding and selections. Regards,
I am using D3 render a simple network diagram. And in each node I want to display html content for that foreign object is used. Foreign object is having html inside. The network is getting rendered. But I am not able to view the html content anybody know why it is not rendering the html?
I am using below code.
dom.svg.selectAll('.node').append("foreignObject")
.attr("width", 100)
.attr("height", 100)
.append("xhtml:body").append("xhtml:p")
.style("color", "red")
.text("Object in SVG");
Here is the fiddle
You can't append foreignObjects (or indeed anything) to circle elements. Instead, append them to a container element like gs for example. Fixed here.
I'm using Raphael.js to produce an SVG drawing from Javascript (actually Coffeescript)
However, I'd like to be able to include subdrawings, automatically scaled, by putting them inside a second <svg> tag nested inside the first. Unfortunately the Raphael Paper object which allows me to add rects and paths etc. doesn't have an option for adding svgs.
I've tried to add the tag directly to the DOM in javascript with the following code :
res = document.createElement("svg")
res.setAttribute("x",x)
res.setAttribute("y",y)
res.setAttribute("width",width)
res.setAttribute("height",height)
res.setAttribute("viewBox","0 0 100 100")
res.innerHTML = someInnerSVG
#paper.canvas.appendChild(res)
This seems to update the DOM as expected, adding my new SVG tag as a child of the main outer SVG. However, nothing in this inner actually appears on the screen. (My inner SVG path is scaled within 0 0 100 100 so is within the viewBox.)
The rest of the drawing in the outer SVG, as produced by Raphael, is visible. But nothing of the inner one is.
Should what I'm trying be possible? Any idea what I'm doing wrong?
You should place these sub elements into a Raphael set. From there, you will be able to apply transformations to the set. To transform the set, you would call the transform() method and use the s attribute:
set.transform('s[sx],[sy]');
Where sx is the horizontal scale amount and sy is the vertical scale amount. Remove the brackets when you insert the numbers.
Please refer to the documentation here: http://raphaeljs.com/reference.html#Element.transform
The methods for elements apply to sets because sets are pseudo elements.