ASE Home Page Products Download Purchase Support About ASE
ChartDirector Support
Forum HomeForum Home   SearchSearch

Message ListMessage List     Post MessagePost Message

  Problem with SVG and getHTMLImageMap
Posted by Karim on Feb-26-2018 17:25
Attachments:
Hi.

We are encountering some troubles with SVG and getHTMLImageMap method.

We used to output charts in PNG, but recently we changed our mind to output them in PNG (no more fixed sized browser window, instead we want to have charts proportionals, so PNG).

We have the charts appearing, so the output in SVG work like a charm :-)

But we have an image maps for every chart on our website, presenting values and sometimes an action like a click opening another page ; it was working with PNG and fixed sizes, and now with SVG it's not working ...

In fact it's like the image map is not scaled at all with the SVG.

You can see an example in attachment, where you can see the shape of the image map after a click, wich is not on the good place on the chart (nor the good size).

Is there a way to make it work like before ?

Thanks.
SVG_imagemap.PNG

  Re: Problem with SVG and getHTMLImageMap
Posted by Peter Kwan on Feb-27-2018 00:22
Hi Karim,

Yes.

According to HTML standard, the HTML image map will not resize. So in ChartDirector, we have included a special Javascript routine to automatically resize the image map. See:

http://www.advsofteng.com/doc/cdnet.htm#JsChartViewer.setAutoResizeImageMap.htm

The exact details are different depending on which programming language edition of ChartDirector you are using. Basically, you need to:

(a) Include the ChartDirector Javascript library "cdjcv.js" in your web page:

<script type="text/javascript" src="cdjcv.js"></script>

(b) Use the WebChartViewer to display the chart and send the image map. In some programming language editions of ChartDirector (such as in ASP.NET), this is the default.

(c) In your web page, add the code to call JsChartViewer.setAutoResizeImageMap for the chart that needs to have the image map auto-resized. For example:

<script>
// Run the following code after the page has loaded
JsChartViewer.addEventListener(window, 'load', function() {
    // Auto resize the image map for the chart in WebChartViewer1
    var viewer = JsChartViewer.get('<%=WebChartViewer1.ClientID%>');
    viewer.setAutoResizeImageMap();
}
</script>

Hope this can help.

Regards
Peter Kwan

  Re: Problem with SVG and getHTMLImageMap
Posted by Karim on Feb-27-2018 13:38
Hi Peter and thanks for answering.

I made it via cdjcv.js, as you said.

I had two things to do :

1) For every chart, I had to use setOutputOptions to set width and height (without this, the chart is displaying correctly, but the image map was at the wrong size :

c.setOutputOptions("width=" & c.getWidth() & " ; height=" & c.getHeight())

2) On the main asp page, I wrote a function, launched on load which parse every chart on page, and use initToolTipHandler (using jquery to get every chart ; each image has its ID containing "legrapheAffiche" and a number, like legrapheAffiche1, legrapheAffiche2 etc.) :

function retailleImageMaps() {
$('img:visible[id*=legrapheAffiche]').each(function() {
var nomIDGraphe=$(this).attr('id');
var lePattern=/^legrapheAffiche(d*)$/i;
match = lePattern.exec(nomIDGraphe);

if(match != null) {
var leNumero = match[1];
console.log("Graphe d'ID " + nomIDGraphe + ", numéro " + leNumero);
var img = document.getElementById(nomIDGraphe);
var widthX = img.naturalWidth;
var heightY = img.naturalHeight;
console.log("Par img : " + widthX + " / " + heightY);
var viewer = JsChartViewer.get(nomIDGraphe);
viewer.originalWidth = widthX;
viewer.originalHeight = heightY;
viewer.initToolTipHandler();
}
});
}

Thank you for helping

Regards

Karim

  Re: Problem with SVG and getHTMLImageMap
Posted by Karim on Feb-27-2018 16:25
Tried with the method you gave me : setAutoResizeImageMap instead of initToolTipHandler

The function launched via onload is now :

function retailleImageMaps() {
$('img:visible[id*=legrapheAffiche]').each(function() {
var nomIDGraphe=$(this).attr('id');
var lePattern=/^legrapheAffiche(d*)$/i;
match = lePattern.exec(nomIDGraphe);

if(match != null) {
var viewer = JsChartViewer.get(nomIDGraphe);
     viewer.setAutoResizeImageMap();
}
});
}

Hope this can help someone :-)

  Re: Problem with SVG and getHTMLImageMap
Posted by Peter Kwan on Feb-28-2018 00:19
Hi Karim,

Thanks for your code. I am sure it will help someone.

Regards
Peter Kwan

  Re: Problem with SVG and getHTMLImageMap
Posted by Karim on Apr-18-2018 17:32
Hi Peter.

Sorry for coming back for this problem, I thought it was closed but ... on Windows 10, Internet Explorer 11, the method viewer.setAutoResizeImageMap(); does ... nothing !

Everything is ok for Firefox or Edge, but IE simply doesn't care !

No console error, but nothing, as if it's not seeing that the size has changed.

Can you help please ?

Thanks

Karim

  Re: Problem with SVG and getHTMLImageMap
Posted by Peter Kwan on Apr-18-2018 22:26
Hi Karim,

Are you using VB.NET with ASP.NET, or it is VBScript with ASP? I will try to create an example to see if I can reproduce the issue.

Regards
Peter Kwan

  Re: Problem with SVG and getHTMLImageMap
Posted by Peter Kwan on Apr-19-2018 01:22
Attachments:
Hi Karim,

After some experiments, I am able to reproduce the issue using classical ASP/VBScript.

The issue is because IE 11 cannot report the "natural size" of the SVG image (the naturalWidth and naturalHeight property of the Javascript IMG object), even if the width and height is specified in the SVG with setOutputOption.

According to the HTML standard, the image map is fixed in size . The server creates the image map based on the "natural size" of the image (c.getWidth() and c.getHeight()).

On the browser side, the setAutoResizeImageMap detects the ratio of the "actual size" of the chart image to that of its "natural size". It then dynamically rewrite the image map. As IE cannot report the "natural size" of an SVG image, the image map cannot be resized.

It turns out there is already an example in this forum to solve the issue, but the code is in PHP:

http://www.chartdir.com/forum/download_thread.php?bn=chartdir_general&pattern=SVG+image+map&thread=1253383061#N1474551381

I have translated the code to ASP as attached. The key is to add the undocumented attribute:

Call viewer.setCustomAttr(31, c.getWidth())
Call viewer.setCustomAttr(32, c.getHeight())

If the above attribute available, setAutoResizeImageMap will use them as the "natural size", so it works even if IE cannot report the natural size.

Hope this can help.

Regards
Peter Kwan
clickbar.asp
clickbar.asp

2.75 Kb

  Re: Problem with SVG and getHTMLImageMap
Posted by Karim on Apr-23-2018 15:15
Hi Peter, and thanks for answering.

I'm not sure I understood your solution ...

Actually, we don't use any "viewer" on ASP classic server side (you understod well, we are using VBScript/ASP).

We generate the output chart via the makeTmpFile method, and the image map via getHTMLImageMap.

Basically, at the end on one example chart, we have

Execute("GrapheResult" & Ext & "=ObjetGraphe.makeTmpFile(Request.ServerVariables(""APPL_PHYSICAL_PATH"") & ""/image/tmp_chart"",5,1200)")
Execute("imageMap" & Ext & "= imageMap & ObjetGraphe.getHTMLImageMap("""", """",""title='{value|1 .}" & uniteIndicateur & "'"")")

(where Ext is a number var, to have a different number for each chart.)

And, into the main page, we have this Javascript function, launched on load :

function retailleImageMaps() {
$('img:visible[id*=legrapheAffiche]').each(function() {
var nomIDGraphe=$(this).attr('id');
var lePattern=/^legrapheAffiche(d*)$/i;
match = lePattern.exec(nomIDGraphe);

if(match != null) {
var viewer = JsChartViewer.get(nomIDGraphe);
     viewer.setAutoResizeImageMap();
}
});
}


So, if I understand your answer, we have to modify EACH chart, to instantiate a WebChartViewer, then call
Call viewer.setCustomAttr(31, c.getWidth())
Call viewer.setCustomAttr(32, c.getHeight())

??

What are the 31 and 32 keys ?

Thank you

  Re: Problem with SVG and getHTMLImageMap
Posted by Peter Kwan on Apr-24-2018 00:02
Hi Karim,

To resize the image map, ChartDirector must need to know the "naturalWidth" and "naturalHeight" of the image. However, in IE 11, there is a bug that the "naturalWidth" and "natureHeight" does not work for SVG. See:

https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/639092/

To work around, we need to directly provide the naturalWidth and naturalHeight to the Javascript using some extra undocumented HIDDEN tags. These tags need to be generated by the WebChartViewer.

For your case, may be you can try to use an array of WebChartViewer objects to store the URL, image map and the HIDDEN parameters, like:

Dim viewers(chartCount - 1)

.....



viewers(Ext) = cd.WebChartViewer(Request, "legrapheAffiche" & Ext)
viewers(Ext).ImageUrl = ObjetGraphe.makeTmpFile(Request.ServerVariables("APPL_PHYSICAL_PATH") & "/image/tmp_chart",5,1200)
viewers(Ext).ImageMap = imageMap & ObjetGraphe.getHTMLImageMap("", "", "title='{value|1 .}" & uniteIndicateur & "'")
Call viewers(Ext).setCustomAttr(31, ObjetGraphe.getWidth())
Call viewers(Ext).setCustomAttr(32, ObjetGraphe.getHeight())


In your current code, you must have some <IMG> and <MAP> tags to display the chart, like:

<img id="legrapheAffiche<%=Ext%>" src='<%=Execute("GrapheResult" & Ext )%>' border="0" usemap="#map<%=Ext%>">
<map name="map<%=Ext%>">
<%=Execute("imageMap" & Ext)%>
</map>

Please replace the above tags with the following line:

<%=viewer(Ext).renderHTML()%>

The WebChartViewer will automatically generate the <IMG>, <MAP> and also the HIDDEN tags.

For your information, the "31" and "32" are the undocumented parameters to tell the ChartDirector Javascript library what is the "naturalWidth" and "naturalHeight" of the image.

Hope this can help.

Regards
Peter Kwan

  Re: Problem with SVG and getHTMLImageMap
Posted by Karim on Apr-24-2018 16:38
Thank you for answering, I will try this.

Just another question : actually, in the <map> tag, we add some other things, like some href to open popups or so.

And, as specified in the renderHTML help, the extra attributes are only for the <img> tag, is it possible to add some attributes to the <map> also ?

Thanks

Regards

Karim

  Re: Problem with SVG and getHTMLImageMap
Posted by Karim on Apr-24-2018 17:51
Another thing I don't understand : the working directory for charts are in /image/tmp_chart

With the old method, by using the <IMG> tag, we had to add the "/image/tmp_chart/" to the result of makeTmpFile to see it, as the method only returns the name of the chart file, without the path, so we put it manually into the src.

Now, with the auto-generated <IMG> tag by renderHTML(), the path is also not returned ... but also in the <IMG> tag, so we can't see our charts ...

  Re: Problem with SVG and getHTMLImageMap
Posted by Peter Kwan on Apr-24-2018 18:52
Hi Karim,

Sorry about the URL. If you need to add the "/image/tmp_chart/" to the URL in the <IMG> tag, with the WebChartViewer, please add it to the ImageUrl in the WebChartViewer. It is like:

viewers(Ext).ImageUrl ="/image/tmp_chart" &  ObjetGraphe.makeTmpFile(Request.ServerVariables("APPL_PHYSICAL_PATH") & "/image/tmp_chart",5,1200)

Basically, the URL in the <IMG> tag will be the WebChartVewer.ImageUrl.

For the attributes inside the <MAP> tag, you would need to add them using Javascript. It is like:

<%=viewer(Ext).renderHTML()%>
<script>
    var imgObj = document.getElementById("<%=viewer(Ext).Id%>");
    var mapObj = document.getElementById(imgObj.useMap.substring(1));
    //... add attributes to the mapObj ....
</script>

Instead of adding the Javascript after renderHTML, you may also add them in retailleImageMaps before calling setAutoResizeImageMap, like:


var imgObj = document.getElementById(nomIDGraphe);
var mapObj = document.getElementById(imgObj.useMap.substring(1));
//... add attributes to the mapObj ....

var viewer = JsChartViewer.get(nomIDGraphe);
viewer.setAutoResizeImageMap();


Hope this can help.

Regards
Peter Kwan

  Re: Problem with SVG and getHTMLImageMap
Posted by Karim on Apr-24-2018 19:46
Thank you for all your answers Peter.

I will try this, and come back for more help ... or to confirm that everyting is ok ;-)

Have a nice day

  Re: Problem with SVG and getHTMLImageMap
Posted by Karim on Apr-25-2018 14:49
It's working :-) !

Thank you Peter, have a nice day !