2

I'm trying to make a a combination of a candlestick chart (representing stock data) and a bar chart (representing volume).

I already have them displayed on one chart but the display and layout I'm having trouble with.

enter image description here

For one, the candlestick and bar data are placed side-by-side rather than stacked on top of each other. Another error is the scale of the volume data for the bar chart is not represented properly in the y-axis (which uses data from candlesticks as basis).

Here is my current code to render the chart:

chart = new Chart(ctx, {
    type: 'candlestick',
    data: {
        labels: labelsData,
        datasets: [{
            label: "My Data",
            data: chartData
        },
        {
            label: 'Volume',
            data: volData,
            type: 'bar'
        }]

    }
});
  • labelsData contains the Date values for each item entry
  • chartData contains JSON object with c,h,l,o,t (close,high,low,open,date) to represent stock data for each item entry
  • volData is an array containing numbers to represent volume for each item entry

What should I add to make the candlesticks and bars placed on the same column, as well as have the bars have their own scale so they do not overshoot the height of the chart?

bloodfire1004
  • 493
  • 2
  • 8
  • 24

3 Answers3

0

It seems you need to scale the volume data since it's two different value units in Y,

Macumbaomuerte
  • 2,197
  • 2
  • 19
  • 22
0

It seems like currentlty there isn't support for this in chartJs I created a feature request, follow the link to see the two issues that were closed due to this.

https://github.com/apexcharts/apexcharts.js/issues/2068

alexalejandroem
  • 1,094
  • 12
  • 17
0

With default configuration you're not easily able to add barcharts. Here is steps you need to do;

Base config:

    const config = {
            // type: 'candlestick', // you must remove this, this option is braking the chart
            data: {
                datasets: []
            },
            options: {
                parsing: false, // must be here, solves another stupid problem
                spanGaps: true, // for better performance
                animation: false, // for better performance
                pointRadius: 0, // for better performance
                plugins: {
                    title: {
                        display: false,
                        text: 'Fiyat Grafiği'
                    },
                },
                responsive: true,
                maintainAspectRatio: false,
                scales: {
                    x: {
                        type: 'timeseries',
                    },
                    y: {
                        type: 'linear',
                    },
                    volume: {
                        type: 'linear',
                        beginAtZero: true,
                        position: 'right',
                        max: maxVolume * 10, // maxVolume should be the maximum number of volumes
                        grid: {
                            display: false, // for better presentation
                        },
                        ticks: {
                            display: false, // for better presentation
                        },
                    }
                },
                interaction: {
                    intersect: false,
                    mode: 'index',
                },
            }
        };

Second step is preparing the datasets;

    let dataSets = [
                {
                    type: 'candlestick', // this must stay
                    label: 'Financial Graph',
                    data: data['klines'].map(function (kline) {
                        return {
                            'x': moment(kline['from']),
                            'o': kline['open_price'],
                            'c': kline['close_price'],
                            'h': kline['high_price'],
                            'l': kline['low_price']
                        };
                    }),
                    color: {
                        up: 'rgb(26, 152, 129)', // those colors are better than defaults
                        down: 'rgb(239, 57, 74)', // those colors are better than defaults
                        unchanged: '#999', // those colors are better than defaults
                    },
                    borderColor: {
                        up: 'rgb(26, 152, 129)',
                        down: 'rgb(239, 57, 74)',
                        unchanged: '#999',
                    },
                    order: 10,
                    yAxisID: 'y', // this must stay
                },
                {
                    type: 'bar',
                    label: 'Volume',
                    data: data['klines'].map(function (kline) {
                        return {
                            'x': moment(kline['from']), // i used moment, feel free to use your own time library
                            'y': kline.quote_asset_volume,
                        }
                    }),
                    backgroundColor: data['klines'].map(function (kline) {
                        return kline.open_price < kline.close_price ? 'rgb(26, 152, 129)' : 'rgb(239, 57, 74)' // for better presentation
                    }),
                    borderColor: '#fff',
                    borderWidth: 1,
                    order: 12,
                    yAxisID: 'volume', // this must stay
                    barPercentage: 0.5, // this must stay
                    barThickness: 6, // this must stay
                    maxBarThickness: 8, // this must stay
                },
            ]

Result;

candlestick chart

Mehmet Gökalp
  • 314
  • 3
  • 6