Search code examples
jqueryhtmlcssinternet-explorerheader

How to represent a Grid with vertical header text in HTML?


I'd like to represent a grid of "scores", with two coordinates : "system" and "location". The score is a numeric value between 0 and 5, while the two others coordinates are strings.

I have to represent this as a IE7-Compatible HTML table, however I'm facing many problems :

As the headers ("location") are strings, they take much more place than the cells (numeric), and so I lose much space (especially because location strings can be pretty long). So there is the matter :

I'd like to be able to rotate my headers.

I was able to do this, using various jQuery plugins (the one used in screenshots is this one), it worked in various navigators (see here) but none of them worked in IE7 (see here)

Without jQuery, using

filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);

I was able to rotate the text, but its container was still not adapting to the new size (see here) : the width was not reduced and the height not increased. So, using this :

table tr:first-child { height: 200px; }

I fixed the first row height (which is not perfect, cause I cannot know how long the cell contents are going to be, but still...), but this did not change the cell width : see here. Using this :

table tr:first-child td { width: 30px; }

Did not change anything, the width was still as large as it needed to be before the rotate.

Now, I would like to know if there is a way to make this work under IE7, if possible without fixed heights/widths (like here). Also, maybe there is another way to represented my data than an HTML table :

  • Maybe a scatter plot with vertical legends
  • Using a big jQuery grid plugin, like jqGrid : however, I need to find one that can rotate table headers
  • Using PNGs in replacement of the text headers. However, I may have more than 400 columns in my table, would that be efficient ?

To summarize, here are my questions :

  • Is there any jQuery grid plugin, compatible with IE, capable of rotating headers ?
  • Is it possible to make this work in IE using CSS or even Javascript ?

Thank you,

PS: My restriction is to be IE-compatible (at least IE7, better IE6 but if that's not possible, that's not possible.), not to avoid using JavaScript. When I can I try not to use it, but if needed, it will be available on the client machines. However, the JS libs I use still need to be IE7 compatible.


Solution

  • I was finally able to do what I wanted, using jQuery and RaphaelJS.

    The trick: converting the text to SVG for easier manipulation. Because this is all done using JavaScript, this doesn't alter the web page semantics.

    Howto

    HTML

    <table>
        <thead>
            <tr>
                <th><div id="column1"><span>aaaaaaaaaaa aaaaaaaa</span></div></th>
                <th><div id="column2"><span>bbbbbbb bbbbbbbbbbbb</span></div></th>
                <th><div id="column3"><span>ccc cccccccccccccccc</span></div></th>
                <th><div id="column4"><span>ddd ddd dddddddddddd</span></div></th>
                <th><div id="column5"><span>eee eee eee eee eee </span></div></th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>1</td>
                <td>2</td>
                <td>3</td>
                <td>4</td>
                <td>5</td>
            </tr>
            <tr>
                <td>I</td>
                <td>II</td>
                <td>III</td>
                <td>IV</td>
                <td>V</td>
            </tr>
        </tbody>
    </table>
    

    As you can see, in each column header, we create a div, with a different id each time (with Django, I use the object ID for this) if we want to manipulate each column independently later, with an inline span, and then with the content.

    Javascript

    Then, use the following code (at the beginning of your page, but not in , better just after :

    $(document).ready(function(){
    $('tr th div').each(function (index, div){
    R = Raphael($(div).attr('id'), 10, 200);
    R.text(5, 100, $(div).find('span').text())
    .rotate(-90, true);
    $(div).find('span').hide();
    });
    });
    

    You will need to adapt the numeric values (except the -90, of course) to your cell sizes. And of course, you will have to import jQuery and RaphaelJS in your code. I used jquery-1.8.2.min.js and raphael-min.js, both available on their respective project sites.

    CSS

    Of course you can use your own CSS with this, but if you encounter difficulties theming the inline text, try to use RaphaelJS's .attr(...) functions. Remember you have to chain them with R.text(...) line :

    R.text(...).attr(...).attr(...).rotate(-90, true);
    

    Final render

    I was able to get something like this :

    Final render
    (source: ompldr.org)

    Next Step

    My next step is now to be able to align the cell contents down to the bottom, see here.