diff --git a/assets/styles/base.scss b/assets/styles/base.scss index b2d9a8b4..1a991ac8 100644 --- a/assets/styles/base.scss +++ b/assets/styles/base.scss @@ -78,7 +78,7 @@ $grayscale: ( --block-progress-fill-background: #33a853; --logo-name: var(--txt-primary); --bar-fill: rgb(243, 147, 45); - --validator-active: #85f891; + --validator-active: #18d2a5; --validator-inactive: #1ca7ed; --validator-jailed: #f8774a; --supply: #1ca7ed; diff --git a/components/modules/address/AddressCharts.vue b/components/modules/address/AddressCharts.vue index 233053bb..c1c102e5 100644 --- a/components/modules/address/AddressCharts.vue +++ b/components/modules/address/AddressCharts.vue @@ -1,17 +1,20 @@ @@ -659,207 +222,23 @@ onBeforeUnmount(() => { - - Txs - - - - - {{ abbreviate(Math.max(...txSeries.map((d) => d.value)), 0) }} - - - - - {{ abbreviate(Math.round(Math.max(...txSeries.map((d) => d.value)) / 2), 0) }} - - - - 0 - - - - - - - {{ - DateTime.now() - .minus({ days: selectedPeriod.value - 1 }) - .toFormat("LLL dd") - }} - - - {{ DateTime.now().minus({ hours: selectedPeriod.value }).set({ minutes: 0 }).toFormat("hh:mm a") }} - - - {{ - selectedPeriod.timeframe === "day" ? "Today" : "Now" - }} - - - - -
-
-
-
- - {{ badgeText }} - -
- - - Txs - {{ tooltipText }} - - -
- - - - - - - - Fee Spent - - - - - {{ - tia(Math.max(...feeSeries.map((d) => d.value)), 0) > 1 - ? tia(Math.max(...feeSeries.map((d) => d.value)), 0) - : tia(Math.max(...feeSeries.map((d) => d.value)), 2) - }} - TIA - - - - - {{ - tia(Math.round(Math.max(...feeSeries.map((d) => d.value)) / 2), 0) > 1 - ? tia(Math.round(Math.max(...feeSeries.map((d) => d.value)) / 2), 0) - : tia(Math.round(Math.max(...feeSeries.map((d) => d.value)) / 2), 2) - }} - TIA - - - - 0 - - - - - - - {{ - DateTime.now() - .minus({ days: selectedPeriod.value - 1 }) - .toFormat("LLL dd") - }} - - - {{ DateTime.now().minus({ hours: selectedPeriod.value }).set({ minutes: 0 }).toFormat("hh:mm a") }} - - - {{ - selectedPeriod.timeframe === "day" ? "Today" : "Now" - }} - - - - -
-
-
-
- - {{ badgeText }} - -
- - - Spent - {{ tia(tooltipText) }} TIA - - -
- - - - - + + + diff --git a/components/modules/namespace/NamespaceCharts.vue b/components/modules/namespace/NamespaceCharts.vue index 56d838bd..ea8cd7e8 100644 --- a/components/modules/namespace/NamespaceCharts.vue +++ b/components/modules/namespace/NamespaceCharts.vue @@ -9,9 +9,14 @@ import Button from "@/components/ui/Button.vue" import { Dropdown, DropdownItem } from "@/components/ui/Dropdown" import Popover from "@/components/ui/Popover.vue" import Toggle from "@/components/ui/Toggle.vue" +import ChartOnEntityPage from "~/components/shared/ChartOnEntityPage.vue" +import Icon from "@/components/Icon.vue" +import Text from "@/components/Text.vue" +import Flex from "@/components/Flex.vue" /** Services */ import { abbreviate, formatBytes } from "@/services/utils" +import { createDataMap, generateDateForPeriod, generateSeriesData, PERIODS as periods } from "@/services/utils/entityCharts" /** API */ import { fetchNamespaceSeries } from "@/services/api/stats" @@ -29,29 +34,7 @@ const props = defineProps({ /** Chart settings */ const selectedPeriodIdx = ref(2) -const periods = ref([ - { - title: "Last 24 hours", - value: 24, - timeframe: "hour", - }, - { - title: "Last 7 days", - value: 7, - timeframe: "day", - }, - { - title: "Last 31 days", - value: 30, - timeframe: "day", - }, - { - title: "Last 12 months", - value: 12, - timeframe: "month", - }, -]) -const selectedPeriod = computed(() => periods.value[selectedPeriodIdx.value]) +const selectedPeriod = computed(() => periods[selectedPeriodIdx.value]) const chartView = ref("line") const loadLastValue = ref(true) @@ -63,14 +46,6 @@ const handleClose = () => { isOpen.value = false } -const handleChangeChartView = () => { - if (chartView.value === "line") { - chartView.value = "bar" - } else { - chartView.value = "line" - } -} - const updateUserSettings = () => { settingsStore.chart = { ...settingsStore.chart, @@ -79,523 +54,91 @@ const updateUserSettings = () => { } } -/** Charts */ -const chartWrapperEl = ref() -const sizeSeriesChartEl = ref() -const pfbSeriesChartEl = ref() - /** Data */ const isLoading = ref(false) const sizeSeries = ref([]) const pfbSeries = ref([]) -/** Tooltip */ -const showSeriesTooltip = ref(false) -const showPfbTooltip = ref(false) -const tooltipEl = ref() -const tooltipXOffset = ref(0) -const tooltipYOffset = ref(0) -const tooltipYDataOffset = ref(0) -const tooltipDynamicXPosition = ref(0) -const tooltipText = ref("") - -const badgeEl = ref() -const badgeText = ref("") -const badgeOffset = ref(0) - -const xAxisLabels = computed(() => { - let labels = { - firstDate: "", - lastDate: "", - } - - switch (selectedPeriod.value.timeframe) { - case "month": - labels.firstDate = DateTime.now() - .minus({ months: selectedPeriod.value.value - 1 }) - .toFormat("LLL y") - labels.lastDate = loadLastValue.value ? DateTime.now().toFormat("LLL") : DateTime.now().minus({ months: 1 }).toFormat("LLL") - break - case "day": - labels.firstDate = DateTime.now() - .minus({ days: selectedPeriod.value.value - 1 }) - .toFormat("LLL dd") - labels.lastDate = loadLastValue.value ? "Today" : DateTime.now().minus({ days: 1 }).toFormat("LLL dd") - break - default: - labels.firstDate = DateTime.now() - .minus({ hours: selectedPeriod.value.value - 1 }) - .set({ minutes: 0 }) - .toFormat("hh:mm a") - labels.lastDate = loadLastValue.value ? "Now" : DateTime.now().minus({ hours: 1 }).set({ minutes: 0 }).toFormat("hh:mm a") - break - } - - return labels -}) - -const buildLineChart = (chartEl, data, onEnter, onLeave) => { - const width = chartWrapperEl.value.wrapper.getBoundingClientRect().width - const height = 180 - const marginTop = 0 - const marginRight = 0 - const marginBottom = 24 - const marginLeft = 52 - - const MAX_VALUE = d3.max(data, (d) => d.value) ? d3.max(data, (d) => d.value) : 1 - - /** Scale */ - const x = d3.scaleUtc( - d3.extent(data, (d) => d.date), - [marginLeft, width - marginRight], - ) - const y = d3.scaleLinear([0, MAX_VALUE], [height - marginBottom - 6, marginTop]) - const line = d3 - .line() - .x((d) => x(d.date)) - .y((d) => y(d.value)) - - /** Tooltip */ - const bisect = d3.bisector((d) => d.date).center - const onPointermoved = (event) => { - onEnter() - - const idx = bisect(data, x.invert(d3.pointer(event)[0])) - - tooltipXOffset.value = x(data[idx].date) - tooltipYDataOffset.value = y(data[idx].value) - tooltipYOffset.value = event.layerY - tooltipText.value = data[idx].value - - if (tooltipEl.value) { - if (idx > parseInt(selectedPeriod.value.value / 2)) { - tooltipDynamicXPosition.value = tooltipXOffset.value - tooltipEl.value.wrapper.getBoundingClientRect().width - 16 - } else { - tooltipDynamicXPosition.value = tooltipXOffset.value + 16 - } - } - - badgeText.value = - selectedPeriod.value.timeframe === "month" - ? DateTime.fromJSDate(data[idx].date).toFormat("LLL") - : selectedPeriod.value.timeframe === "day" - ? DateTime.fromJSDate(data[idx].date).toFormat("LLL dd") - : DateTime.fromJSDate(data[idx].date).set({ minutes: 0 }).toFormat("hh:mm a") - - if (!badgeEl.value) return - const badgeWidth = badgeEl.value.getBoundingClientRect().width - if (tooltipXOffset.value - marginLeft < badgeWidth / 2) { - badgeOffset.value = 0 - } else if (badgeWidth + tooltipXOffset.value > width) { - badgeOffset.value = Math.abs(width - (badgeWidth + tooltipXOffset.value)) + (data.length - 1 - idx) * 2 - } else { - badgeOffset.value = badgeWidth / 2 - } - } - const onPointerleft = () => { - onLeave() - badgeText.value = "" - } - - /** SVG Container */ - const svg = d3 - .create("svg") - .attr("width", width) - .attr("height", height) - .attr("viewBox", [0, 0, width, height]) - .attr("preserveAspectRatio", "none") - .attr("style", "max-width: 100%; height: intrinsic;") - .style("-webkit-tap-highlight-color", "transparent") - .on("pointerenter pointermove", onPointermoved) - .on("pointerleave", onPointerleft) - .on("touchstart", (event) => event.preventDefault()) - - /** Vertical Lines */ - svg.append("path") - .attr("fill", "none") - .attr("stroke", "var(--op-10)") - .attr("stroke-width", 2) - .attr("d", `M${marginLeft},${height - marginBottom + 2} L${marginLeft},${height - marginBottom - 5}`) - svg.append("path") - .attr("fill", "none") - .attr("stroke", "var(--op-10)") - .attr("stroke-width", 2) - .attr("d", `M${width - 1},${height - marginBottom + 2} L${width - 1},${height - marginBottom - 5}`) - - /** Default Horizontal Line */ - svg.append("path") - .attr("fill", "none") - .attr("stroke", "var(--op-10)") - .attr("stroke-width", 2) - .attr("d", `M${0},${height - marginBottom - 6} L${width},${height - marginBottom - 6}`) - - /** Chart Line */ - let path1 = null - let path2 = null - path1 = svg - .append("path") - .attr("fill", "none") - .attr("stroke", "var(--brand)") - .attr("stroke-width", 2) - .attr("stroke-linecap", "round") - .attr("stroke-linejoin", "round") - .attr("d", line(loadLastValue.value ? data.slice(0, data.length - 1) : data)) - - if (loadLastValue.value) { - // Create pattern - const defs = svg.append("defs") - const pattern = defs - .append("pattern") - .attr("id", "dashedPattern") - .attr("width", 8) - .attr("height", 2) - .attr("patternUnits", "userSpaceOnUse") - pattern.append("rect").attr("width", 4).attr("height", 2).attr("fill", "var(--brand)") - pattern.append("rect").attr("x", 8).attr("width", 4).attr("height", 2).attr("fill", "transparent") - - // Last dash segment - path2 = svg - .append("path") - .attr("fill", "none") - .attr("stroke", "url(#dashedPattern)") - .attr("stroke-width", 2) - .attr("stroke-linecap", "round") - .attr("stroke-linejoin", "round") - .attr("d", line(data.slice(data.length - 2, data.length))) - } - - const totalDuration = 1_000 - const path1Duration = loadLastValue.value ? (totalDuration / data.length) * (data.length - 1) : totalDuration - const path1Length = path1.node().getTotalLength() - - path1 - .attr("stroke-dasharray", path1Length) - .attr("stroke-dashoffset", path1Length) - .transition() - .duration(path1Duration) - .ease(d3.easeLinear) - .attr("stroke-dashoffset", 0) - - if (loadLastValue.value) { - const path2Duration = totalDuration / data.length - const path2Length = path2.node().getTotalLength() + 1 - - path2 - .attr("stroke-dasharray", path2Length) - .attr("stroke-dashoffset", path2Length) - .transition() - .duration(path2Duration) - .ease(d3.easeLinear) - .delay(path1Duration) - .attr("stroke-dashoffset", 0) - } - - const point = svg - .append("circle") - .attr("cx", x(data[data.length - 1].date)) - .attr("cy", y(data[data.length - 1].value)) - .attr("fill", "var(--brand)") - .attr("r", 3) - .attr("opacity", 0) - - point.transition().delay(totalDuration).duration(200).attr("opacity", 1) - - if (chartEl.children[0]) chartEl.children[0].remove() - chartEl.append(svg.node()) -} - -const buildBarChart = (chartEl, data, onEnter, onLeave, metric) => { - const width = chartWrapperEl.value.wrapper.getBoundingClientRect().width - const height = 180 - const marginTop = 0 - const marginRight = 2 - const marginBottom = 24 - const marginLeft = 52 - - const barWidth = Math.max(Math.round((width - marginLeft - marginRight) / data.length - (data.length > 7 ? 4 : 8)), 4) - - const MAX_VALUE = d3.max(data, (d) => d.value) ? d3.max(data, (d) => d.value) : 1 - - /** Scale */ - const x = d3.scaleUtc( - d3.extent(data, (d) => d.date), - [marginLeft, width - marginRight - barWidth], - ) - const y = d3.scaleLinear([0, MAX_VALUE], [height - marginBottom, marginTop]) - - /** Tooltip */ - const bisect = d3.bisector((d) => d.date).center - const onPointermoved = (event) => { - onEnter() - - const idx = bisect(data, x.invert(d3.pointer(event)[0] - barWidth / 2)) - - const elements = document.querySelectorAll(`[metric="${metric}"]`) - elements.forEach((el) => { - if (+el.getAttribute("data-index") === idx) { - el.style.filter = "brightness(1.2)" - } else { - el.style.filter = "brightness(0.6)" - } - }) - - tooltipXOffset.value = x(data[idx].date) - tooltipYDataOffset.value = y(data[idx].value) - tooltipYOffset.value = event.layerY - tooltipText.value = data[idx].value - - if (tooltipEl.value) { - if (idx > parseInt(selectedPeriod.value.value / 2)) { - tooltipDynamicXPosition.value = tooltipXOffset.value - tooltipEl.value.wrapper.getBoundingClientRect().width - 16 - } else { - tooltipDynamicXPosition.value = tooltipXOffset.value + 16 - } - } - - badgeText.value = - selectedPeriod.value.timeframe === "month" - ? DateTime.fromJSDate(data[idx].date).toFormat("LLL") - : selectedPeriod.value.timeframe === "day" - ? DateTime.fromJSDate(data[idx].date).toFormat("LLL dd") - : DateTime.fromJSDate(data[idx].date).set({ minutes: 0 }).toFormat("hh:mm a") - - if (!badgeEl.value) return - const badgeWidth = badgeEl.value.getBoundingClientRect().width - if (tooltipXOffset.value - marginLeft < badgeWidth / 2) { - badgeOffset.value = 0 - } else if (badgeWidth + tooltipXOffset.value > width) { - badgeOffset.value = Math.abs(width - (badgeWidth + tooltipXOffset.value)) + (data.length - 1 - idx) * 2 - } else { - badgeOffset.value = (badgeWidth - barWidth) / 2 - } - } - const onPointerleft = () => { - onLeave() - - const elements = document.querySelectorAll("[data-index]") - elements.forEach((el) => { - el.style.filter = "" - }) - badgeText.value = "" - } +/** Series config */ +const seriesConfig = [ + { + name: "size", + metric: "size", + series: sizeSeries, + title: "DA Usage", + tooltipLabel: "Usage", + yAxisFormatter: (value) => formatBytes(value, 0), + tooltipValueFormatter: formatBytes, + unit: null, + }, + { + name: "pfb_count", + metric: "pfb", + series: pfbSeries, + title: "Pay For Blobs Count", + tooltipLabel: "Count", + yAxisFormatter: abbreviate, + tooltipValueFormatter: abbreviate, + unit: null, + }, +] - /** SVG Container */ - const svg = d3 - .create("svg") - .attr("width", width) - .attr("height", height) - .attr("viewBox", [0, 0, width, height]) - .attr("preserveAspectRatio", "none") - .attr("style", "max-width: 100%; height: intrinsic;") - .style("-webkit-tap-highlight-color", "transparent") - .on("pointerenter pointermove", onPointermoved) - .on("pointerleave", onPointerleft) - .on("touchstart", (event) => event.preventDefault()) - - /** Vertical Lines */ - svg.append("path") - .attr("fill", "none") - .attr("stroke", "var(--op-10)") - .attr("stroke-width", 2) - .attr("d", `M${marginLeft},${height - marginBottom + 2} L${marginLeft},${height - marginBottom - 5}`) - svg.append("path") - .attr("fill", "none") - .attr("stroke", "var(--op-10)") - .attr("stroke-width", 2) - .attr("d", `M${width - 1},${height - marginBottom + 2} L${width - 1},${height - marginBottom - 5}`) - - /** Default Horizontal Line */ - svg.append("path") - .attr("fill", "none") - .attr("stroke", "var(--op-10)") - .attr("stroke-width", 2) - .attr("d", `M${0},${height - marginBottom - 6} L${width},${height - marginBottom - 6}`) - - /** Chart Bars */ - svg.append("defs") - .append("pattern") - .attr("id", "diagonal-stripe") - .attr("width", 6) - .attr("height", 6) - .attr("patternUnits", "userSpaceOnUse") - .attr("patternTransform", "rotate(45)") - .append("rect") - .attr("width", 2) - .attr("height", 6) - .attr("transform", "translate(0,0)") - .attr("fill", "var(--brand)") - - svg.append("g") - .selectAll("g") - .data(data) - .enter() - .append("rect") - .attr("class", "bar") - .attr("data-index", (d, i) => i) - .attr("metric", metric) - .attr("x", (d) => x(new Date(d.date))) - .attr("y", (d) => y(d.value)) - .attr("width", barWidth) - .attr("fill", (d, i) => (loadLastValue.value && i === data.length - 1 ? `url(#diagonal-stripe)` : "var(--brand)")) - .transition() - .duration(1_000) - .attr("height", (d) => Math.max(height - marginBottom - 6 - y(d.value), 0)) - - if (chartEl.children[0]) chartEl.children[0].remove() - chartEl.append(svg.node()) -} +const sizeConfig = computed(() => seriesConfig.find((config) => config.metric === "size")) +const pfbConfig = computed(() => seriesConfig.find((config) => config.metric === "pfb")) -const fetchData = async (metric, from) => { - const data = await fetchNamespaceSeries({ +const fetchData = async (metric) => { + return await fetchNamespaceSeries({ id: props.id, name: metric, timeframe: selectedPeriod.value.timeframe, - from: from - ? from - : parseInt( - DateTime.now().minus({ - days: selectedPeriod.value.timeframe === "day" ? selectedPeriod.value.value : 0, - hours: selectedPeriod.value.timeframe === "hour" ? selectedPeriod.value.value : 0, - months: selectedPeriod.value.timeframe === "month" ? selectedPeriod.value.value : 0, - }).ts / 1_000, - ), + from: parseInt( + DateTime.now().minus({ + days: selectedPeriod.value.timeframe === "day" ? selectedPeriod.value.value : 0, + hours: selectedPeriod.value.timeframe === "hour" ? selectedPeriod.value.value : 0, + months: selectedPeriod.value.timeframe === "month" ? selectedPeriod.value.value : 0, + }).ts / 1_000, + ), }) - - return data -} -const getSizeSeries = async () => { - sizeSeries.value = [] - - const sizeSeriesRawData = await fetchData("size") - - const sizeSeriesMap = {} - sizeSeriesRawData.forEach((item) => { - sizeSeriesMap[ - DateTime.fromISO(item.time).toFormat(["day", "month"].includes(selectedPeriod.value.timeframe) ? "y-LL-dd" : "y-LL-dd-HH") - ] = item.value - }) - - for (let i = 1; i < selectedPeriod.value.value + 1; i++) { - let dt - if (selectedPeriod.value.timeframe === "month") { - dt = DateTime.now() - .startOf("month") - .minus({ - months: selectedPeriod.value.timeframe === "month" ? selectedPeriod.value.value - i : 0, - }) - } else { - dt = DateTime.now().minus({ - days: selectedPeriod.value.timeframe === "day" ? selectedPeriod.value.value - i : 0, - hours: selectedPeriod.value.timeframe === "hour" ? selectedPeriod.value.value - i : 0, - }) - } - sizeSeries.value.push({ - date: dt.toJSDate(), - value: - parseInt( - sizeSeriesMap[dt.toFormat(["day", "month"].includes(selectedPeriod.value.timeframe) ? "y-LL-dd" : "y-LL-dd-HH")], - ) || 0, - }) - } } -const getPfbSeries = async () => { - pfbSeries.value = [] - - const pfbSeriesRawData = await fetchData("pfb_count") +const generateSeries = async (configs) => { + isLoading.value = true - const pfbSeriesMap = {} - pfbSeriesRawData.forEach((item) => { - pfbSeriesMap[ - DateTime.fromISO(item.time).toFormat(["day", "month"].includes(selectedPeriod.value.timeframe) ? "y-LL-dd" : "y-LL-dd-HH") - ] = item.value - }) + await Promise.all( + configs.map(async (config) => { + const rawData = await fetchData(config.name) + const dataMap = createDataMap(rawData, selectedPeriod.value.timeframe) + generateSeriesData(selectedPeriod.value, dataMap, config.series) + }), + ) - for (let i = 1; i < selectedPeriod.value.value + 1; i++) { - let dt - if (selectedPeriod.value.timeframe === "month") { - dt = DateTime.now() - .startOf("month") - .minus({ - months: selectedPeriod.value.timeframe === "month" ? selectedPeriod.value.value - i : 0, - }) - } else { - dt = DateTime.now().minus({ - days: selectedPeriod.value.timeframe === "day" ? selectedPeriod.value.value - i : 0, - hours: selectedPeriod.value.timeframe === "hour" ? selectedPeriod.value.value - i : 0, - }) - } - pfbSeries.value.push({ - date: dt.toJSDate(), - value: - parseInt(pfbSeriesMap[dt.toFormat(["day", "month"].includes(selectedPeriod.value.timeframe) ? "y-LL-dd" : "y-LL-dd-HH")]) || - 0, - }) - } + isLoading.value = false } -const buildNamespaceCharts = async (loadData = true) => { - isLoading.value = true - - if (loadData) { - await getSizeSeries() - await getPfbSeries() - } - +const handleChangeChartView = () => { if (chartView.value === "line") { - buildLineChart( - sizeSeriesChartEl.value.wrapper, - loadLastValue.value ? sizeSeries.value : sizeSeries.value.slice(0, sizeSeries.value.length - 1), - () => (showSeriesTooltip.value = true), - () => (showSeriesTooltip.value = false), - ) - buildLineChart( - pfbSeriesChartEl.value.wrapper, - loadLastValue.value ? pfbSeries.value : pfbSeries.value.slice(0, pfbSeries.value.length - 1), - () => (showPfbTooltip.value = true), - () => (showPfbTooltip.value = false), - ) + chartView.value = "bar" } else { - buildBarChart( - sizeSeriesChartEl.value.wrapper, - loadLastValue.value ? sizeSeries.value : sizeSeries.value.slice(0, sizeSeries.value.length - 1), - () => (showSeriesTooltip.value = true), - () => (showSeriesTooltip.value = false), - "size", - ) - buildBarChart( - pfbSeriesChartEl.value.wrapper, - loadLastValue.value ? pfbSeries.value : pfbSeries.value.slice(0, pfbSeries.value.length - 1), - () => (showPfbTooltip.value = true), - () => (showPfbTooltip.value = false), - "pfb", - ) + chartView.value = "line" } +} - isLoading.value = false +const fetchAllData = async () => { + await generateSeries(seriesConfig) } watch( () => selectedPeriodIdx.value, - () => { - buildNamespaceCharts() - }, + () => fetchAllData(), ) watch( () => [chartView.value, loadLastValue.value], () => { updateUserSettings() - if (!isLoading.value) { - buildNamespaceCharts(false) - } }, ) -const debouncedRedraw = useDebounceFn((e) => { - buildNamespaceCharts() -}, 500) - onBeforeMount(() => { isLoading.value = true const settings = JSON.parse(localStorage.getItem("settings")) @@ -604,13 +147,7 @@ onBeforeMount(() => { }) onMounted(async () => { - window.addEventListener("resize", debouncedRedraw) - - buildNamespaceCharts() -}) - -onBeforeUnmount(() => { - window.removeEventListener("resize", debouncedRedraw) + await fetchAllData() }) @@ -685,182 +222,23 @@ onBeforeUnmount(() => { - - DA Usage - - - - - {{ formatBytes(Math.max(...sizeSeries.map((d) => d.value)), 0) }} - - - - - {{ formatBytes(Math.round(Math.max(...sizeSeries.map((d) => d.value)) / 2), 0) }} - - - - 0 - - - - - - - {{ xAxisLabels.firstDate }} - - - - {{ xAxisLabels.lastDate }} - - - - - -
-
-
-
- - {{ badgeText }} - -
- - - Usage - {{ formatBytes(tooltipText) }} - - -
- - - - - - - - Pay For Blobs Count - - - - - {{ abbreviate(Math.max(...pfbSeries.map((d) => d.value)), 0) }} - - - - - {{ abbreviate(Math.round(Math.max(...pfbSeries.map((d) => d.value)) / 2), 0) }} - - - - 0 - - - - - - - {{ xAxisLabels.firstDate }} - - - - {{ xAxisLabels.lastDate }} - - - - - -
-
-
-
- - {{ badgeText }} - -
- - - Count - {{ abbreviate(tooltipText) }} - - -
- - - - - + + + diff --git a/components/modules/rollup/RollupCharts.vue b/components/modules/rollup/RollupCharts.vue index a131ea59..b8d90618 100644 --- a/components/modules/rollup/RollupCharts.vue +++ b/components/modules/rollup/RollupCharts.vue @@ -1,8 +1,6 @@