bjurhager
Posts: 15
Joined: Thu Jul 22, 2021 1:01 pm

React, Extremes from first series.

Hi, I'm using the official react wrapper in my project and ran in to some issues.
Image

I have a chart with multiple series, Candlestick, lines, scatter etc.
I would like the X and Y to be focused on the candlesticks and not as the image above were we see the 200sma from another timeframe.
This should only be visible if inside candlestick range if that makes sens?

I've also noticed that the react component crash after few minutes without any errors, Is this the correct way of updating the data?

Here is my code.

Code: Select all

const WorkerChart = (props) => {
    const chartComponent = useRef(null);
    const [chartOptions, setChartOptions] = useState({
        credits: { enabled: false },
        accessibility: { enabled: false },
        navigator: { enabled: false },
        scrollbar: { enabled: false },
        rangeSelector: { enabled: false },
        tooltip: { enabled: false },
        chart: {
            animation: false,
            backgroundColor: 'transparent',
            margin: [40, 40, 40, 0]
        },
        plotOptions: {
            series: {
                animation: false,
                states: { enabled: false, inactive: { opacity: 1 } },
                dataGrouping: { enabled: false },
            }
        },
        yAxis: [
            {
                labels: {
                    enabled: false,
                    align: 'left',
                    style: {
                        fontSize: 7
                    }
                },
                height: "100%",
                gridLineWidth: 0
            }

        ],
        xAxis: {
            visible: false,
            labels: { enabled: false },
            tickWidth: 0,
            tickLength: 0
        }
    })

    const isEmpty = (obj) => {
        return Object.keys(obj).length === 0;
    }
    useEffect(() => {
        try {
            if (!isEmpty(props.worker)) {
                var ohlc = []
                var volume = []
                var indicators = []
                var positions = []
                var position_history = {
                    open: [],
                    close: []
                }
                var i = 0;

                for (i; i < props.worker.stf.length; i += 1) {
                    ohlc.push([
                        Number(props.worker.stf[i][0]), // the date
                        Number(props.worker.stf[i][1]), // open
                        Number(props.worker.stf[i][2]), // high
                        Number(props.worker.stf[i][3]), // low
                        Number(props.worker.stf[i][4]) // close
                    ]);

                    volume.push([
                        Number(props.worker.stf[i][0]), // the date
                        Number(props.worker.stf[i][6])  // the volume
                    ]);

                }

                if (!isEmpty(props.worker.positions_history)) {
                    props.worker.positions_history.forEach(position => {
                        if (position.ccy === props.worker.ccy && Number(position.cTime) >= ohlc[ohlc.length - 1][0]) {
                            position_history.open.push([Number(position.cTime), Number(position.openAvgPx)])
                            position_history.close.push([Number(position.uTime), Number(position.closeAvgPx)])
                        }
                    })
                }
                if (!isEmpty(props.worker.positions)) {
                    props.worker.positions.forEach(position => {
                        if (Number(position.avgPx)) {
                            positions.push([Number(position.cTime), Number(position.avgPx)])
                        }
                    })
                }
                if (!isEmpty(props.worker.indicators)) {
                    indicators = props.worker.indicators
                }
            }
            let themeColors = {}
            if (props.theme === 'dark') {
                themeColors = {
                    candlestick: {
                        lineColor: 'rgba(255, 255, 255, 0.25)',
                        color: '#FFFFFF',
                        upColor: '#FFFFFF'
                    },
                    line: {
                        lineColor: 'rgba(255, 255, 255, 0.6)',
                        lineWidth: 0.4
                    }
                }
            }
            if (props.theme === 'light') {
                themeColors = {
                    candlestick: {
                        lineColor: 'rgba(0,0,0,0.2)',
                        color: 'rgba(0,0,0,0.8)',
                        upColor: 'rgba(0,0,0,0.6)'
                    },
                    line: {
                        lineColor: 'rgba(0,0,0,0.2)',
                        lineWidth: 1
                    }
                }
            }
            setChartOptions({
                plotOptions: {
                   ...themeColors
                },
                xAxis: { min: Number(props.worker.stf[props.worker.stf.length - 1][0]) },
                series: [
                    {
                        type: "candlestick",
                        name: "main",
                        zIndex: 10,
                        data: ohlc.reverse()
                    },
                    {
                        type: "scatter",
                        linkedTo: 'main',
                        name: "positions",
                        zIndex: 15,
                        marker: {
                            symbol: 'circle',
                        },
                        data: positions.reverse()
                    },
                    {
                        type: "scatter",
                        linkedTo: 'main',
                        name: "Open",
                        color: '#00FF00',
                        zIndex: 15,
                        marker: {
                            symbol: 'circle',
                        },
                        data: position_history.open.reverse()
                    },
                    {
                        type: "scatter",
                        linkedTo: 'main',
                        name: "Close",
                        color: '#FF0000',
                        zIndex: 15,
                        marker: {
                            symbol: 'circle',
                        },
                        data: position_history.close.reverse()
                    },
                    ...indicators
                ]
            })
        } catch (error) {

        }
    }, [props])


useEffect(() => {
    try {
        chartComponent.current.chart.reflow();
    } catch (error) {
        console.log(error)
    }
}, [])
return (
        <HighchartsReact
            ref={chartComponent}
            highcharts={Highcharts}
            constructorType={"stockChart"}
            options={chartOptions}
            updateArgs = { [true, true, false] }
            containerProps={{ style: { width: "100%", height: '100%' } }}
        />
)
}
export default WorkerChart;
Best / F
Attachments
chart.jpg
chart.jpg (7.06 KiB) Viewed 1231 times
bjurhager
Posts: 15
Joined: Thu Jul 22, 2021 1:01 pm

Re: React, Extremes from first series.

Solved the xAxis range in a better way than to set "min"
Using "xAxis: {range: 40 * 60000}," instead to display 40minutes of data.
bjurhager
Posts: 15
Joined: Thu Jul 22, 2021 1:01 pm

Re: React, Extremes from first series.

Think i also solved the yAxis problem.
Getting he high / low from candle data.

var max = Math.max(...[].concat(...ohlc[2]));
var min = Math.min(...[].concat(...ohlc[3]));

setChartOptions({
plotOptions: {...themeColors},
yAxis: {ceiling: max, floor: Math.min(min)},
xAxis: {range: 40 * 60000},
series: [
kamil.m
Posts: 892
Joined: Thu May 19, 2022 1:33 pm

Re: React, Extremes from first series.

Hi!

That is amazing to hear that you have managed to solve everything by yourself.

Please do not hesitate to contact us with any other questions related to Highcharts functionality,
Best regards!
Kamil Musiałowski
Highcharts Developer
bjurhager
Posts: 15
Joined: Thu Jul 22, 2021 1:01 pm

Re: React, Extremes from first series.

:D No worries.
I still have one question tho. Is it possible to plot a series that don't alter the yAxis extremes?

Lets say we have candlesticks with high = 300 and low = 200. Then i want to plot something at something = 25.

I dont want the extremes to be high = 300 and low = 25.
That would mean that 25 is not visible until candles goes that low.

Is this possible in a correct way?
Best /F
kamil.m
Posts: 892
Joined: Thu May 19, 2022 1:33 pm

Re: React, Extremes from first series.

Hi there!

Sadly, there is no such option in our library for excluding a particular series or point from extremes recalculation. You can try to play around with the setExtremes method, i.e get extremes before adding a new series, and then set the extremes after to the previously saved values. But please be aware of the fact, that it might mess up the next extremes calculations (for example, after showing/hiding series or adding a point to your 'normal' series).

Best regards!
Kamil Musiałowski
Highcharts Developer
bjurhager
Posts: 15
Joined: Thu Jul 22, 2021 1:01 pm

Re: React, Extremes from first series.

Perfect thanks, i will play around with some stuff :)
best / F
bjurhager
Posts: 15
Joined: Thu Jul 22, 2021 1:01 pm

Re: React, Extremes from first series.

New question in the same topic.
Sometimes my last candlestick is not showing up. It's like the chart isnt moving with the newly added candle.
Why could this be?
Best /F
kamil.m
Posts: 892
Joined: Thu May 19, 2022 1:33 pm

Re: React, Extremes from first series.

Sure thing, play around with it, and let me know if you will need some assistance with it!

When it comes to not showing the newly added data, there are too many variables that might be causing this issue, so it is hard to guess without looking at the chart.

It depends on how the data is added, is the redraw method called, do the extremes change, and is the data grouping disabled?

If you still won't be able to investigate this issue, feel free to reproduce it in an online editor and I'll be more than happy to help you with it.

Regards!
Kamil Musiałowski
Highcharts Developer
bjurhager
Posts: 15
Joined: Thu Jul 22, 2021 1:01 pm

Re: React, Extremes from first series.

Here is the full code if that's to any help.
All data is updated, candles is added etc. If i try to pan, somethimes it show up and stays correct.

Code: Select all

import React, { useEffect, useState, useRef } from 'react'
import Highcharts from "highcharts/highstock";
import HighchartsReact from "highcharts-react-official";

const WorkerChart = (props) => {
    const chartComponent = useRef(null);
    const [chartOptions, setChartOptions] = useState({})

    const isEmpty = (obj) => {
        return Object.keys(obj).length === 0;
    }
    useEffect(() => {
        try {
            if (!isEmpty(props.worker)) {
                var themeColors = {}
                var labelColors = {

                }
                var ohlc = []
                var volume = []
                var positions = []
                var position_history = {
                    open: [],
                    close: []
                }
                var i = 0;

                for (i; i < props.worker.stf.length; i += 1) {
                    ohlc.push([
                        Number(props.worker.stf[i][0]), // the date
                        Number(props.worker.stf[i][1]), // open
                        Number(props.worker.stf[i][2]), // high
                        Number(props.worker.stf[i][3]), // low
                        Number(props.worker.stf[i][4]) // close
                    ]);

                    volume.push([
                        Number(props.worker.stf[i][0]), // the date
                        Number(props.worker.stf[i][6])  // the volume
                    ]);

                }

                if (!isEmpty(props.worker.positions_history)) {
                    props.worker.positions_history.forEach(position => {
                        if (position.ccy === props.worker.ccy && Number(position.cTime) >= ohlc[ohlc.length - 1][0]) {
                            position_history.open.push([Number(position.cTime), Number(position.openAvgPx)])
                            position_history.close.push([Number(position.uTime), Number(position.closeAvgPx)])
                        }
                    })
                }
                if (!isEmpty(props.worker.positions)) {
                    props.worker.positions.forEach(position => {
                        if (Number(position.avgPx)) {
                            positions.push([Number(position.cTime), Number(position.avgPx)])
                        }
                    })
                }
            }

            if (props.theme === 'dark') {
                themeColors = {
                    candlestick: {
                        lineColor: 'rgba(255, 255, 255, 0.25)',
                        color: '#FFFFFF',
                        upColor: '#FFFFFF'
                    },
                    line: {
                        lineColor: 'rgba(255, 255, 255, 0.6)',
                        lineWidth: 0.4
                    }
                }
                labelColors = {
                    color: 'rgba(255, 255, 255, 0.6)'
                }
            }
            if (props.theme === 'light') {
                themeColors = {
                    candlestick: {
                        lineColor: 'rgba(0,0,0,0.2)',
                        color: 'rgba(0,0,0,0.8)',
                        upColor: 'rgba(0,0,0,0.6)'
                    },
                    line: {
                        lineColor: 'rgba(0,0,0,0.2)',
                        lineWidth: 1
                    }
                }
                labelColors = {
                    color: 'rgba(0, 0, 0, 0.6)'
                }

            }

            setChartOptions({
                credits: { enabled: false },
                accessibility: { enabled: false },
                navigator: { enabled: false },
                scrollbar: { enabled: false },
                rangeSelector: { enabled: false },
                tooltip: { enabled: false },
                chart: {
                    animation: false,
                    backgroundColor: 'transparent'
                },
                yAxis:
                {
                    labels: {
                        enabled: true,
                        align: 'left',
                        style: {
                            ...labelColors,
                            fontSize: 8
                        }
                    },
                    height: "100%",
                    gridLineWidth: 0
                },
                xAxis: {
                    visible: true,
                    labels: { 
                        enabled: true,
                        align: 'right',
                        style: {
                            ...labelColors,
                            fontSize: 8
                        }
                    },
                    gridLineWidth: 0,
                    lineWidth: 0.05,
                    tickWidth: 0,
                    tickLength: 0,
                    endOnTick: true,
                    alignTicks: false,
                    range: 40 * 60000
                },
                plotOptions: {
                    series: {
                        animation: false,
                        states: { enabled: false, inactive: { opacity: 1 } },
                        dataGrouping: { enabled: false },
                    }, ...themeColors
                },
                series: [
                    {
                        type: "candlestick",
                        name: "main",
                        zIndex: 10,
                        data: ohlc.reverse()
                    },
                    {
                        type: "scatter",
                        linkedTo: 'main',
                        name: "positions",
                        zIndex: 15,
                        marker: {
                            symbol: 'circle',
                        },
                        data: positions.reverse()
                    },
                    {
                        type: "scatter",
                        linkedTo: 'main',
                        name: "Open",
                        color: '#00FF00',
                        zIndex: 15,
                        marker: {
                            symbol: 'circle',
                        },
                        data: position_history.open.reverse()
                    },
                    {
                        type: "scatter",
                        linkedTo: 'main',
                        name: "Close",
                        color: '#FF0000',
                        zIndex: 15,
                        marker: {
                            symbol: 'circle',
                        },
                        data: position_history.close.reverse()
                    },
                    ...props.worker.indicators
                ]
            })
        } catch (error) {

        }
    }, [props])
    useEffect(() => {
        try {
            chartComponent.current.chart.reflow();
        } catch (error) {
            console.log(error)
        }
    }, [])
    return (
        <HighchartsReact
            ref={chartComponent}
            highcharts={Highcharts}
            constructorType={"stockChart"}
            options={chartOptions}
            containerProps={{ style: { width: "100%", height: '100%' } }}
        />
    )
}
export default WorkerChart;
kamil.m
Posts: 892
Joined: Thu May 19, 2022 1:33 pm

Re: React, Extremes from first series.

Could you please reproduce it in the code editor?

You can start with this simple react HC demo: https://codesandbox.io/s/highcharts-rea ... =/demo.jsx
Also, take a look at this GitHub article, maybe it will help you: https://github.com/highcharts/highchart ... -to-update
Kamil Musiałowski
Highcharts Developer
bjurhager
Posts: 15
Joined: Thu Jul 22, 2021 1:01 pm

Re: React, Extremes from first series.

immutable={true}
Seems to have done the trick :) As i don't interact with the chart this solution works for me.

If anyone else has the same problem. Here's the code.

Code: Select all

<HighchartsReact
            ref={chartComponent}
            highcharts={Highcharts}
            constructorType={"stockChart"}
            options={chartOptions}
            immutable={true} <---------------------
            containerProps={{ style: { width: "100%", height: '100%' } }}
        />
Best / F
kamil.m
Posts: 892
Joined: Thu May 19, 2022 1:33 pm

Re: React, Extremes from first series.

Great to hear that!

Seems that you have managed to do everything by yourself in this thread, without any help from me :D

Anyways, let me know once you'll need anything else!
Have a great day
Kamil Musiałowski
Highcharts Developer

Return to “Highcharts Stock”