Loading shapes into d3 - javascript

I have a set of shapes that I want to use in D3. They have defined borders and are in png format. I can't figure out how to use them though. This seems like it should be supported, but I've searched around the web and on SO and can't seem to find out how to do so. Can someone point me in the right direction please?

SVG shapes are loaded as paths or, in the case of predefined shapes like circles, ellipses and rectangles, as those shapes with attributes that determine their size.
If you're loading pngs, you need to load an image, like this:
newImage = svg.append("svg:image")
.attr("xlink:href", "../yourImageNameAndPath.png")
.attr("width", 280)
.attr("height", 280);

Related

Images not Generating D3

Here is my problem. My graph currently looks like this: Which is dandy. However, I want the black squares on top to be filled with pictures. Luckily I have a CSS file that has pictures linked with classes. I also have a JSON file that contains all the class names. All those class names are assigned to the squares and I can see the picture in the inspect element on Chrome. The only issue is the pictures don't appear in the square. (Also my axises broke, but that is secondary concern). CSS, JSON
This is where I'm assigning classes and creating the rectangles.
svg.selectAll(".div")
.data(data.chartData, function(d){return d.vNm;})
.enter().append("rect")
.attr("x", function(d){
return x(d.vNm);
})
.attr("y", function(d){
return (y(d.values.reduce(function(sum, d){
return sum + d.amount;
}, 0))) - 64.5;
})
.attr("width", 43)
.attr("height", 43)
.attr("class", function(d){return d.vId;})
.style("fill", function(d) { return segColor(d.data.type); });
One approach to solve your problem is to use html elements like div for the images above the chart instead of svg elements, so you can use the full power of css.
Luckily you don't need to calculate the position of those html elements by yourself, there are some libraries that help you position the images correctly above the bars in the chart.
Check out https://popper.js.org/ for example, you can just call its API for each bar you render using d3.js:
var popper = new Popper(barElement, onPopper, {
placement: 'top'
});
SVG elements do not follow exactly the same CSS rules as typical HTML elements.
In your case, background-image doesn't work.
The least painful way to achieve the effect would be to embed an <image> tag after the <rect>:
<image width="100" height="100" xlink:href="data:image/png;base64,...">
It means that you have to modify your JSON to store the image's base64 data in there instead of CSS.

d3.js - translating multiple labels without rotation

I'm relatively new to d3 and am attempting to augment a radar diagram such that it rotates on click and the next axis points directly upwards.
The example in which I am working from is found here.
Problem
Currently, when the svg is clicked, I rotate the entire svg by a specified angle based on the number of axis there are in the graph. Since I am rotating the entire svg the labels that are appended to each axis will rotate also (as shown in the following image).
The text is currently unreadable and I want to achieve a solution which is more similar to the following image:
I would like each label to stay with their respective axis and also stay upright after the svg has been rotated, but I am finding it hard to achieve this.
JSFIDDLE
This JSFIDDLE is the stripped down code of the current implementation (I left out the numerous failed attempts) and the following code, which would be in the 'rotateOnClick' function is the closest I have came to a solution so far (I haven't used the index i variable so far but my intention was to swap the position of labels with each other when clicked).
g.selectAll(".legend")
.transition()
.duration(cfg.rotateDuration)
.attr("transform", function(d, i){
if (i<total) i++;
else i = 0;
return "rotate("+newAngle*-1+", "+(cfg.w/2)+",0 )"
})]
.ease(cfg.easeFunction);
I need to manipulate each label individually and stay aligned with its respective axis and also for it to work with a dynamic number of axis.
I greatly appreciate any help and insight.

How to embed bitmap into D3js generated SVG code?

Given access to suitable topojson and bitmaps, I use the topoJSON file to generate a SVG viz via D3js. Then I append a bitmap to it via :
// Append bitmap
svg.append("image")
.attr("xlink:href", "./myimage.png")
.attr("width", width)
.attr("height", height)
.attr("class", "bg");
But this actually just add a link toward the image. Also, when I select the dataviz DOM, and save it as SVG, I don't have the bitmap binary, but just the bitmap's link.
Is it possible, and how to really embed my .png binary into my SVG DOM via D3js or javascript ?
See also: https://rugger-demast.codio.io/front/_location_map-en-wikiatlas.html , where you can try to download the SVG.
This example shows how to draw an image to a canvas element and use the .toDataURL function to get a snapshot of this canvas into a string that you can then use as the xlink:href attribute:
http://bl.ocks.org/emeeks/707681f1f5b4a2063d6e

Zooming in on a map with elements in d3

I have a zoomable map of the world with a single point on it (in reality there are multiple points from a separate resource but I have simplified it). The block is here.
When I try and zoom in it jumps to a certain scale and then usually doesn't allow any more zooming movements. I have experimented with various different values for the transition, scale and scaleExtent taken from this example and this one (with the latter being very close to what I want overall) but nothing has worked. It seems to get quite close to the actual size at height/6 for minimum zoom but still behaves badly.
I suspect the main problem is with scaleExtent. I actually want the minimum zoom to be the size of the map and so it isn't possible to pan around unless zoomed in.
The other problem is, as you can see in the bl.ock that the circle disappears when you zoom. I want the circle to maintain position and size (so it doesn't get bigger when I zoom).
Can any one help with
The zoom problem on the map, so the map minimum zoom is the actual size map and I can zoom in to about 6x that
Preventing the map from panning unless zoomed in
Maintaining the size and position of the circle on the map
I've put an example of what I think you're after on this bl.ock which is based on the first example you pointed to. It looks as though this line .scaleExtent([height, height*6]) is limiting the scale (well that the purpose of it) to something that was incompatible with your expectations and the initial scale you set, so when you zoom in past a certain level (in this case height) you get stick between height and height * 6.
If you set your minimum zoom and your initial zoom I think you'll get around some of your issues.
The issue with the dots was that they weren't referenced in the redraw function, so when you zoomed d3 / the browser didn't know what to do with them. In my example I've put the following snippet in to address this:
g.selectAll("circle")
.attr("cx", function (d,i) { return projection(d)[0]; })
.attr("cy", function (d,i) { return projection(d)[1]; })
.attr("r", "10px")
.style("fill", "red");

D3: Grayscale image display driven by 2D array data

Does anybody know how to display a greyscale image, i.e. a 2-D array of pixel intensities,using d3? I can't seem to find any examples of it anywhere, is it going to be tricky? Any help / links / pointers appreciated!
If just want to display an image, use the image element and the "xlink:href" attribute. For example:
svg.append("image")
.attr("xlink:href", "my.png")
.attr("width", 960)
.attr("height", 500);
If you want to colorize a grayscale image, then see this colorized heightmap example which uses quantiles to create a diverging color scale, and with HCL interpolation for better perception:
If you have your data in some other representation, these examples might be useful:
heatmap from CSV using SVG rect elements
heatmap from JSON using Canvas
Lastly, if you have individual samples rather than a precomputed 2D histogram, you’ll need to bin the data before generating one of the above heatmaps.

Categories

Resources