7

I use jqGrid with many columns containing boolean information, which are displayed as checkboxes inside the table (see http://www.ok-soft-gmbh.com/VerticalHeaders/TestFixedO.htm as an example). To display information more compactly I use vertical column headers. It works very well and works in jqGrid in all browsers (see my discussion with Tony Tomov in jqGrid forum http://www.trirand.com/blog/?page_id=393/feature-request/headers-with-vertical-orientation/), but in IE vertical text is blurred and doesn't look nice enough (open the link above in IE and you will see exactly what I mean). I was asked from users why the text displayed so strangely. So I'm thinking of using a JavaScript-based SVG library like SVG Web ( http://code.google.com/p/svgweb/ ) or Raphaël ( http://raphaeljs.com/ ). SVG is very powerful and it is difficult to find a good example. I need only to display vertical text (-90 grad, from the bottom up) and use if possible without working in mode of absolute positioning.

So one more time my question: I need to have a possibility to display vertical text (-90 grad rotation) inside <td> elements of a table header. I want to use a JavaScript-based SVG library like SVG Web or Raphaël. The solution must support IE6. Does anybody have a good reference example which could help me do this? If somebody posts a whole solution of the problem I would be happy.

To be exact here is my current solution: I define

.rotate 
{
    -webkit-transform: rotate(-90deg);    /* Safari 3.1+, Chrome */
    -moz-transform: rotate(-90deg);    /* Firefox 3.5+ */
    -o-transform: rotate(-90deg); /* Opera starting with 10.50 */
    /* Internet Explorer: */
    filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); /* IE6, IE7 */
   -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)" /* IE8 */;
}

define RotateCheckboxColumnHeaders function

var RotateCheckboxColumnHeaders = function (grid, headerHeight) {
    // we use grid as context (if one have more as one table on tnhe page)
    var trHead = $("thead:first tr", grid.hdiv);
    var cm = grid.getGridParam("colModel");
    $("thead:first tr th").height(headerHeight);
    headerHeight = $("thead:first tr th").height();

    for (var iCol = 0; iCol < cm.length; iCol++) {
        var cmi = cm[iCol];
        if (cmi.formatter === 'checkbox') {
            // we must set width of column header div BEFOR adding class "rotate" to
            // prevent text cutting based on the current column width
            var headDiv = $("th:eq(" + iCol + ") div", trHead);
            headDiv.width(headerHeight).addClass("rotate");
            if (!$.browser.msie) {
                if ($.browser.mozilla) {
                    headDiv.css("left", (cmi.width - headerHeight) / 2 + 3).css("bottom", 7);
                }
                else {
                    headDiv.css("left", (cmi.width - headerHeight) / 2);
                }
            }
            else {
                var ieVer = jQuery.browser.version.substr(0, 3);
                // Internet Explorer
                if (ieVer !== "6.0" && ieVer !== "7.0") {
                    headDiv.css("left", cmi.width / 2 - 4).css("bottom", headerHeight / 2);
                    $("span", headDiv).css("left", 0);
                }
                else {
                    headDiv.css("left", 3);
                }
            }
        }
    }
};

And include a call like RotateCheckboxColumnHeaders(grid, 110); after creating jqGrid.

Wayne Koorts
  • 10,142
  • 10
  • 45
  • 72
Oleg
  • 217,934
  • 30
  • 386
  • 757
  • if you are looking for CSS3 equivalent solution may be this site will help you http://www.useragentman.com/IETransformsTranslator/ i might try to recreate your grid and try it in IE6 – paul Jan 03 '11 at 05:00
  • @paul: Thank you for advice, but I already tested `DXImageTransform.Microsoft.Matrix` before. It produce the same results as `DXImageTransform.Microsoft.BasicImage(rotation=3)` filter with the same quality. If the font size is relatively small everithing looks bad. Moreover if one try to scale the page, IE scale the bad image and not try to produce the new image with the better quality. All other browsers produces a perfect results which are also perfect scalable. So the problam stay opened. Even IE9 beta don't give the better results. – Oleg Jan 03 '11 at 18:25
  • Making things work for IE is a bit challenging....We generally have a fallback mechanism in form of png image. So, your best bet might be using png images if svg doesn't worked.... – paul Jan 04 '11 at 00:24

2 Answers2

3

Here's a working jsfiddle that does it. It should work in IE 6, I only used jquery and raphael js. I made static sizes for the raphael drawing area and the text, but you can certainly do a little math to figure out dynamic sizes:

http://jsfiddle.net/UYj58/9/

Code looks like this if you include jquery and raphael:

$(document).ready(function(){
    var font = {font: '12px Helvetica, Arial'};
    var fill = {fill: "hsb(120deg, .5, 1)"}
    $('tr th div').each(function (index, div){
        R = Raphael($(div).attr('id'), 20, 100);
        R.text(4, 50, $(div).find('span').text())
            .attr(font)
            .attr(fill)
            .rotate(-90, true);
        $(div).find('span').hide();
    });
});

And the HTML looks like this:

<table>
    <thead>
        <tr>
            <th><div id="columnOne"><span>heading one</span></div></th>
            <th><div id="columnTwo"><span>heading two</span></div></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>1</td>
            <td>2</td>
        </tr>
        <tr>
            <td>4</td>
            <td>5</td>
        </tr>
    </tbody>
</table>

Oh, and I used this as my example: http://raphaeljs.com/text-rotation.html

Milimetric
  • 13,020
  • 4
  • 40
  • 53
  • Thank you for your answer! The problem is now not so sharp because IE9 supports `ms-transform: rotate(-90deg);` which work perfect (see [the demo](http://www.ok-soft-gmbh.com/jqGrid/CheckboxesWithVerticalHeaders1.htm) from [the answer](http://stackoverflow.com/questions/3974324/jqgrid-using-multiple-methods-to-filter-data/3979490#3979490)). Nevertheless having the solution which work in IE6-IE8 would be nice. I read some time before about `raphael` plugin and wanted to test it. It will be easer having your answer. I will try to integrate your suggestion in jqGrid next week. Thanks! – Oleg May 01 '11 at 14:12
  • Awesome, no problem. And yeah, IE9 changes everything. But for IE6 I personally think raphael and SVG are the only attractive options. Although, I'm all for not supporting IE6 :) – Milimetric May 01 '11 at 14:19
  • oh no problem :) I was just glad to be useful. – Milimetric Aug 03 '11 at 17:32
  • Forked your jsFiddle to left-align the text (text-anchor start): http://jsfiddle.net/74Hjd/4/ – Joshua Stewardson Feb 25 '13 at 22:36
0

Canvas text transformations example

            <!--[if IE]><script type="text/javascript" src="../excanvas.js"></script><![endif]-->
<script type="text/javascript" src="../canvas.text.js"></script>
<script type="text/javascript" src="../faces/dejavu_sans-normal-normal.js"></script>
<script type="text/javascript" src="../faces/dejavu_sans-bold-normal.js"></script>
    </head>
    <body>
            <canvas width="500" height="300" id="test-canvas" style="font-size: 16px;"></canvas>

            <script type="text/javascript">
                function initCanvas(canvas) {
                    if (window.G_vmlCanvasManager && window.attachEvent && !window.opera) {
                        canvas = window.G_vmlCanvasManager.initElement(canvas);
                    }
                    return canvas;
                }

                window.onload = function() {
                    var canvas = initCanvas(document.getElementById("test-canvas")),
                                ctx = canvas.getContext('2d');

                    ctx.strokeStyle = "rgba(255,0,0,1)";
                    ctx.fillStyle = "rgba(0,0,0,1)";
                    ctx.lineWidth = 1;
                    ctx.font = "20pt Verdana, sans-serif";
                    ctx.strokeStyle = "#000";
                    ctx.rotate(Math.PI / 2);
                    ctx.fillText('Vertical', 0, 0);
                    ctx.restore();
                }
            </script>
    </body>

Ali Habibzadeh
  • 10,137
  • 3
  • 48
  • 68
  • I know that the problem which I asked for can be solved. You suggest HTML5 technique. It looks close to using JavaScript based SVG library, but your links are too general. I need at least an example of usage this technique for rotated textes. Could you give me more exact reference? Is it works for IE6? – Oleg Apr 24 '10 at 17:07
  • Thank you for the example, but I am a little disappointed from canvas. 1) in this example font size is fixed 16px and look like bad after scaling with Ctrl+'+' (my old solution can be perfect scaled in all browsers excepted IE). It is the most important disadvantage. 2) I wrote that I need -90 grad rotation and not 90 grad. Changing from Math.PI/2 to -Math.PI/2 or 3*Math.PI/2 not works. 3) All coordinates seems be ABSOLUTE and not relative, which makes placing the text inside of table header more complex. Perfect for me is if I could use in my CSS "transform: rotate(-90deg);" from CSS3, but... – Oleg Apr 24 '10 at 21:23