Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 
Not applicable

2D Drawing (Canvas, ExplorerCanvas, Raphael, VML)

I've been trying to implement some 2D drawing into a QlikView extension. The overall goal is to be able to implement this in a custom mapping application. I've taken a look at some of the mapping extensions, but they all seem to utilize Google Maps, which I don't really need (or want). I basically want to draw some shapes on the screen, color them according to QlikView data and allow the user to select them with a click.

My first try was using Canvas and since I'm using IE8, ExplorerCanvas (excanvas.sourceforge.net). I used Qva.LoadScript to load the required js file for ExplorerCanvas. Then I created an AddExtension, where I tried to implement a simple canvas example:

Qva.LoadScript('/QvAjaxZfc/QvsViewClient.aspx?public=only&name=Extensions/First/excanvas.js', function(){});

Qva.AddExtension('First', function() {
try {
  var can = document.createElement('canvas');
  G_vmlCanvasManager.initElement(can);
 
  if(can.getContext) {
   var ctx = can.getContext('2d');
   ctx.fillStyle="#FF0000";
   ctx.fillRect(0,0,150,75);    
  }
} catch(err) {
   alert('ERROR');
}
}, true);

This is a simplified version, but I am able to get through this without any errors. Nothing is drawn to the screen. I mixed in some traditional html elements and those will display. I figured the issue was around setting up the Context, but an alert inside the if(can.getContext) gets fired, so it is hitting the Canvas code, but not displaying anything.

I've also made similar attempts using Raphael & VML, but have had similar results. Does anyone have an example of a 2D drawing extension that doesn't use Google Maps? I took a look at the SVG example in the Extensions Demo. That seems to be very similar to what I am looking for, but I was unable to find the extension source anywhere.

Any assistance would be appreciated. Thank you!

1 Solution

Accepted Solutions
Brian_Munz
Employee
Employee

Hi NMiller.

I can provide you with the code for the SVG/Raphael extension example in a little while here, but a problem I see right off the bat is that you should either put the loadscript inside the extension and all of the extension code in the function like this:


Qva.AddExtension('First', function() {

Qva.LoadScript('/QvAjaxZfc/QvsViewClient.aspx?public=only&name=Extensions/First/excanvas.js', function(){


try {
  var can = document.createElement('canvas');
  G_vmlCanvasManager.initElement(can);
 
  if(can.getContext) {
   var ctx = can.getContext('2d');
   ctx.fillStyle="#FF0000";
   ctx.fillRect(0,0,150,75);    
  }
} catch(err) {
   alert('ERROR');
}

});
}, true);

or put the loading of the extension in the loadscript function like this:

Qva.LoadScript('/QvAjaxZfc/QvsViewClient.aspx?public=only&name=Extensions/First/excanvas.js', function(){

Qva.AddExtension('First', function() {
try {
  var can = document.createElement('canvas');
  G_vmlCanvasManager.initElement(can);
 
  if(can.getContext) {
   var ctx = can.getContext('2d');
   ctx.fillStyle="#FF0000";
   ctx.fillRect(0,0,150,75);    
  }
} catch(err) {
   alert('ERROR');
}
}, true);

});

This ensures that the js library is loaded before the extension tries to use it.

View solution in original post

4 Replies
Brian_Munz
Employee
Employee

Hi NMiller.

I can provide you with the code for the SVG/Raphael extension example in a little while here, but a problem I see right off the bat is that you should either put the loadscript inside the extension and all of the extension code in the function like this:


Qva.AddExtension('First', function() {

Qva.LoadScript('/QvAjaxZfc/QvsViewClient.aspx?public=only&name=Extensions/First/excanvas.js', function(){


try {
  var can = document.createElement('canvas');
  G_vmlCanvasManager.initElement(can);
 
  if(can.getContext) {
   var ctx = can.getContext('2d');
   ctx.fillStyle="#FF0000";
   ctx.fillRect(0,0,150,75);    
  }
} catch(err) {
   alert('ERROR');
}

});
}, true);

or put the loading of the extension in the loadscript function like this:

Qva.LoadScript('/QvAjaxZfc/QvsViewClient.aspx?public=only&name=Extensions/First/excanvas.js', function(){

Qva.AddExtension('First', function() {
try {
  var can = document.createElement('canvas');
  G_vmlCanvasManager.initElement(can);
 
  if(can.getContext) {
   var ctx = can.getContext('2d');
   ctx.fillStyle="#FF0000";
   ctx.fillRect(0,0,150,75);    
  }
} catch(err) {
   alert('ERROR');
}
}, true);

});

This ensures that the js library is loaded before the extension tries to use it.

Brian_Munz
Employee
Employee

Actually the code to the SVG/Raphael map extension comes with an install of v11.  You can find it in the C:\Program Files\QlikView\Examples\Extensions directory.

Not applicable
Author

Thanks Brian. I am still working with QlikView 10. I'll grab the QlikView 11 installation and take a look.

I think I saw on one of your other posts that these should work on QV10, but were tested on QV11. Is that correct? Is there anything major that won't work on QV10?

Thanks for the advice on setting up the LoadScript and AddExtension functions. It makes sense to require that the complete script loads before moving on to creating the extension. Unfortunately, that didn't change the results I am getting. I'll take a look at the SVG example when I get home and can install on another PC.

Thanks!

Not applicable
Author

Aha, Houston, we have a red dot! I looked a little closer at your other examples and found a few JavaScript DOM issues I had. After fixing those issues and re-arranging the LoadScript and AddExtension calls as you suggested, I was able to draw a red dot on the screen using Raphael. My ExplorerCanvas version still isn't working, but I'll probably stick to Raphael for now.

Thanks again!

In case anyone runs into similar issues, here is my Script.js:

Qva.LoadScript('/QvAjaxZfc/QvsViewClient.aspx?public=only&name=Extensions/First/raphael.js', function(){
//alert('Script Loaded');

Qva.AddExtension('First', function() {
  try {
   //alert('Add Extension');
   var mainDiv = document.createElement('div');
   mainDiv.setAttribute('id', 'mainDiv');
   this.Element.appendChild(mainDiv);

   var paper = new Raphael(document.getElementById('mainDiv'), 500, 500);

   // Creates circle at x = 50, y = 40, with radius 10
   var circle = paper.circle(50, 40, 10);
   // Sets the fill attribute of the circle to red (#f00)
   circle.attr("fill", "#f00");
  
   //alert(this.Element.innerHTML);
  } catch(err) {
    txt="There was an error on this page.\n\n";
    txt+="Error description: " + err.description + "\n\n";
    txt+="Click OK to continue.\n\n";
    alert(txt);
  }
}, true);
});