Closed KissloveDewangan closed 5 months ago
Hi @KissloveDewangan ! Thank you for the question. At start, I'm not sure what do you mean by nativaly implementing Highcharts in Android. For me it sounds like the library was used not in android project but in some other solution which let you create an android app. The wrapper wasn't created for such purposes and tested on any other platforms than native android so I cannot guarantee that it will behave correctly on those.
Anyways, for me it looks like a problem with dynamic chart size calculation. Please make sure that one of the sizes (height or width) will be set to match_parent
and the other one has set a specific value in dp. This is known problem and that's the only solution I can provide. At this moment I cannot think of any other way of helping you. You can provide more info such as platform you are using the native code on, chart initialization code and so on.
Hi @soommy12 , Thank you for your quick response. Few things I want to clarify further. We have integrated the Android Highcharts library only and attaching the HIChartView at runtime as given below (written in Kotlin, Android Studio):
val chartView = view.inflate(R.layout.item_highchartview) as HIChartView
val lp = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)
lp.gravity = Gravity.CENTER
chartView.layoutParams = lp
val options = HIOptions()
options.exporting = HIExporting()
options.exporting.enabled = false
options.credits = HICredits()
options.credits.enabled = false
val legend = HILegend()
legend.enabled = false
options.legend = legend
val chart = HIChart()
if (type?.contains("area") == true) {
chart.type = "area"
}
options.chart = chart
options.chart.marginRight = 8
options.chart.marginLeft = 8
options.chart.marginTop = 0
options.chart.spacingTop = 4
options.chart.spacingBottom = 4
options.chart.backgroundColor = HIColor.initWithHexValue("00000000")
options.chart.events = HIEvents()
options.chart.events.load = HIFunction(object : Runnable {
override fun run() {
events?.fireChartLoadEvent()
}
})
val title = HITitle()
title.text = ""
options.title = title
// Setting Up X axis
val xAxis = HIXAxis()
xAxis.categories = ArrayList(xAxisLabelsList)
xAxis.tickInterval = xAxisLabelsList.size / 3
xAxis.labels = HILabels()
xAxis.labels.style = HICSSObject()
xAxis.labels.style.fontSize = FONT_SIZE
xAxis.visible = true
xAxis.labels.enabled = true
xAxis.lineWidth = 0
options.xAxis = object : ArrayList<HIXAxis?>() {
init {
add(xAxis)
}
}
// Setting Up Y axis
val yAxis = HIYAxis()
yAxis.visible = false
yAxis.title = HITitle()
yAxis.title.text = ""
options.yAxis = object : ArrayList<HIYAxis?>() {
init {
add(yAxis)
}
}
options.series = ArrayList(mainList)
val tooltip = HITooltip()
tooltip.split = true
tooltip.valuePrefix = "₹"
options.tooltip = tooltip
val plotOptions = HIPlotOptions()
if (type?.contains("stacked-area") == true) {
plotOptions.area = HIArea()
plotOptions.area.stacking = "normal"
plotOptions.area.lineWidth = 1
plotOptions.area.marker = HIMarker()
plotOptions.area.marker.enabled = false
// plotOptions.area.fillOpacity = 1
val linkedList = LinkedList<HIStop>()
linkedList.add(HIStop(0f, HIColor.initWithHexValue("CFD4FF")))
linkedList.add(HIStop(1f, HIColor.initWithHexValue("CFD4FF")))
plotOptions.area.fillColor = HIColor.initWithLinearGradient(HIGradient(), linkedList)
} else {
plotOptions.line = HILine()
plotOptions.line.lineWidth = 1
plotOptions.line.marker = HIMarker()
plotOptions.line.marker.enabled = false
}
options.plotOptions = plotOptions
chartView.options = options
view.addView(chartView)
Please go through above code and let me know if I'm missing something.
Hi @KissloveDewangan ! Thanks for additional info. You didn't clraify what framework are you using for develop you app (debugging via chrome dev tools doesn't look like typical android app, are you using react native or something else? If yes, this library was not designed neither tested for such solutions).
Anyway, as I mentioned from my previous post make sure that HIChartView
class has fixed height or width in dp. In your code you are setting both dimensions to MATCH_PARENT
. Please, use fixed value for one of those dimensions (preferably height), let's say 400dp. That way it should work. This is happening because HC view is in WebView under the hood which has some problem with dynamic dimension calculaction of the view which in turn may cause that the view is not visible in the end.
I experience something similar. In our case HIChartView in a ConstraintLayout, and we have set a fixed height for the chart. And sometimes when we open the screen the WebView on the HIChartView has 0 height, however when I checked the layout with layout inspector the HiChartView has 249dp height.
Also I saw an error message on the log: E/HIChartView: javascript:(function update(options) { chart.update(options); })({ ... E/Highcharts: Uncaught ReferenceError: chart is not defined
<com.highsoft.highcharts.core.HIChartView
android:id="@+id/chart"
android:layout_width="0dp"
android:layout_height="250dp"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/some_label" />
We draw and redraw the chart with this code:
viewModel.chartModel.observe(viewLifecycleOwner) { options: HIOptions ->
if (chart.options == null) {
chart.options = options
} else {
chart.update(options)
}
}
I'm facing a similar problem. I'm trying to implement HighCharts in an activity wich retrieves dinamycally new data with an asynctask. If i try to add these new data to the chart I get this error:
A WebView method was called on thread 'AsyncTask #1'. All WebView methods must be called on the same thread.
If I use
runOnUiThread(new Runnable() {
@Override
public void run() {
hiChartView.redraw();
}
});
chart doesn't appear and in the log you'll find
E/Highcharts: Uncaught ReferenceError: chart is not defined
Hi there,
Thank you for sharing your experience. This behavior can occur when asynchronously fetched data is delivered very quickly. Conceptually, on the Android side, all objects have been created and the JavaScript request to create the chart has been sent, but on the JavaScript side, everything hasn't been fully initialized yet. Since the wrapper is based on WebView, the JavaScript code still needs to execute. I found that introducing a delay of around 500 milliseconds resolved the issue in my case. An ideal solution would be to defer the update until the chart has fully loaded, which can be detected using the load
event.
Regarding the code provided by @warnyul with the observer, it's hard to imagine a scenario where options is null, as they are necessary for rendering the chart.
Furthermore, there is a workaround to address this issue. It arises with the update()
method. Therefore, if the data that updates the chart are the series, they can be updated by direct assignment, in which case this problem does not occur:
chart.options.series = ArrayList(listOf(series))
Closing due to inactivity. Please feel free to reopen the ticket if you have any further questions.
I have integerated highcharts-android natively in android. Above, is the issue screenshot happening sometimes on my android device where the chart is not loading and getting blank screen. And the above screenshot is taken by debugging the HIChartView webview using chrome dev tools. My highchart implementation as given below:-
Most of the time highchart is working great. But sometimes in an app session it is not working at all (all highchart HIChartView suddenly stops working) and I have to kill the app entirely and then cold starting the app then the highchart starts working again.
Any help would be highly appreciated. Please let me know if you need any further information