cqlib_core/visualization/result/options.rs
1// This code is part of Cqlib.
2//
3// (C) Copyright China Telecom Quantum Group 2026
4//
5// This code is licensed under the Apache License, Version 2.0. You may
6// obtain a copy of this license in the LICENSE.txt file in the root directory
7// of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
8//
9// Any modifications or derivative works of this code must retain this
10// copyright notice, and modified files need to carry a notice indicating
11// that they have been altered from the originals.
12
13//! Public types and options for result/statistics plots.
14//!
15//! # Sort Policies
16//!
17//! | Value | Description |
18//! |-------|-------------|
19//! | `asc` | Sort bitstring labels lexicographically ascending |
20//! | `desc` | Sort bitstring labels lexicographically descending |
21//! | `value` | Sort by peak value across datasets, ascending |
22//! | `value_desc` | Sort by peak value across datasets, descending |
23//! | `hamming` | Sort by Hamming distance to [`ResultPlotOptions::target_string`] |
24
25use std::collections::BTreeMap;
26
27pub(crate) const DEFAULT_COLORS: [&str; 8] = [
28 "#4569d4", "#d64b5f", "#2f9d73", "#f0a33a", "#8a5bd7", "#2aa7b8", "#bd6b33", "#56616f",
29];
30
31/// Internal result plot family.
32#[derive(Debug, Clone, Copy, PartialEq, Eq)]
33pub(crate) enum ResultPlotKind {
34 /// Plot raw counts.
35 Histogram,
36 /// Normalize counts into probabilities before plotting.
37 Distribution,
38}
39
40/// Options for histogram and probability-distribution plots.
41///
42/// Use [`ResultPlotOptions::default`] for library defaults, then override only the fields
43/// needed for a specific chart.
44///
45/// # Examples
46///
47/// ```rust
48/// use cqlib_core::visualization::ResultPlotOptions;
49///
50/// let options = ResultPlotOptions {
51/// sort: "value_desc".to_string(),
52/// number_to_keep: Some(8),
53/// title: Some("Measurement counts".to_string()),
54/// ..ResultPlotOptions::default()
55/// };
56/// assert_eq!(options.sort, "value_desc");
57/// ```
58#[derive(Debug, Clone)]
59pub struct ResultPlotOptions {
60 /// Optional figure size in inches-like units, scaled to SVG pixels.
61 pub figsize: Option<(f64, f64)>,
62 /// Per-dataset colors. Defaults to Cqlib's built-in qualitative palette.
63 pub color: Vec<String>,
64 /// Keep the largest `k` bars and aggregate the rest into a `rest` bar.
65 pub number_to_keep: Option<usize>,
66 /// Sort policy: `asc`, `desc`, `value`, `value_desc`, or `hamming`.
67 pub sort: String,
68 /// Target bitstring used by `sort = "hamming"`.
69 pub target_string: Option<String>,
70 /// Optional legend entries, one per dataset.
71 pub legend: Option<Vec<String>>,
72 /// Whether to draw numeric labels above bars.
73 pub bar_labels: bool,
74 /// Optional chart title.
75 pub title: Option<String>,
76}
77
78impl ResultPlotOptions {
79 /// Resolve user colors or fall back to Cqlib's built-in qualitative palette.
80 pub(super) fn resolved_colors(&self) -> Vec<String> {
81 if self.color.is_empty() {
82 DEFAULT_COLORS
83 .iter()
84 .map(|color| color.to_string())
85 .collect()
86 } else {
87 self.color.clone()
88 }
89 }
90}
91
92impl Default for ResultPlotOptions {
93 fn default() -> Self {
94 Self {
95 figsize: None,
96 color: Vec::new(),
97 number_to_keep: None,
98 sort: "asc".to_string(),
99 target_string: None,
100 legend: None,
101 bar_labels: true,
102 title: None,
103 }
104 }
105}
106
107/// Internal result series keyed by formatted bitstring labels.
108///
109/// Public plotting APIs accept [`crate::device::ExecutionResult`] directly; this alias is kept
110/// inside the result-plot data pipeline for normalization, sorting, and rendering preparation.
111pub(crate) type PlotSeries = BTreeMap<String, f64>;