This is an automated email from the ASF dual-hosted git repository. vogievetsky pushed a commit to branch segment_timeline2 in repository https://gitbox.apache.org/repos/asf/druid.git
commit b865422cc54d1e1eeb8ab2284f095930c2ffa962 Author: Vadim Ogievetsky <[email protected]> AuthorDate: Mon Nov 4 20:56:51 2024 -0800 now line and fixes --- .../segment-timeline/segment-bar-chart-render.scss | 13 ++++------- .../segment-timeline/segment-bar-chart-render.tsx | 27 +++++++++++++++++----- .../segment-timeline/segment-bar-chart.tsx | 4 ++-- web-console/src/hooks/use-clock.ts | 18 ++++++--------- 4 files changed, 34 insertions(+), 28 deletions(-) diff --git a/web-console/src/components/segment-timeline/segment-bar-chart-render.scss b/web-console/src/components/segment-timeline/segment-bar-chart-render.scss index c036c313cf3..e6badd45a7c 100644 --- a/web-console/src/components/segment-timeline/segment-bar-chart-render.scss +++ b/web-console/src/components/segment-timeline/segment-bar-chart-render.scss @@ -73,16 +73,11 @@ opacity: 0.5; } } - } - - .bar-chart-tooltip { - position: absolute; - left: 20px; - right: 0; - div { - display: inline-block; - width: 230px; + .now-line { + stroke: orange; + stroke-dasharray: 2, 2; + opacity: 0.7; } } diff --git a/web-console/src/components/segment-timeline/segment-bar-chart-render.tsx b/web-console/src/components/segment-timeline/segment-bar-chart-render.tsx index adfb5657309..8b29ed428dd 100644 --- a/web-console/src/components/segment-timeline/segment-bar-chart-render.tsx +++ b/web-console/src/components/segment-timeline/segment-bar-chart-render.tsx @@ -19,14 +19,14 @@ import type { NonNullDateRange } from '@blueprintjs/datetime'; import IntervalTree from '@flatten-js/interval-tree'; import classNames from 'classnames'; -import { max } from 'd3-array'; +import { max, sort, sum } from 'd3-array'; import { axisBottom, axisLeft } from 'd3-axis'; import { scaleLinear, scaleUtc } from 'd3-scale'; import type { MouseEvent as ReactMouseEvent, ReactNode } from 'react'; import { useMemo, useRef, useState } from 'react'; import { getDatasourceColor } from '../../druid-models'; -import { useGlobalEventListener } from '../../hooks'; +import { useClock, useGlobalEventListener } from '../../hooks'; import { capitalizeFirst, clamp, @@ -36,6 +36,8 @@ import { formatBytes, formatNumber, groupBy, + groupByAsMap, + minute, month, prettyFormatIsoDate, TZ_UTC, @@ -50,7 +52,7 @@ import { aggregateSegmentStats, formatIntervalStat, INTERVAL_STATS } from './com import './segment-bar-chart-render.scss'; const CHART_MARGIN: Margin = { top: 10, right: 0, bottom: 25, left: 70 }; -const MIN_BAR_WIDTH = 3; +const MIN_BAR_WIDTH = 4; const POSSIBLE_GRANULARITIES = [ new Duration('PT15M'), new Duration('PT1H'), @@ -60,14 +62,21 @@ const POSSIBLE_GRANULARITIES = [ new Duration('P1Y'), ]; -const EXTEND_X_SCALE_DOMAIN_BY = 10; +const EXTEND_X_SCALE_DOMAIN_BY = 4; function offsetDateRange(dateRange: NonNullDateRange, offset: number): NonNullDateRange { return [new Date(dateRange[0].valueOf() + offset), new Date(dateRange[1].valueOf() + offset)]; } function stackIntervalRows(trimmedIntervalRows: TrimmedIntervalRow[]): IntervalBar[] { - const sortedIntervalRows = trimmedIntervalRows.sort((a, b) => { + // Total size of the datasource will be user as an ordering tiebreaker + const datasourceToTotalSize = groupByAsMap( + trimmedIntervalRows, + intervalRow => intervalRow.datasource, + intervalRows => sum(intervalRows, intervalRow => intervalRow.size), + ); + + const sortedIntervalRows = sort(trimmedIntervalRows, (a, b) => { const shownDaysDiff = b.shownDays - a.shownDays; if (shownDaysDiff) return shownDaysDiff; @@ -75,7 +84,7 @@ function stackIntervalRows(trimmedIntervalRows: TrimmedIntervalRow[]): IntervalB b.originalTimeSpan.getCanonicalLength() - a.originalTimeSpan.getCanonicalLength(); if (timeSpanDiff) return timeSpanDiff; - return b.datasource.localeCompare(a.datasource); + return datasourceToTotalSize[b.datasource] - datasourceToTotalSize[a.datasource]; }); const intervalTree = new IntervalTree(); @@ -125,6 +134,7 @@ export const SegmentBarChartRender = function SegmentBarChartRender( const [bubbleOpenOn, setBubbleOpenOn] = useState< { start: Date; end: Date; x: number; y: number; text: string } | undefined >(); + const now = useClock(minute.canonicalLength); const svgRef = useRef<SVGSVGElement | null>(null); const trimGranularity = useMemo(() => { @@ -348,6 +358,8 @@ export const SegmentBarChartRender = function SegmentBarChartRender( }; } + const nowX = timeScale(now); + return ( <div className="segment-bar-chart-render"> <svg @@ -400,6 +412,9 @@ export const SegmentBarChartRender = function SegmentBarChartRender( height={innerStage.height} /> )} + {0 < nowX && nowX < innerStage.width && ( + <line className="now-line" x1={nowX} x2={nowX} y1={0} y2={innerStage.height + 8} /> + )} {intervalBars.map((intervalBar, i) => { return ( <rect diff --git a/web-console/src/components/segment-timeline/segment-bar-chart.tsx b/web-console/src/components/segment-timeline/segment-bar-chart.tsx index 047fda7fdd2..ba73c8422c6 100644 --- a/web-console/src/components/segment-timeline/segment-bar-chart.tsx +++ b/web-console/src/components/segment-timeline/segment-bar-chart.tsx @@ -66,7 +66,7 @@ export const SegmentBarChart = function SegmentBarChart(props: SegmentBarChartPr const query = SqlQuery.from(N('sys').table('segments')) .changeWhereExpression( SqlExpression.and( - sql`'${dateRange[0].toISOString()}' <= "end" AND "start" <= '${dateRange[1].toISOString()}'`, + sql`"start" <= '${dateRange[1].toISOString()}' AND '${dateRange[0].toISOString()}' < "end"`, C('start').unequal(START_OF_TIME_DATE), C('end').unequal(END_OF_TIME_DATE), C('is_published').equal(1), @@ -105,7 +105,7 @@ export const SegmentBarChart = function SegmentBarChart(props: SegmentBarChartPr if (startStr === START_OF_TIME_DATE && endStr === END_OF_TIME_DATE) return; const start = new Date(startStr); const end = new Date(endStr); - if (!(dateRange[0] <= end && start <= dateRange[1])) return; + if (!(start <= dateRange[1] && dateRange[0] < end)) return; return { start, diff --git a/web-console/src/hooks/use-clock.ts b/web-console/src/hooks/use-clock.ts index 5d126442195..a909a2c1f74 100644 --- a/web-console/src/hooks/use-clock.ts +++ b/web-console/src/hooks/use-clock.ts @@ -16,7 +16,9 @@ * limitations under the License. */ -import { useEffect, useState } from 'react'; +import { useState } from 'react'; + +import { useInterval } from './use-interval'; function getNowToSecond(): Date { const now = new Date(); @@ -24,18 +26,12 @@ function getNowToSecond(): Date { return now; } -export function useClock() { +export function useClock(updateInterval = 1000) { const [now, setNow] = useState<Date>(getNowToSecond); - useEffect(() => { - const checkInterval = setInterval(() => { - setNow(getNowToSecond()); - }, 1000); - - return () => { - clearInterval(checkInterval); - }; - }, []); + useInterval(() => { + setNow(getNowToSecond()); + }, updateInterval); return now; } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
