How to send an event from a custom visualization component (in a tile of an sso embed dashboard inside the iframe) to parent web page

Jun_Lu
New Member

I have a custom visualization component created. I put it in a tile of an sso embed dashboard (inside an iframe). I wanted to send an event from the tile to the parent page of the sso embed dashboard but failed to do so. 

The iframe is defined (in Angular) as:

<iframe id="looker-iframe" [src]="targetUrl | safe" title="Dashboard" sandbox = "allow-same-origin allow-scripts" (load)="attachEventListener()"></iframe>

The following code is used in updateAsync() of a Looker custom vis component .ts file. It’s assumes that a message is sent to the parent page when user clicks on some svg inside the vis component.

window.postMessage(message, '*'); //Here message is a stringified json object.

At runtime, the sso embed dashboard is shown correctly and custom vis in shown correctly as well in a tile.  My console.log() output shows that onClick() is triggered but  the parent page of the iframe can’t receive the  message event.

Any idea why window.postMessage(message, '*') doesn’t work for iframe → parent event sending?

I even tried window.parent.postMessage(message, '*') but it’s not working either.

Thanks,

Jun

0 6 1,237
6 REPLIES 6

Hey Jun! Thanks for the interesting question. 

I’ve recently been doing some work in this area and my immediate answer is yes this is possible, but the implementation is made complicated by some recent changes to Chrome and Looker. 

I do have some ideas about how we might be able to get around this. I’d like to do some testing and get back to you after the weekend. I look forward to following up with you!

Noah

Jun_Lu
New Member

Glad to hear from you Noah! Looking forward to further update from you 🙂

Thanks,

Jun

Hey Jun! Hope you’re well.

After some testing, I discovered it is currently not possible to communicate from a custom viz tile to its “grand”-parent. This is because the web app containing the dashboard is not the direct parent of the custom viz iframe. Without a proxy service, communication between these two frames is prevented by CORB.

We could consider adding a proxy to the custom visualizations api, but that would have to be investigated in 2021 and there are likely to be some steep security concerns in the way of that. If I could get more information about what you’re trying to accomplish, I could include that in the ticket proposing this change. 

I tested some hacky, workaround ideas unsuccessfully. However, depending on what you’re trying to accomplish, I have an idea that might interest you. Using the Extension Framework, you can create a visualization that is a direct child of the web app. This implementation would make the communication work as you expect in your original post. 

You can find where I’ve experimented with a visualization layer in the extension framework here: https://github.com/noahamac/vizzy (Column chart) and here: https://github.com/noahamac/vizzy/tree/vizzy-map (Map chart). These projects are works in progress and not officially supported. This is not a 1:1 replacement for a dashboard containing custom viz tile, but depending on what you’re trying to do may suffice. Future plans for the Extension Framework include “visualization components” which will certainly make this option more readily achievable than it is now, where you’re somewhat “on your own” to implement the viz, data fetching via API, etc. 

I hope this was helpful to you. If the Extension Framework solution doesn’t help you accomplish what you’re trying to do, I’d love to learn more about your objective and find another path forward with you. Even if that is recording your use case for some research into a custom viz iframe event proxy in Q1 2021. 

Thanks! 
Noah

Jun_Lu
New Member

Hi Noah,

Thank you so much for your help!

There seems to be an existing solution (but with some drillmenu positioning issue).

https://github.com/looker/custom_visualizations_v2/blob/master/docs/api_reference.md

→ LookerCharts.Utils.openDrillMenu(options)

I tried the above API. The drillmenu itself seems to work for me.  The parent page of the iframe can receive the message.

However, I can’t manage to set the position of the drillmenu properly.

I have a bubble chart svg created in the viz component. So I need to show the drill menu inside the bubble circle. But it seems that even when I set the optional value of ‘element’ to be the DOMElement of the bubble chart circle,  the dirllmen still shows at the left bottom of the widget where the bubble chart svg is created instead of at the position of the mouse pointer which hovers over a bubble.

        LookerCharts.Utils.openDrillMenu(
{
'links': [ { label: crossLinkLabel, type: 'drill', type_label: 'links', url: crossLinkTargetString } ],
'event': messageEvent,
'domElement': JSON.parse(JSON.stringify(d3.select('#id_' + index).node()))
}
);

I tried different ways but still can’t get the drillmenu position issue solved.

Thanks,

Jun

Jun_Lu
New Member

I found the solution to solve the drillmenu position issue:  Just wrap pageX and pageY inside the event.

The following is my code snippet.

LookerCharts.Utils.openDrillMenu(

    { 'links': [ { label: crossLinkLabel, type: 'drill', type_label: 'links', url: crossLinkTargetString } ],

      'event': {

          pageX: d3.event.pageX,

          pageY: d3.event.pageY

     }

)

It doesn’t matter whether it is svg or not, drillmenu will be shown where the mouse click event happens.

Thanks,

Jun

Jun_Lu
New Member
e70985a8-459c-4dba-8d5f-64bce0421b0f.png
9f2e7bc4-2c22-45f0-af71-75da7c677de2.png