import { Utils } from 'arm-common'; import p from 'prop-types'; import React, { useLayoutEffect, useMemo, useState } from 'react'; import { ChartContainer, getRoot, useAm5, useAm5Colors } from '../Am5.jsx'; const classNamePrefix = 'armu_ai_chatbot-time-chart'; export default function TimeChart(props) { const { id, xAxis, yAxis, series, data } = props; const [chartId] = useState(id || Utils.uuid(classNamePrefix)); const am5 = useAm5(); const am5Colors = useAm5Colors(); const allValues = useMemo(() => { if (data?.length) { if (series?.length) { const values = []; for (let item of data) { for (let serie of series) { if (!isNaN(item[serie.yAxis])) { values.push(item[serie.yAxis]); } } } return values; } else { return data.map(d => d[yAxis]); } } return []; }, [data, series, yAxis]); const minValue = Math.min(...allValues); const maxValue = Math.max(...allValues); const largerValue = Math.max(maxValue, Math.abs(minValue)); useLayoutEffect(() => { if (am5 && data) { const root = getRoot(chartId); const chart = root.container.children.push( am5xy.XYChart.new(root, { panX: true, panY: true, wheelX: "panX", wheelY: "zoomX", pinchZoomX: true, layout: root.verticalLayout }) ); const cursor = chart.set("cursor", am5xy.XYCursor.new(root, { behavior: "none" })); cursor.lineY.set("visible", false); const xAxisAm5 = chart.xAxes.push( am5xy.DateAxis.new(root, { maxDeviation: 0.2, baseInterval: { timeUnit: "day", count: 1 }, renderer: am5xy.AxisRendererX.new(root, {}), tooltip: am5.Tooltip.new(root, {}) }) ); const yAxisAm5 = chart.yAxes.push( am5xy.ValueAxis.new(root, { renderer: am5xy.AxisRendererY.new(root, { pan: "zoom" }), min: minValue - (largerValue * 0.1), max: maxValue + (largerValue * 0.1), strictMinMax: true }) ); chart.set("colors", am5.ColorSet.new(root, { colors: am5Colors })); if (series?.length) { const legend = chart.children.push(am5.Legend.new(root, { centerX: am5.p50, x: am5.p50, })); series.forEach(addSeries.bind({ root, chart, xAxisAm5, yAxisAm5, xAxis, data })); legend.data.setAll(chart.series.values); } else if (yAxis) { addSeries.call({ root, chart, xAxisAm5, yAxisAm5, xAxis, data }, { yAxis }); } chart.set("scrollbarX", am5.Scrollbar.new(root, { orientation: "horizontal" })); } }, [am5, allValues]); return ( ); } TimeChart.defaultProps = { id: '', xAxis: '', yAxis: '', series: [], data: null } TimeChart.propTypes = { id: p.string, xAxis: p.string.isRequired, yAxis: p.string, series: p.arrayOf(p.shape({ name: p.string, yAxis: p.string })), data: p.arrayOf(p.object).isRequired } function addSeries(seriesConfig) { const { root, chart, xAxisAm5, yAxisAm5, xAxis, data } = this; const { name, yAxis } = seriesConfig; const tooltip = am5.Tooltip.new(root, { labelText: "{valueY}", }); const series = chart.series.push( am5xy.LineSeries.new(root, { name, minBulletDistance: 10, xAxis: xAxisAm5, yAxis: yAxisAm5, valueXField: xAxis, valueYField: yAxis, tooltip }) ); series.bullets.push(function () { return am5.Bullet.new(root, { sprite: am5.Circle.new(root, { radius: 6, fill: series.get("fill"), stroke: root.interfaceColors.get("background"), strokeWidth: 2, }) }); }); series.data.setAll(data); }