How to use formatter function in ApexCharts with Phoenix heex

I use the Apexcharts JS library to draw graphs in my Phoenix application. The Apexchart integration is done according to this example.

I want to use custom tooltips as in the example from Apexcharts docs:

tooltip: {
  y: {
    formatter: function(value, { series, seriesIndex, dataPointIndex, w }) {
       return value
     }
  }
 }

But I don’t know how to call the js function inside heex. I tried it like this:

<.chart
   id="chart1"
   chartset={%{
     chart: %{
       type: "line",
       height: 450,
       toolbar: %{
         show: false
       }
      },
     series: [%{
       name: "CPU usage",
       data: @series
     }],
     xaxis: %{
       categories: @categories,
     },
     yaxis: %{
       title: %{
         text: "Average CPU usage, %",
       },
       min: 0,
       max: 100
     },
     tooltip: %{
       y: %{
         formatter: function(value, { series, seriesIndex, dataPointIndex, w }) {
           return value
         }
       }
     }
   }}
 />

and got the following error:

error: syntax error before: '{'
    │
 47 │ ...  formatter: function(value, { series, seriesIndex, dataPointIndex, w }) {
    │                                                                             ^
    │
    └─ lib/monitor_web/live/statistic_live/show_cpu.html.heex:47:100

Does anyone have any ideas? (it works without tooltip section)

In HEEX templates and Phoenix Components you’re on the Elixir side. You can’t write JavaScript in Elixir*. Presumably, those attrs on chart are getting sent as JSON to your hook, which configures the chart. One thing you can do is have the formatter function defined in your hook and pass just the args that it needs from the back-end to the front-end.

e.g if you wanted to format axis labels in a specific timezone you can send the timezone to the hook (this is for a different charting lib). Thetimezone arg comes from the backend.

          // if timezone is provided, we assume the x-axis represents time and display it in said timezone
          if (timezone) {
            this.chart.setOption({
              xAxis: {
                axisLabel: {
                  formatter: (date) => datefns.formatInTimeZone(date, timezone, formatString || "HH:mm")
                }
              }
            })
          }

Maybe you could pass a function from the backend to the front-end as a string and eval it in the hook, but there may be dragons there.

* You could write a sigil that understands JS and you can write script tags in your templates.