javascriptjquerycssjasper-reportsvisualize

Center visualize.js div content on page


I have been trying to get a report that we have built with jasperreports and rendered via visualize.js to be centered horizontally on a page (regardless of the page or browser dimensions).

My current code is:

 <!DOCTYPE html>
 <html>
 <head>

 <script src="https://mobiledemo.jaspersoft.com/jasperserver-pro/client/visualize.js"></script>
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mootools/1.5.1/mootools-core-full-compat.min.js"></script>

 <script type='text/javascript'>
   window.addEvent('load', function() {
     visualize({
       auth: {
         name: "joeuser",
         password: "joeuser",
         organization: "organization_1"
       }
     }, function(v) {
       //render dashboard from provided resource
       v("#container").report({
         resource: "/public/Samples/Reports/06g.ProfitDetailReport",
         scale: "container",
         error: handleError
       });

       //show error
       function handleError(err) {
         alert(err.message);
       }

     });

});

 </script>

 <style>
         html,
         body {
           height: 100%;
           width: 100%;
           margin: 0 auto;
           background-color: #000000;
         }

         #container {
           display: block;
           width: 100%;
           height: 100%;
           border: 0px;
           margin: 0 auto;
           background: blue;
         }
 </style>

 </head>

 <body>

 <div id="container"></div>

 </body>

 </html>

The following fiddle should show the current issue: https://jsfiddle.net/g207h68x/

If you resize the result window, you can see that as the report is scaled (via the scale:"container" entry in the render function it sticks to the left of the screen.

I can't use any specific sizes for the <div> as each dashboard has their own unique dimensions depending on what is being displayed in the report or dashboard (some may be 300x500 and others may be up to 1920x1080).

I have tried to wrap the <div> inside flexboxes which didn't seem to help..unless I was not doing it correctly (entirely possible).

Another approach was to try and nest the div within a parent div, but that didn't seem to work either (again, I may have not done it correctly either).

I have also tried to make the <div> an inline-block, but that seems to throw off the scaling entirely for visualize.js as it reads the container dimensions (I think).

I looked into the visualize.js documentation, but there is really not much there for dynamic sizing and spacing on the page.

I even tried to put the <div> within a table...but that didn't seem to help as the table cells would just span across the page or container.

I did read somewhere that the JQuery UI can be used to further manipulate what visualize.js is doing, but I could not find any examples or references on where that was documented.

If anyone knows how to center this type of content, I would greatly appreciate your input.

Thank you in advance.


Solution

  • The centering does not work in your jsfiddle because the report gets scaled inside the container and its transform-origin is set to top left. To overcome most of the issues I have come up with the following script based on the one you posted.

    The main idea is to add some margins to the ".jrTable" table with the beforeRender event, then to intercept the CSS transform-origin from within visualize.js and set the new one.

    Please note that this is not a complete script and does not work on some narrow window setups. I did not run it on a dashboard either. You will have to decide when to set this new origin based on some measurements. Also, the jQuery's cssHook will probably need adjustments for different vendor prefixes if you intend to target other browsers. I tested it only in Chrome and Safari with the default one. More info on jQuery cssHooks.

    EDIT: It seems that the initial solution based on changing the margin and the transform-origin produces unpredictable results and does not scale correctly in all cases. Keeping it for reference here, though.

    Better results can be achieve just by adjusting the offset after the transform-origin is applied:

    window.addEvent('load', function() {
    
      var hookRegistered = new $.Deferred();
      var $container = $("#container"); 
      
      function adjustPageOffset($jrPage) {
        var pageWidth = $jrPage[0].getBoundingClientRect().width,
            containerWidth = $container.width();
    
        (pageWidth<containerWidth) ? $jrPage.offset({left:(containerWidth-pageWidth)/2}) : $jrPage.offset({left:0});
      }
    
      __visualize__.require(["jquery"], function($) {
        $.cssHooks["transformOrigin"] = {
          set: function( elem, value ) {
            elem.style["transformOrigin"] = value;
            
            if ($(elem).is(".jrPage") && "top left" === value) { 				
              adjustPageOffset($(elem));
            }        
          }
        };
        
        hookRegistered.resolve();
      });
    
      // wait for the hook to register in visualize's embedded jQuery
      // then load the report
      hookRegistered.then(function() {
        visualize({
          auth: {
              name: "joeuser",
              password: "joeuser",
              organization: "organization_1"
          }
        }, function (v) {
          //render dashboard from provided resource
          v("#container").report({
              resource: "/public/Samples/Reports/06g.ProfitDetailReport",
              scale: "container",
              error: handleError
          });
    
          //show error
          function handleError(err) {
              alert(err.message);
          }
    
        });
      });
    });

    And the modified jsfiddle.