import {Fragment} from 'react';
import {useTheme} from '@emotion/react';
import styled from '@emotion/styled';
import {Location} from 'history';
import moment from 'moment';
import {CompactSelect} from 'sentry/components/compactSelect';
import {t} from 'sentry/locale';
import {space} from 'sentry/styles/space';
import {Series} from 'sentry/types/echarts';
import {getDuration} from 'sentry/utils/formatters';
import usePageFilters from 'sentry/utils/usePageFilters';
import Chart, {useSynchronizeCharts} from 'sentry/views/starfish/components/chart';
import ChartPanel from 'sentry/views/starfish/components/chartPanel';
import {
useQueryDbTables,
useQueryTopDbOperationsChart,
useQueryTopTablesChart,
} from 'sentry/views/starfish/modules/databaseModule/queries';
import {datetimeToClickhouseFilterTimestamps} from 'sentry/views/starfish/utils/dates';
import {zeroFillSeries} from 'sentry/views/starfish/utils/zeroFillSeries';
const INTERVAL = 12;
type Props = {
location: Location;
onChange: (value: string) => void;
table: string;
};
function parseOptions(options, label) {
const prefix = {t('Operation')};
return [
{
value: 'ALL',
prefix,
label: `ALL`,
},
...options.map(action => {
return {
value: action.key,
prefix,
label: `${action.key || 'null'} - ${getDuration(
action.value / 1000,
2,
true
)} ${label}`,
};
}),
];
}
export default function DatabaseChartView({table, onChange}: Props) {
const pageFilter = usePageFilters();
const theme = useTheme();
const {start_timestamp, end_timestamp} = datetimeToClickhouseFilterTimestamps(
pageFilter.selection.datetime
);
const {data: tableData} = useQueryDbTables();
const {isLoading: isTopGraphLoading, data: topGraphData} =
useQueryTopDbOperationsChart(INTERVAL);
const {isLoading: tableGraphLoading, data: tableGraphData} =
useQueryTopTablesChart(INTERVAL);
const seriesByDomain: {[action: string]: Series} = {};
const tpmByDomain: {[action: string]: Series} = {};
if (!tableGraphLoading) {
tableGraphData.forEach(datum => {
seriesByDomain[datum.domain] = {
seriesName: datum.domain,
data: [],
};
tpmByDomain[datum.domain] = {
seriesName: datum.domain,
data: [],
};
});
tableGraphData.forEach(datum => {
seriesByDomain[datum.domain].data.push({
value: datum.p50,
name: datum.interval,
});
tpmByDomain[datum.domain].data.push({
value: datum.count,
name: datum.interval,
});
});
}
const topDomains = Object.values(seriesByDomain).map(series =>
zeroFillSeries(
series,
moment.duration(INTERVAL, 'hours'),
moment(start_timestamp),
moment(end_timestamp)
)
);
const tpmDomains = Object.values(tpmByDomain).map(series =>
zeroFillSeries(
series,
moment.duration(INTERVAL, 'hours'),
moment(start_timestamp),
moment(end_timestamp)
)
);
const tpmByQuery: {[query: string]: Series} = {};
const seriesByQuery: {[action: string]: Series} = {};
if (!isTopGraphLoading) {
topGraphData.forEach(datum => {
seriesByQuery[datum.action] = {
seriesName: datum.action,
data: [],
};
tpmByQuery[datum.action] = {
seriesName: datum.action,
data: [],
};
});
topGraphData.forEach(datum => {
seriesByQuery[datum.action].data.push({
value: datum.p50,
name: datum.interval,
});
tpmByQuery[datum.action].data.push({
value: datum.count,
name: datum.interval,
});
});
}
const chartColors = [...theme.charts.getColorPalette(6).slice(2, 7), theme.gray300];
useSynchronizeCharts([!tableGraphLoading]);
return (
{tableData.length === 1 && tableData[0].key === '' ? (
) : (
onChange(opt.value)}
/>
)}
);
}
const Selectors = styled(`div`)`
display: flex;
margin-bottom: ${space(2)};
`;
const ChartsContainer = styled('div')`
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: ${space(2)};
`;
const ChartsContainerItem = styled('div')`
flex: 1;
`;