1

I have been trying to follow different d3.js tutorials to create my own hexagon mesh.

I have come up to this I need to replace the random colors with images, I read that I need to do something like this:

 var imagePatterns = svg.selectAll('pattern').data(data).
             enter().append('pattern')
             .attr('x',50)
             .attr('y',50)
             .attr('width',1)
             .attr('height',1)
             .append('image').attr("xlink:href", function(d,i){
                 return data[i].img;
             })
            .attr("x", function(d,i){
                 return i+100;
             })
            .attr("y", function(d,i){
                 return i+200;
             })
            .attr("width", 230)
            .attr("height", 230)
            .attr("id", function(d,i){
                 return 'fillImage'+i
             });

I have a data array with 40 images, the number of hexagon of a radius 120 form the topoApi is 40 , I know I need to set my image some how to the center of each hexagon, but with the above code I only see the patterns in the generated html but nothing else

First thing I need to get the images to show on my screen then I should work on positioning them, please help

Ragda Awad
  • 63
  • 8

1 Answers1

1

I've found away to fill the hexagon with an image that serves my propose for the time, so I am going to accept my own answer.Future solutions may be posted.

Please note: in my case I only needed to fill images for 8 hexagons that are relatively located in the center of the mesh, I didnt need to do any calculations I only figured out that I have 44 hexagons and I needed to fill the paths numbered from 20 to 27 of the mesh. My images data set contains 8 images which I used to create a number of images pattern for every hexagon I need to fill

 var imagePatterns = d3.select("#imagesContainer").append('svg').selectAll('pattern')
        .data(data)
        .enter().append('defs').append('pattern')
        .attr('id', function (d, i) {
            return 'fillImage' + (19 + i);
        })
        .attr('patternUnits', 'userSpaceOnUse')
        .attr('width', 190)
        .attr('height', 270)
        .append('image').attr("xlink:href", function (d, i) {
    return d;
}).attr("x", 0)
        .attr("y", 0)
        .attr("width", imageWidth)
        .attr("height", imageHeight);

In the hexTopology function which creates hexagon geometries I added a fill property for the geometry objects of the paths I wanted to fill, other paths are filled with white color.

var hexagonPaths = [20, 21, 22, 23, 24, 25, 26, 27]; 
    geometries.forEach(function (obj, ind) {
        if (hexagonPaths.indexOf(ind) > -1)
        {
                geometries[ind].fill = "url(#fillImage" + ind + ")";
                geometries[ind].text = 'my text';

        }
        else
        {
            geometries[ind].fill ='#fff';
            geometries[ind].text = '';
        }
    });

then I updated the style for each path of the hexagons

svg.append("g")
        .attr("class", "hexagon")
        .selectAll("path")
        .data(topology.objects.hexagons.geometries)
        .enter().append("path")
        .attr("d", function (d) {
            return path(topojson.feature(topology, d));
        }).style('fill', function (d, i) {
            return d.fill; 
        });

Two last points:

  • I dont think this solution is the best answer cause I still have the issue of the 8 image patterns that I needed them to fill the hexagons but I dont want them to have any space in my html.

  • I must mention that I started with this tutorial and this answer was very helpful

Community
  • 1
  • 1
Ragda Awad
  • 63
  • 8