Coverage for graphica/gui/dataset_bindings.py: 97.8%
42 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-12 16:38 +0000
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-12 16:38 +0000
1"""データセットのプロパティ(Dataset の属性)とプロパティ欄の対応表。欄を 1 つ足すときは表に 1 行足す。
3表の順は選んだデータセットを欄に戻す順。欄から値を読む行(read がある行)は、変わったらその属性だけを
4選択中のデータセットすべてに当てる(DatasetPropertyPanel.on_property_changed)。read が無い行は戻すだけで、
5変更は専用の処理が受ける(凡例名・色・第 2 Y 軸・描画先・2D・値域)。
6"""
7from graphica.core.dataset import linestyle_name
8from graphica.gui.binding import WATCH, Binding, check, found_text, item_data, number, shown_text
10# 誤差列の欄で「誤差列を使わない」を表す選択肢
11NO_ERROR_COLUMN_LABEL = "(なし)"
12# データ点ラベルの内容の欄で「Y値そのもの」を表す選択肢
13POINT_LABEL_Y_VALUE_LABEL = "Y値"
15# マーカーの形の選択肢(保存値 = matplotlib の記号, 表示名)。'None' はマーカーを描かない
16NO_MARKER = 'None'
17MARKER_CHOICES = (
18 ('o', "円"), ('s', "四角"), ('^', "三角(上)"), ('v', "三角(下)"), ('D', "ひし形"),
19 ('<', "三角(左)"), ('>', "三角(右)"), ('p', "五角形"), ('h', "六角形"), ('*', "星"),
20 ('+', "十字"), ('x', "バツ"), ('.', "点"), (NO_MARKER, "なし"),
21)
23_PANEL = 'property_panel.'
26def _linestyle(key, widget):
27 """保存値は '--' と 'dashed' のような表記ゆれを含むので表示名に揃えて選ぶ。線を描かない値は選択なしにする
28 (直前のデータセットの表示が残って誤解されないように)。"""
29 def write(_owner, combo, value):
30 shown = linestyle_name(value)
31 if shown is None:
32 combo.setCurrentIndex(-1)
33 else:
34 combo.setCurrentText(shown)
35 return Binding(key, widget, lambda _o, w: w.currentText(), write, 'currentTextChanged', (WATCH,))
38def _marker(key, widget, slots):
39 """選択肢のデータが保存値。表に無い記号(手で書いたファイル・プラグイン)は、消さずに選択肢を足して出す。"""
40 def read(_owner, combo):
41 value = combo.currentData()
42 return None if value == NO_MARKER else value
44 def write(_owner, combo, value):
45 value = NO_MARKER if value is None else value
46 found = combo.findData(value)
47 if found == -1:
48 combo.addItem(str(value), value)
49 found = combo.count() - 1
50 combo.setCurrentIndex(found)
51 return Binding(key, widget, read, write, 'currentIndexChanged', slots)
54def _color(key, widget, slot):
55 return Binding(key, widget, None, lambda _o, w, v: w.set_color(v), 'colorChanged', (slot,))
58def _picked_color(key, widget):
59 return Binding(key, widget, lambda _o, w: w.color_name(), lambda _o, w, v: w.set_color(v), 'colorChanged', (WATCH,))
62def _point_label_column(key, widget):
63 """選択肢はデータセットの列なので、戻すたびに作り直す。"""
64 def write(_owner, combo, value):
65 name, columns = value
66 combo.clear()
67 combo.addItems([POINT_LABEL_Y_VALUE_LABEL] + columns)
68 combo.setCurrentText(name or POINT_LABEL_Y_VALUE_LABEL)
70 def read(_owner, combo):
71 return None if combo.currentText() == POINT_LABEL_Y_VALUE_LABEL else combo.currentText()
72 return Binding(key, widget, read, write, 'currentTextChanged', (WATCH,),
73 load=lambda ds: (ds.point_label_col_name, ds.df.columns.tolist()))
76def _value_range(key, widget, empty_value):
77 """値域が自動(None)のときは欄に仮の値を入れておく。"""
78 return Binding(key, widget, None, lambda _o, w, v: w.setValue(v if v is not None else empty_value),
79 'valueChanged', (_PANEL + 'on_2d_value_range_changed',))
82DATASET_PROPERTY_BINDINGS = (
83 # textChanged だと1文字ごとに描き直して重いので editingFinished
84 Binding('name', 'ui.legend_name_edit', None, lambda _o, w, v: w.setText(v), 'editingFinished',
85 (_PANEL + 'on_legend_name_changed',)),
86 # 種類によって意味のある欄が変わるので、種類が変わるたびに出し入れし直す
87 shown_text('plot_type', 'ui.plot_type_combo',
88 (WATCH, _PANEL + 'update_gradient_controls_visibility', _PANEL + 'update_smoothing_control_visibility',
89 _PANEL + 'update_error_display_control_items', _PANEL + 'update_marker_controls_visibility')),
90 _linestyle('linestyle', 'ui.linestyle_combo'),
91 number('linewidth', 'ui.linewidth_spinbox', (WATCH,)),
92 _marker('marker', 'ui.marker_combo', (WATCH, _PANEL + 'update_marker_controls_visibility')),
93 number('markersize', 'ui.markersize_spinbox', (WATCH,)),
94 item_data('marker_fill', 'marker_fill_combo', (WATCH, _PANEL + 'update_marker_controls_visibility')),
95 _picked_color('marker_face_color', 'marker_face_color_picker'),
96 item_data('marker_edge', 'marker_edge_combo', (WATCH, _PANEL + 'update_marker_controls_visibility')),
97 _picked_color('marker_edge_color', 'marker_edge_color_picker'),
98 number('marker_edge_width', 'marker_edge_width_spinbox', (WATCH,)),
99 _color('color', 'color_picker_widget', 'colors.on_color_changed'),
100 # 平滑化のチェックで手法の欄の有効/無効も切り替える
101 check('smoothing', 'ui.smoothing_checkbox', (WATCH, _PANEL + 'update_smoothing_control_visibility')),
102 item_data('smoothing_method', 'smoothing_method_combo', (WATCH,)),
103 number('alpha', 'alpha_spinbox', (WATCH,)),
104 check('gradient_enabled', 'gradient_checkbox', (WATCH, _PANEL + 'update_gradient_controls_visibility'),
105 signal='toggled'),
106 _color('gradient_color2', 'gradient_color2_picker', 'colors.on_gradient_color2_changed'),
107 item_data('gradient_target', 'gradient_target_combo', (WATCH,)),
108 check('waterfall_enabled', 'waterfall_checkbox', (WATCH, _PANEL + 'update_waterfall_controls_visibility'),
109 signal='toggled'),
110 item_data('waterfall_offset_mode', 'waterfall_offset_mode_combo', (WATCH,)),
111 number('waterfall_offset_x', 'waterfall_offset_x_spinbox', (WATCH,)),
112 number('waterfall_offset_y', 'waterfall_offset_y_spinbox', (WATCH,)),
113 check('waterfall_occlusion_enabled', 'waterfall_occlusion_checkbox', (WATCH,), signal='toggled'),
114 check('waterfall_depth_shrink_enabled', 'waterfall_depth_checkbox',
115 (WATCH, _PANEL + 'update_waterfall_controls_visibility'), signal='toggled'),
116 number('waterfall_depth_shrink_ratio', 'waterfall_depth_ratio_spinbox', (WATCH,)),
117 # 点ラベルは上限の説明の更新もするので専用のハンドラ(中で on_property_changed を呼ぶ)
118 check('show_point_labels', 'point_labels_checkbox', (_PANEL + 'on_point_labels_toggled',), signal='toggled'),
119 _point_label_column('point_label_col_name', 'point_label_col_combo'),
120 Binding('use_secondary_y', 'use_secondary_y_checkbox', None, lambda _o, w, v: w.setChecked(v), 'stateChanged',
121 (_PANEL + 'on_secondary_y_changed',)),
122 Binding('subplot_target', 'subplot_target_combo', None, lambda _o, w, v: w.setCurrentIndex(v),
123 'currentIndexChanged', (_PANEL + 'on_subplot_target_changed',)),
124 item_data('error_display', 'error_display_combo', (WATCH,)),
125 # textChanged だと1文字ごとに描き直して重いので editingFinished
126 Binding('legend_label', 'legend_label_edit', lambda _o, w: w.text().strip(), lambda _o, w, v: w.setText(v or ''),
127 'editingFinished', (WATCH,)),
128 check('hide_from_legend', 'hide_from_legend_checkbox', (WATCH,), signal='toggled'),
129 item_data('nan_policy', 'nan_policy_combo', (WATCH,)),
130 Binding('data_kind', 'data_2d_checkbox', None, lambda _o, w, v: w.setChecked(v == '2d_grid'), 'toggled',
131 (_PANEL + 'on_data_2d_toggled',)),
132 found_text('colormap', 'colormap_combo', (WATCH,)),
133 item_data('map_display_mode', 'map_display_mode_combo', (WATCH,)),
134 number('contour_levels', 'contour_levels_spinbox', (WATCH,)),
135 found_text('grid_interp_method', 'grid_interp_method_combo', (WATCH,)),
136 Binding('color_range_auto', 'color_range_auto_checkbox', None, lambda _o, w, v: w.setChecked(v), 'toggled',
137 (_PANEL + 'on_2d_value_range_changed',), load=lambda ds: ds.vmin is None and ds.vmax is None),
138 _value_range('vmin', 'vmin_spinbox', 0.0),
139 _value_range('vmax', 'vmax_spinbox', 1.0),
140)