+
+
+
+
+
+ No minimum daily fee rate data available yet.
+
+
+
+
+
+
+
diff --git a/frontend/src/app/components/min-fee-rate-cdf-graph/min-fee-rate-cdf-graph.component.scss b/frontend/src/app/components/min-fee-rate-cdf-graph/min-fee-rate-cdf-graph.component.scss
new file mode 100644
index 000000000..ad23fe65b
--- /dev/null
+++ b/frontend/src/app/components/min-fee-rate-cdf-graph/min-fee-rate-cdf-graph.component.scss
@@ -0,0 +1,108 @@
+.full-container {
+ display: flex;
+ flex-direction: column;
+ padding: 0px 15px;
+ width: 100%;
+ height: calc(100vh - 225px);
+ min-height: 400px;
+ @media (min-width: 992px) {
+ height: calc(100vh - 150px);
+ }
+}
+
+.chart-header {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 12px;
+ @media (min-width: 768px) {
+ flex-direction: row;
+ align-items: flex-start;
+ justify-content: space-between;
+ gap: 20px;
+ }
+
+ .heading {
+ min-width: 0;
+
+ .title {
+ font-size: 18px;
+ line-height: 1.2;
+ @media (min-width: 465px) {
+ font-size: 20px;
+ }
+ .btn {
+ vertical-align: baseline;
+ }
+ }
+
+ .subtitle {
+ margin-top: 4px;
+ font-size: 12px;
+ color: var(--transparent-fg);
+ }
+ }
+
+}
+
+.chart-controls {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 10px;
+ margin: 12px 0 4px;
+ @media (min-width: 768px) {
+ flex-direction: row;
+ flex-wrap: wrap;
+ align-items: center;
+ justify-content: space-between;
+ }
+
+ .threshold-input {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ flex: 0 0 auto;
+ label {
+ margin: 0;
+ font-size: 11px;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+ color: var(--transparent-fg);
+ white-space: nowrap;
+ }
+ input {
+ width: 90px;
+ }
+ }
+
+ .formRadioGroup {
+ .btn-sm {
+ font-size: 9px;
+ @media (min-width: 830px) {
+ font-size: 14px;
+ }
+ }
+ }
+}
+
+.chart {
+ display: flex;
+ flex: 1;
+ height: 100%;
+ padding-bottom: 20px;
+ padding-right: 10px;
+ @media (max-width: 992px) {
+ padding-bottom: 25px;
+ }
+}
+
+.chart-widget {
+ width: 100%;
+ height: 100%;
+ max-height: 238px;
+}
+
+.no-data {
+ padding: 30px 0;
+}
diff --git a/frontend/src/app/components/min-fee-rate-cdf-graph/min-fee-rate-cdf-graph.component.ts b/frontend/src/app/components/min-fee-rate-cdf-graph/min-fee-rate-cdf-graph.component.ts
new file mode 100644
index 000000000..c245eb9a7
--- /dev/null
+++ b/frontend/src/app/components/min-fee-rate-cdf-graph/min-fee-rate-cdf-graph.component.ts
@@ -0,0 +1,320 @@
+import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, Input, LOCALE_ID, OnInit } from '@angular/core';
+import { EChartsOption } from '@app/graphs/echarts';
+import { Observable, combineLatest, of } from 'rxjs';
+import { map, share, startWith, switchMap, tap } from 'rxjs/operators';
+import { SeoService } from '@app/services/seo.service';
+import { formatNumber } from '@angular/common';
+import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
+import { download } from '@app/shared/graphs.utils';
+import { StorageService } from '@app/services/storage.service';
+import { MiningService } from '@app/services/mining.service';
+import { StateService } from '@app/services/state.service';
+import { ActivatedRoute } from '@angular/router';
+import { MinFeeRateDay } from '@app/interfaces/node-api.interface';
+import { DEFAULT_MIN_FEE_RATE_THRESHOLD, MinFeeRateService } from '@app/services/min-fee-rate.service';
+import { chartColors } from '@app/app.constants';
+
+const CURVE_COLOR = chartColors[8]; // '#00897B'
+
+// The series is one point per day, so anything shorter than a month is degenerate.
+const TIMESPANS = ['1m', '3m', '6m', '1y', '2y', '3y', 'all'];
+
+@Component({
+ selector: 'app-min-fee-rate-cdf-graph',
+ templateUrl: './min-fee-rate-cdf-graph.component.html',
+ styleUrls: ['./min-fee-rate-cdf-graph.component.scss'],
+ styles: [`
+ .loadingGraphs {
+ position: absolute;
+ top: 50%;
+ left: calc(50% - 15px);
+ z-index: 99;
+ }
+ `],
+ standalone: false,
+ changeDetection: ChangeDetectionStrategy.OnPush,
+})
+export class MinFeeRateCdfGraphComponent implements OnInit {
+ @Input() widget = false;
+
+ miningWindowPreference: string;
+ radioGroupForm: UntypedFormGroup;
+
+ chartOptions: EChartsOption = {};
+ chartInitOptions = {
+ renderer: 'svg',
+ };
+
+ statsObservable$: Observable