0

The goal is to have a table that displays item name, and item %. I want to put in an animated background color that will visually display this %. So if the % is 25, then 25% of the table row will be filled with a color. So far this is what I have. I decided to make an extra td that holds the rectangle that will overlap the first two.

The cshtml (within a bootstrap modal):

            <script>
                var modelThing = @Html.Raw(Json.Encode(Model.Things));
            </script>
            <table id="tableThing">
                <tr>
                    <th>Name</th>
                    <th>%</th>
                </tr>
            </table>

The js:

var t = $("table#tableThing");

$.each(modelThing , function (i, thing) {

    t.append('<tr style="position: relative"><td>' + thing.Name + '</td><td>' + thing.Percentage + '</td><td style="position: absolute; padding:0px; left:0px; width:100%;">' + '<div id="thingPlacer' + thing.Id + '"/>' + '</td></tr>')
    t.attr("class", "table table-hover")

    $("#thingsModal").on('show.bs.modal', function () {

        d3.select("#thingPlacer" + thing.Id).selectAll('svg').remove();

        var svg = d3.select("#thingPlacer" + thing.Id).append('svg')
            .attr('width', "100%")
            .attr('height', "100%")
            .append('rect')
            .attr("width", 0)
            .attr('fill', "rgba(200,0,0,0.15)")
            .transition().duration(1000).ease("linear")
            .attr('width', thing.Percentage + "%")
            .attr('height', "100%");
    });

});

The problem with this way is that the SVG made by d3 sets its height to the default 150px (since height is set to 100%). This bleeds out of the row and into the three below it. I need to find a way to either make the rectangle the same height as the row, or make the table cell the height of the row and turn off overfill, or maybe make two rows and have the rows overlap instead. Is there a way to make the div containing cell match the height of the first two td's? Or is there another way I should be approaching this?

I wanted to try to stick with d3 because of their other charts and graphs, which may take the place of the plain rectangle at some point.

EDIT

I was able to get the cell to use the correct height by adding the following:

    var rowInfo;
    rowInfo = $("tr");

And then changing the height attribute to:

.attr('height', rowInfo.height())

However this does not update the size when switching to mobile, or changing screen size.

No Window
  • 126
  • 15

1 Answers1

2

Take a look at the following:

How to make <div> fill <td> height

If you choose the "hack" route, try setting the min-height of the containing tr to 1px to give css something to work from. Otherwise, you can calculate a height at render time based off the height of the parent tr.

[Edit]

Size changes when calculating height can be accounted for by attaching to the window resize method. My standard MO for that condition is to refactor the resize method from your code to something that you can invoke from the method, then call it from $(window).resize:

$(window).resize(function(e) {
    resizeSVG();
    });

resizeSVG(); would be your refactored method: select the svg, grab the new row height, then set the height attr as you are in your current draw code. I'll put together a small code sample if needed.

If scaling becomes an issue (The container's width and height may not be adjusting the size of the rendered svg), you may want to include the viewBox attribute on your svg to control the size ratio of the image as it grows. You can use .attr() to add the viewBox attribute to your drawn svg.

Scaling SVG using CSS

Applying SVG scaling with d3

Community
  • 1
  • 1