tradingview / lightweight-charts-android

Android wrapper for lightweight-charts library
Apache License 2.0
100 stars 33 forks source link

setVisibleRange() is not working #91

Open HyeonWooKim opened 3 years ago

HyeonWooKim commented 3 years ago

Hello.

I want to show the price information for the last 2 months. But unlike Javascript, it was not applied in Android kotlin.

//chartData has 365 days of information val fromT = Time.StringTime((chartData.get(chartData.length() - 60) as JSONObject).getString("time")) // 2021-08-15 val nowT = Time.StringTime((chartData.get(chartData.length() - 1) as JSONObject).getString("time")) // 2021-10-15 chartsView.api.timeScale.setVisibleRange(TimeRange(fromT, nowT))

However, the results always show the widest range of data that can be displayed on the screen. How can I apply it to get the results I want? Thank you so much.

makedonsky94 commented 3 years ago

Hi! We need a log to determine what the actual problem is.

Make an inheritance from ChartsView and override logLevel

override val logLevel = LogLevel.DEBUG

After that you can see logs in the console of chrome inspector

makedonsky94 commented 3 years ago

image

HyeonWooKim commented 3 years ago

Hi. This is my app logs. I make a virtual investment application, so all data have the future date. data1

data2

data3

I expected the app to display data for the last two months. But app result: result

When the same behavior was applied to Javascript, it worked normally.

data5

makedonsky94 commented 3 years ago

Is it intended to call fitContent right after setVisibleRange?

HyeonWooKim commented 3 years ago

@makedonsky94 There was no special intention. Even if I remove the fitContent method, setVisibleRange still doesn't work.

makedonsky94 commented 3 years ago

The bridge between js and native seems ok because we see logs in the Chrome inspector. So I guess this is a tricky case. Can you make a demo with reproducing of this bug?

Also, can you send a version name of WebView implementation?

HyeonWooKim commented 3 years ago

I found one thing: If I rebuild the app after changing the 'from date' value of visibleRange , the chart is displayed properly only the first time. After when I set another data (See another stock), the range is not applied again. If I want to display multiple stock data in a one chart view, do I need an action such as clearing it?

If this does not help much in solving the problem, I will compress the data and upload it.

And my android WebView version : 94.0.4604.85, my test device is Galaxy Z Fold 3.

makedonsky94 commented 3 years ago

It would be helpful if you will provide code. I've tried to reproduce your case but no luck

HyeonWooKim commented 3 years ago

OK. Here's my chartView source code and sample data. When I open stock info, ConsoleActivity starts and inflates the ChartView. And the sample data in the zip file is updated. At first, visibleRange looks fine. But when update with other data, a problem occurs. This issue occurs until I clear the app data in Application info . After erasing the app data, it is displayed normally again upon first execution, so it is likely a problem related to internal data initialization.

I only attached View source because Activity and Util source seem unrelated. example.zip

makedonsky94 commented 3 years ago

I've tried to reproduce but still no luck.

This issue occurs until I clear the app data in Application info

I guess the problem in the data you provide in the library. I can't help until I understood how you storing and providing the data to the library. It would be helpful if you simulate that behaviour in the demo

HyeonWooKim commented 3 years ago

I can't help until I understood how you storing and providing the data to the library

Nothing special to do. I just convert JSONArray received using socket.io library to ArrayList and save it in static variable. When receiving new data, clear the existing ArrayList and set the data again. If there is a problem with static variables, I will test it by changing the storage method to a local variable.

When receiving data

private final Emitter.Listener onChartInfo = args -> {
    try {
       //onChartInfo executes when new chart data is sent
        JSONObject data = (JSONObject) args[0];
        ChartUtil.Companion.init();
        ChartUtil.chartData = data.getJSONArray("cdata"); // Static variable
        ChartUtil.volumeData = data.getJSONArray("vdata"); // Static variable
        if (mConsoleActivity != null) {
            mConsoleActivity.requestChartInit(); // this method will execute init() method (I attached above comment)
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
};

and this is ChartUtil.init method ( I use both Java and Kotlin)

    fun init() {
        psum.clear() // Use it when calculate SMA values
        sma20Data.clear()
        sma60Data.clear()
        sma120Data.clear()
        lastChartData = null
        lastVolumeData = null
        lastsma20 = null
        lastsma60 = null
        lastsma120 = null
    }

After storing all data, I called renderChartData() (I already attached this method above comment)

fun renderChartData() {
    //chart data set, SMA data set
    val clen = ChartUtil.chartData.length()
    val cdata: MutableList<SeriesData> = ArrayList()
    val vdata: MutableList<SeriesData> = ArrayList()
    for (i in 0 until clen) {
        val item = ChartUtil.getBarData(ChartUtil.chartData.get(i) as JSONObject)
        if (item != null) {
            cdata.add(item)
        }
    }
    val vlen = ChartUtil.volumeData.length()
    for (i in 0 until vlen) {
        val item = ChartUtil.getVolumeData(ChartUtil.volumeData.get(i) as JSONObject)
        if (item != null) {
            vdata.add(item)
        }
    }
    candleSeries.setData(cdata) //Is there any work to clear before I set data?
    volumeSeries.setData(vdata)
    sma20Series.setData(ChartUtil.sma20Data)
    sma60Series.setData(ChartUtil.sma60Data)
    sma120Series.setData(ChartUtil.sma120Data)
}

And this is ChartUtil.getBarData() method

    fun getBarData(rawData: JSONObject): SeriesData? {
        return try {
            BarData(
                    Time.StringTime(rawData.getString("time"), Locale.KOREA),
                    rawData.getLong("open").toFloat(),
                    rawData.getLong("high").toFloat(),
                    rawData.getLong("low").toFloat(),
                    rawData.getLong("close").toFloat())
        } catch (e: JSONException) {
            e.printStackTrace()
            null
        }
    }

I'm sorry but these days I'm really busy so I don't have time to make a demo app. If the problem is not solved even after 1~2 weeks later, I will try to make a demo app.