Frappe Plots not rendered correctly

I’m trying to create a Frappe plot in my anvil app.
To that end, I’ve included the relevant js library in my native libraries (<script src="https://unpkg.com/frappe-charts@latest"></script>) and added the following code to my form.

from anvil.js.window import frappe
# ...
  def __init__(self, **properties):
    column_panel = anvil.js.get_dom_node(self.column_panel)
    frappe.Chart(column_panel , {  
       "data": my_data,
       "type": 'percentage',
    })

my_data looks as follows:

{'labels': ['A','B','C','D',],
  'datasets': [
    {'name': 'My favorite letters', 'values': [28.8, 12.68, 9.74, 8.25, ]}
  ]
}

In JSFiddle, this works like a charm. However, when running the anvil app, the plot does not render, and the only thing I can see is some part of the legend (running of to the side). The values match. But the console contains errors like: <svg> attribute width: Expected length, "NaN", suggesting there is some error in the calculation of the graphic’s item sizes. My assumption is, that there is no width defined, but I’m not sure and also uncertain how to debug this (if at all). Any ideas?

https://anvil.works/build#clone:FT3M6U77LLVW65DP=X2G3GJHIBRYOQEVMCUYT2VZV

Hi @christian.steinmeyer - welcome to the forum!

The __init__ function executes before the form is added to the page, and it looks like the library you’re using is expecting information (such as width) that’s only available after being added to the page.

Try moving your setup code to the form’s show event, which fires after the form on the page! (This is how I load three.js for my 3D Christmas tree for our Advent Calendar, for the same reason.)

1 Like

That worked, thanks!
For anyone else that might come across this thread: I added the show_form method to the code as in the example, but had to add this method explicitly to the show event of the form in the designer (Form > Properties > Events > Show). This might be obvious for a regular anvil user but wasn’t to me (I expected some predefined method that I was just overriding).

1 Like

I have a follow up question. After getting the chart to display, I’d like to now make it dynamic. To that end, I’ve created a sub-form that I’ve put into a repeating_panel. Just to make sure, I didn’t break anything, I’ve also included this sub-form as is on to my main-form. Further, I’ve added a button to add an item to a list. I use this list to populate the repeating panel. Most of that works great - however, the charts within the repeating panel do not get rendered. Are there any other cycles, processes or such that I need to be aware of to get that to work?

Here is an updated clone:
https://anvil.works/build#clone:FT3M6U77LLVW65DP=X2G3GJHIBRYOQEVMCUYT2VZV

Your code should work and it looks like you’ve stubbed your toe on a race condition (When the chart is in the repeatingpanel the repeatingpanel form show is firing before the component is visible on the screen and so frappe is not setting the width property correctly). We’ll look into this our end.

Here is a workaround you could employ which involves raising a custom event after you call refresh_data_bindings.

https://anvil.works/build#clone:2Y5VKZCDAGPD4YE6=7C6QT5JFQRNN6L32NWTGNEXH

Edit: the original code should now work

1 Like

Thank you very much for getting back to me (also for being so quick and for looking into it)!
You workaround works like a charm, putting me a lot closer to my goal :slight_smile:

1 Like