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.
Related
I am using image-js.
I have looked at the documentation and I do not see a function called normalize or histogram stretching. However I do see some histogram functions. Can I use the histogram functions to do a normalization on a grayscale PNG array of height values?
The image array is values of heights from range 0 - 255 black being lowest height white highest. I am using this array to create a grayscale heightmap image.
Clarify:
By normalize I mean normalizing an image colors in this case the grayscale. Like this project but using image-js https://www.npmjs.com/package/#jimp/plugin-normalize
The normalization I want to accomplished is described in this GIMP doc and listed below
From GIMP: 8.10. Normalize
The Normalize command scales the brightness values of the active layer so that the darkest point becomes black and the brightest point becomes as bright as possible, without altering its hue. This is often a “magic fix” for images that are dim or washed out. “Normalize” works on layers from RGB, Grayscale, and Indexed images.
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.
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
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 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);