krishna_v
krishna_v

Reputation: 1511

display rectangles based on values

I am trying to draw rectangle size based on the values. I want to draw bigger rectangle if the value is more and relatively smaller size if the value is lesser.

My code:

var rect = svg.selectAll("rect")
                        .data(filtereddata)
                        .enter().append("rect")
                        .attr("id", function(d,i) { console.log(d); return d.instancegroup;  })
                        .attr("rx",3)
                        .attr("ry",3)
                        .style("fill", function(d,i) { return "#01DF01";})
                        .attr("x", function(d,i) { return i * 80; })
                        .attr("width",function (d,i){
                            if (d.value < 80)
                            {
                                return 40;
                            }
                            else
                            {
                                return d.value/4; 
                            }

                        })
                        .on("click",function(d,i) { console.log(d);})
                        .attr("y", function(d) { return 40; })
                        .attr("height", function(d) { 
                            if (d.value < 80)
                            {
                                return 15;
                            }
                            else
                            {
                                return d.value/5; 
                            }
                            })

However the spacing between the rectangles does not work properly. Is there a better way to resolve this.enter image description here

I tried with axis too but didnt work. I was getting wrong to align the x-axis.

var margin = {top: 20, right: 20, bottom: 70, left: 40},
            width = 600 - margin.left - margin.right,
            height = 300 - margin.top - margin.bottom;

        var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);
        var y = d3.scale.linear().range([height, 0]);
 var rect = svg.selectAll("rect")
                    .data(filtereddata)
                    .enter().append("rect")
                    .attr("id", function(d,i) { console.log(d); return d.instancegroup;  })
                    .attr("rx",3)
                    .attr("ry",3)
                    .style("fill", function(d,i) { return "#01DF01";})
.attr("x", function (d,i) { 

                            if(i ==0 )
                            {
                                return 40;
                            }
                            else
                            {
                                return x(d.value) + 100 ;
                            }

                            })
                        .attr("y", function (d,i) { return  40;})
                        .attr("width", function (d,i) { return height - y(d.value);})
                        .attr("height", function (d,i) { console.log(x(d.value)); return height - y(d.value);})

The data :

[{"status: "Up",value: "300"},{"status: "Up",value: "200"},{"status: "Up",value: "35"}]

Upvotes: 2

Views: 542

Answers (1)

altocumulus
altocumulus

Reputation: 21578

Since x positions are accumulated using widths of previous rectangles having varying dimensions, I'd pre-calculate these values and attach them to the objects prior to binding the data array via d3:

var SPACING = 20;

var data = [
    {"status": "Up", value: "300"},
    {"status": "Up", value: "200"},
    {"status": "Up", value: "35"}
];


data.forEach(function(d, i, array) {
    d.width = d.value < 80 ? 40 : d.value / 4;
    d.height = d.value < 80 ? 15 : d.value / 5;
    d.x = i == 0 ? 0 : array[i-1].x + array[i-1].width + SPACING;
    d.y = 40;
});

Later on you are able to directly access these properties without the need for further calculations:

var rect = svg.selectAll("rect")
                .data(filtereddata)
                .enter().append("rect")
                    .attr({
                        "id": function (d, i) { return d.instancegroup; },
                        "rx": 3,
                        "ry": 3,
                        "x": function (d) { return d.x; },
                        "y": function (d) { return d.y; },
                        "width": function (d) { return d.width; },
                        "height": function (d) { return d.height; }
                    })
                    .on("click", function (d) {
                        console.log(d);
                    })
                    .style("fill", function (d) {
                        return "#01DF01";
                    })

Upvotes: 1

Related Questions