Введение:
У меня есть диаграмма ApexCharts с данными из API. Я использую API под названием finnhub для получения данных фондового рынка, которые отображаются на графике. Возвращенные данные содержат массив цен и соответствующий массив значений времени, которые не находятся в равном интервале (фондовый рынок закрывается в определенные моменты времени) (цены по оси Y и время по оси X). Данные, которые я получаю, имеют довольно высокое разрешение, а это означает, что на оси X МНОГО подписей, что делает их очень загроможденными и нечитаемыми. Я использую React Hooks.
Проблема, которую я получаю:
Метки оси X расположены слишком близко друг к другу (изображение)
Как видите, метки на оси x, которые показывают время, действительно близко друг к другу. Он выглядит слишком загроможденным. Я хочу сделать так, чтобы на диаграмме было всего около 4-5 меток, которые равномерно разнесены по горизонтали.
Код:
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;
Что я пробовал:
Я пробовал возиться со свойством тиков. Эффекта не было. Я попытался установить его на диаграмму type: "numeric"
и type: "datetime"
, но это вызвало следующий эффект:
Нерегулярные интервалы данных (изображение)
x- метки осей теперь размещены идеально, но проблема в том, что данные на диаграмме расположены неравномерно. Как видите, интервал данных между 5: 50 и 5: 55 очень велик, в отличие от интервала данных прямо выше 5: 55 . Я хочу, чтобы интервал данных диаграммы был одинаковым во всех местах, как на первом изображении.
Код:
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;
Что я хочу для достижения:
Я хочу, чтобы метки данных на оси x были похожи на те, что показаны на втором рисунке (не слишком загромождены, всего около 4-5 меток на диаграмму), в то время как если сама диаграмма будет выглядеть как вторая картинка (расстояние между изменениями данных равно). Любая помощь будет очень приветствоваться.
PS: Это мой первый вопрос по StackOverflow, извините, если я сделал что-то неправильно.