highcharts / highcharts-ios

iOS wrapper for Highcharts.
Other
127 stars 39 forks source link

HIFunction javascript global context #451

Closed jogatea closed 2 weeks ago

jogatea commented 1 month ago

Hello I had a question on adding a JS function to execute some formatting for certain data in the chart. I want to update the tooltips but the JS function string that I am getting is coming from a server that has references outside the context of function, but obviously it'll fail to execute once ran locally with the Highcharts library because it doesn't have those references. Is there a reason why we don't have the ability to inject context into the Highcharts webview that we can use in our JS functions? Or if it's a possibility to add the ability to inject global context so that our HIFunction's can use common functionality that we want to share between them rather than having to make sure that the function has all the context evaluated before being executed?

E.g. let function = HIFunction(jsFunction: "function () { return 'The value for this is' + getMessage();}")

getMessage() is defined outside the context but I want to be able to inject it somehow rather than flattening it beforehand from the server side.

MikolajMichalczak commented 1 month ago

Hi @jogatea!

In mobile wrappers, creating a global function like in a JavaScript file isn't possible, as the available interface only operates within the Highcharts.chart() structure. However, there are some solutions that can be adapted to different cases. Basically, you can define a function using chart.events.load, and in the case of a tooltip, access it through this.series.chart:

let options = HIOptions()

let chart = HIChart()
chart.type = "column"
chart.events = HIEvents()
chart.events.load = HIFunction(jsFunction: "function(){ this.getMessage = () => { return 'test' }; }")
options.chart = chart

let title = HITitle()
title.text = "Demo chart in SwiftUI"
options.title = title

let tooltip = HITooltip()
tooltip.formatter = HIFunction(jsFunction: "function(){return this.series.chart.getMessage();}")
options.tooltip = tooltip

let series = HIColumn()
series.data = [49.9, 71.5, 106.4, 129.2, 144, 176, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
options.series = [series]

I’m not sure exactly how your code works, but you still need to load this function. Alternatively, as you mentioned, you could construct the exact string you need on the server side with the necessary functions.

MikolajMichalczak commented 2 weeks ago

Closing due to inactivity. Please feel free to reopen the ticket if you have any further questions.