javascript - Set a certain interval for x-axis ticks in ApexCharts - Stack Overflow

Introduction:I have a ApexCharts chart with data from an API. I'm using an API called finnhub to

Introduction:

I have a ApexCharts chart with data from an API. I'm using an API called finnhub to get the stock market data which is displayed on the chart. The data returned has an array of prices and a corresponding array of times, which are not at an equal interval (stock market is closed at certain times) (prices on the y-axis and time on the x-axis). The data I'm getting is quite high resolution, which means there are a LOT of labels on the x-axis, making it look really cluttered and unreadable. I'm using React Hooks.

The problem I'm getting:

X-axis labels are too close together (image)

As you can see, the labels on the on the x-axis which are displaying the time, are really close together. It looks too cluttered. I want to make it so that there are only about 4-5 labels on the chart which are spaced out evenly across.

Code:

import React, { useState, useEffect } from "react";
import Chart from "react-apexcharts";
import axios from "axios";
import dayjs from "dayjs";

function StockChart() {
    const [options, setOptions] = useState({
        chart: {
            type: "area",
            height: 350,
            zoom: {
                enabled: false
            }
        },
        dataLabels: {
            enabled: false
        },
        stroke: {
            curve: "straight"
        },
        xaxis: {
            categories: [],
            labels: {
                formatter: function (val) {
                    return dayjs(val).format("DD. HH:mm");
                },
                hideOverlappingLabels: Boolean,
                rotate: 0,
                trim: false
            },
            axisTicks: {
                autoskip: true,
                maxTicksLimit: 4,
                interval: 3
            }
        },
        tooltip: {
            x: {
                format: "dd MMM yyyy"
            }
        },
        fill: {
            type: "gradient",
            gradient: {
                shadeIntensity: 1,
                opacityFrom: 0.7,
                opacityTo: 0.9,
                stops: [0, 100]
            }
        }
    });

    const [series, setSeries] = useState([
        {
            name: "Closing Price",
            data: []
        }
    ]);

    useEffect(() => {
        axios
            .get(
";resolution=60&from=1572100000&to=1572910590"
            )
            .then(res => {
                setSeries(prev => {
                    prev[0].data = res.data.c.map(val => val);
                    return prev;
                });
                setOptions(prev => {
                    prev.xaxis.categories = res.data.t.map(time => time * 1000);
                    return prev;
                });
            })
            .catch(err => console.log(err));
    });

    // Ignore the below function and state, it's just for testing
    const [disableChart, setDisableChart] = useState(false);
    function toggleChart() {
        setDisableChart(prev => !prev);
    }

    return (
        <div className="chart-container">
            <h1 onClick={toggleChart}>my chart</h1>
            {disableChart ? null : (
                <Chart options={options} series={series} type="area" width="50%" />
            )}
        </div>
    );
}

export default StockChart;

What I've tried:

I've tried messing around with the ticks property. There was no effect. I've tried setting it to a type: "numeric" and type: "datetime" chart but that caused the following effect:

Irregular data intervals(image)

The x-axis labels are now spaced perfectly, but the problem now is that the data on the chart isn't evenly spaced. As you can see, the data interval between 5:50 and 5:55 is very large, unlike the data interval right above 5:55. I want the data interval of the chart to be equal in all places, like in the first image.

Code:

import React, { useState, useEffect } from "react";
import Chart from "react-apexcharts";
import axios from "axios";
import dayjs from "dayjs";

function StockChart() {
    const [options, setOptions] = useState({
        chart: {
            type: "area",
            height: 350,
            zoom: {
                enabled: false
            }
        },
        dataLabels: {
            enabled: false
        },
        stroke: {
            curve: "straight"
        },
        xaxis: {
            type: "numeric",
            labels: {
                formatter: function (val) {
                    return dayjs(val).format("DD. HH:mm");
                },
                hideOverlappingLabels: Boolean,
                rotate: 0,
                trim: false
            },
            axisTicks: {
                show: true
            }
        },
        tooltip: {
            x: {
                format: "dd MMM yyyy"
            }
        },
        fill: {
            type: "gradient",
            gradient: {
                shadeIntensity: 1,
                opacityFrom: 0.7,
                opacityTo: 0.9,
                stops: [0, 100]
            }
        }
    });

    const [series, setSeries] = useState([
        {
            name: "Closing Price",
            data: []
        }
    ]);

    useEffect(() => {
        axios
            .get(
    ";resolution=60&from=1572100000&to=1572910590"
            )
            .then(res => {
                setSeries(prev => {
                    for (let i = 0; i < res.data.c.length; i++) {
                        console.log(res.data.t[i]);
                        prev[0].data[i] = [res.data.t[i], res.data.c[i]];
                    }
                    console.log(prev);
                    return prev;
                });
            })
            .catch(err => console.log(err));
    });

    // Ignore the below function and state, it's just for testing
    const [disableChart, setDisableChart] = useState(false);
    function toggleChart() {
        setDisableChart(prev => !prev);
    }

    return (
        <div className="chart-container">
            <h1 onClick={toggleChart}>my chart</h1>
            {disableChart ? null : (
                <Chart options={options} series={series} type="area" width="50%" />
            )}
        </div>
    );
}

export default StockChart;

What I want to achieve:

I want to have the data labels on the x-axis be similar to the ones like in the second picture (not too cluttered, only about 4-5 labels per chart), while having the chart itself look like the second picture (distance between data changes is equal). Any help would be greatly appreaciated.

PS: This is my first StackOverflow question, sorry if I did something incorrectly.

Introduction:

I have a ApexCharts chart with data from an API. I'm using an API called finnhub to get the stock market data which is displayed on the chart. The data returned has an array of prices and a corresponding array of times, which are not at an equal interval (stock market is closed at certain times) (prices on the y-axis and time on the x-axis). The data I'm getting is quite high resolution, which means there are a LOT of labels on the x-axis, making it look really cluttered and unreadable. I'm using React Hooks.

The problem I'm getting:

X-axis labels are too close together (image)

As you can see, the labels on the on the x-axis which are displaying the time, are really close together. It looks too cluttered. I want to make it so that there are only about 4-5 labels on the chart which are spaced out evenly across.

Code:

import React, { useState, useEffect } from "react";
import Chart from "react-apexcharts";
import axios from "axios";
import dayjs from "dayjs";

function StockChart() {
    const [options, setOptions] = useState({
        chart: {
            type: "area",
            height: 350,
            zoom: {
                enabled: false
            }
        },
        dataLabels: {
            enabled: false
        },
        stroke: {
            curve: "straight"
        },
        xaxis: {
            categories: [],
            labels: {
                formatter: function (val) {
                    return dayjs(val).format("DD. HH:mm");
                },
                hideOverlappingLabels: Boolean,
                rotate: 0,
                trim: false
            },
            axisTicks: {
                autoskip: true,
                maxTicksLimit: 4,
                interval: 3
            }
        },
        tooltip: {
            x: {
                format: "dd MMM yyyy"
            }
        },
        fill: {
            type: "gradient",
            gradient: {
                shadeIntensity: 1,
                opacityFrom: 0.7,
                opacityTo: 0.9,
                stops: [0, 100]
            }
        }
    });

    const [series, setSeries] = useState([
        {
            name: "Closing Price",
            data: []
        }
    ]);

    useEffect(() => {
        axios
            .get(
"https://finnhub.io/api/v1/stock/candle?symbol=AAPL&resolution=60&from=1572100000&to=1572910590"
            )
            .then(res => {
                setSeries(prev => {
                    prev[0].data = res.data.c.map(val => val);
                    return prev;
                });
                setOptions(prev => {
                    prev.xaxis.categories = res.data.t.map(time => time * 1000);
                    return prev;
                });
            })
            .catch(err => console.log(err));
    });

    // Ignore the below function and state, it's just for testing
    const [disableChart, setDisableChart] = useState(false);
    function toggleChart() {
        setDisableChart(prev => !prev);
    }

    return (
        <div className="chart-container">
            <h1 onClick={toggleChart}>my chart</h1>
            {disableChart ? null : (
                <Chart options={options} series={series} type="area" width="50%" />
            )}
        </div>
    );
}

export default StockChart;

What I've tried:

I've tried messing around with the ticks property. There was no effect. I've tried setting it to a type: "numeric" and type: "datetime" chart but that caused the following effect:

Irregular data intervals(image)

The x-axis labels are now spaced perfectly, but the problem now is that the data on the chart isn't evenly spaced. As you can see, the data interval between 5:50 and 5:55 is very large, unlike the data interval right above 5:55. I want the data interval of the chart to be equal in all places, like in the first image.

Code:

import React, { useState, useEffect } from "react";
import Chart from "react-apexcharts";
import axios from "axios";
import dayjs from "dayjs";

function StockChart() {
    const [options, setOptions] = useState({
        chart: {
            type: "area",
            height: 350,
            zoom: {
                enabled: false
            }
        },
        dataLabels: {
            enabled: false
        },
        stroke: {
            curve: "straight"
        },
        xaxis: {
            type: "numeric",
            labels: {
                formatter: function (val) {
                    return dayjs(val).format("DD. HH:mm");
                },
                hideOverlappingLabels: Boolean,
                rotate: 0,
                trim: false
            },
            axisTicks: {
                show: true
            }
        },
        tooltip: {
            x: {
                format: "dd MMM yyyy"
            }
        },
        fill: {
            type: "gradient",
            gradient: {
                shadeIntensity: 1,
                opacityFrom: 0.7,
                opacityTo: 0.9,
                stops: [0, 100]
            }
        }
    });

    const [series, setSeries] = useState([
        {
            name: "Closing Price",
            data: []
        }
    ]);

    useEffect(() => {
        axios
            .get(
    "https://finnhub.io/api/v1/stock/candle?symbol=AAPL&resolution=60&from=1572100000&to=1572910590"
            )
            .then(res => {
                setSeries(prev => {
                    for (let i = 0; i < res.data.c.length; i++) {
                        console.log(res.data.t[i]);
                        prev[0].data[i] = [res.data.t[i], res.data.c[i]];
                    }
                    console.log(prev);
                    return prev;
                });
            })
            .catch(err => console.log(err));
    });

    // Ignore the below function and state, it's just for testing
    const [disableChart, setDisableChart] = useState(false);
    function toggleChart() {
        setDisableChart(prev => !prev);
    }

    return (
        <div className="chart-container">
            <h1 onClick={toggleChart}>my chart</h1>
            {disableChart ? null : (
                <Chart options={options} series={series} type="area" width="50%" />
            )}
        </div>
    );
}

export default StockChart;

What I want to achieve:

I want to have the data labels on the x-axis be similar to the ones like in the second picture (not too cluttered, only about 4-5 labels per chart), while having the chart itself look like the second picture (distance between data changes is equal). Any help would be greatly appreaciated.

PS: This is my first StackOverflow question, sorry if I did something incorrectly.

Share Improve this question asked Aug 6, 2020 at 11:54 GeorgeGeorge 5912 gold badges7 silver badges18 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 3

Well, I faced the same problem but in vue-project. So this helped to me:

  methods: {
      onChartResize(event) {
        this.$refs.oilProductionProfile.updateOptions({
        xaxis: { tickAmount: Math.ceil(event.srcElement.innerWidth / 140) },
      });
    },
  },
  created() {
    window.addEventListener("resize", this.onChartResize);
  },
  destroyed() {
    window.removeEventListener("resize", this.onChartResize);
  },
 

We subscribing on window event, recalculating tickAmount according to current window's innerwidth, and then calling "updateOptions" to refresh axis.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744899644a4599901.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信