質問するログイン新規登録

回答編集履歴

2

無駄コード

2026/01/31 23:11

投稿

TN8001
TN8001

スコア10237

answer CHANGED
@@ -236,10 +236,12 @@
236
236
  //Drawing.DrawDebugRectangle(rp.Canvas, rp.Paint, panelRect, labelPoint, LabelFontColor);
237
237
 
238
238
  // 上にずらす座標計算(内側の軸から順に上に乗っていく仕様)
239
- var axes = Edge == Edge.Left
239
+ var offsetY = 0f;
240
- ? rp.Plot.Axes.GetAxes(Edge.Left).OfType<HorizontalLabelYAxis>().ToList()
240
+ foreach (var axes in rp.Plot.Axes.GetAxes(Edge).OfType<HorizontalLabelYAxis>())
241
- : rp.Plot.Axes.GetAxes(Edge.Right).OfType<HorizontalLabelYAxis>().ToList();
241
+ {
242
- var offsetY = axes.Take(axes.IndexOf(this) + 1).Sum(x => x.AxisLabelSize.Height);
242
+ offsetY += axes.AxisLabelSize.Height;
243
+ if (axes == this) break;
244
+ }
243
245
  LabelStyle.Render(rp.Canvas, labelPoint.MovedUp(offsetY), rp.Paint);
244
246
 
245
247
  DrawTicks(rp, TickLabelStyle, panelRect, TickGenerator.Ticks, this, MajorTickStyle, MinorTickStyle);

1

追記

2026/01/31 21:43

投稿

TN8001
TN8001

スコア10237

answer CHANGED
@@ -83,15 +83,9 @@
83
83
  if (!Range.HasBeenSet) return SizeWhenNoData;
84
84
 
85
85
  float maxTickLabelWidth = TickGenerator.Ticks.Length > 0
86
- ? TickGenerator.Ticks.Select(x => TickLabelStyle.Measure(x.Label, paint).Width).Max()
86
+ ? TickGenerator.Ticks.Select(x => TickLabelStyle.Measure(x.Label, paint).Width).Max() : 0;
87
- : 0;
88
87
 
89
88
  // 軸上にラベルを表示するのでPaddingBetweenTickAndAxisLabelsは不要
90
- //float axisLabelHeight = string.IsNullOrEmpty(LabelStyle.Text) && LabelStyle.Image is null
91
- // ? EmptyLabelPadding.Horizontal
92
- // : LabelStyle.Measure(LabelText, paint).Height
93
- // + PaddingBetweenTickAndAxisLabels.Horizontal
94
- // + PaddingOutsideAxisLabels.Horizontal;
95
89
  float axisLabelHeight = string.IsNullOrEmpty(LabelStyle.Text) && LabelStyle.Image is null
96
90
  ? EmptyLabelPadding.Horizontal
97
91
  : LabelStyle.Measure(LabelText, paint).Height
@@ -99,7 +93,6 @@
99
93
  + PaddingOutsideAxisLabels.Horizontal;
100
94
 
101
95
  // ラベルが軸の反対側に半分出るので1/2
102
- //return maxTickLabelWidth + axisLabelHeight;
103
96
  return maxTickLabelWidth / 2 + axisLabelHeight;
104
97
  }
105
98
 
@@ -116,9 +109,7 @@
116
109
  LabelAlignment = Alignment.UpperCenter;
117
110
  LabelStyle.Render(rp.Canvas, labelPoint, rp.Paint);
118
111
 
119
- //DrawTicks(rp, TickLabelStyle, panelRect, TickGenerator.Ticks, this, MajorTickStyle, MinorTickStyle);
120
112
  DrawTicks2(rp, TickLabelStyle, panelRect, TickGenerator.Ticks, this, MajorTickStyle, MinorTickStyle);
121
-
122
113
  DrawFrame(rp, panelRect, Edge, FrameLineStyle);
123
114
  }
124
115
 
@@ -134,10 +125,8 @@
134
125
  float tickLength = tick.IsMajor ? majorStyle.Length : minorStyle.Length;
135
126
  float yPx = axis.GetPixel(tick.Position, panelRect);
136
127
  float x = axis.Edge == Edge.Left ? panelRect.Right : panelRect.Left;
137
- //float xEdge = axis.Edge == Edge.Left ? x - tickLength : x + tickLength;
138
128
 
139
129
  // 左右にtickLength分の線を引く
140
- //PixelLine pxLine = new(x, yPx, xEdge, yPx);
141
130
  PixelLine pxLine = new(x - tickLength, yPx, x + tickLength, yPx);
142
131
 
143
132
  var lineStyle = tick.IsMajor ? majorStyle : minorStyle;
@@ -145,23 +134,117 @@
145
134
 
146
135
  if (string.IsNullOrWhiteSpace(tick.Label) || !label.IsVisible) continue;
147
136
  label.Text = tick.Label;
148
- //float pxDistanceFromTick = 5;
149
- //float pxDistanceFromEdge = tickLength + pxDistanceFromTick;
150
137
 
151
- // 軸に重ねるので余計なオフセット計算なし
138
+ float xPx = x; // 軸に重ねるので余計なオフセット計算なし
152
- //float xPx = axis.Edge == Edge.Left ? x - pxDistanceFromEdge : x + pxDistanceFromEdge;
153
- float xPx = x;
154
139
 
155
140
  Pixel px = new(xPx, yPx);
156
141
  if (label.Rotation == 0)
157
- {
158
- // 何も気にせずMiddleCenterに描く
159
- //label.Alignment = axis.Edge == Edge.Left ? Alignment.MiddleRight : Alignment.MiddleLeft;
160
- label.Alignment = Alignment.MiddleCenter;
142
+ label.Alignment = Alignment.MiddleCenter; // 何も気にせずMiddleCenterに描く
161
- }
162
143
  label.Render(rp.Canvas, px, paint);
163
144
  }
164
145
  }
165
146
  }
166
147
  ```
167
- ![アプリ画像](https://ddjkaamml8q8x.cloudfront.net/questions/2026-01-30/1273532d-0f5f-4426-a91d-441a0dc71f5b.png)
148
+ ![アプリ画像](https://ddjkaamml8q8x.cloudfront.net/questions/2026-01-30/1273532d-0f5f-4426-a91d-441a0dc71f5b.png)
149
+
150
+ ---
151
+
152
+ ## 追記
153
+ > Y軸の真上というのは、たとえば、示してくれたグラフでいうと"LeftAxis"の文字が、左のY軸の0.01の数字とForm1という文字の間に横書きで表示されて欲しいという意味でした。
154
+
155
+ ```cs
156
+ using ScottPlot;
157
+ using ScottPlot.AxisPanels;
158
+ using ScottPlot.WinForms;
159
+
160
+ namespace Qa3g98l2vj841kv;
161
+
162
+ public partial class Form1 : Form
163
+ {
164
+ public Form1()
165
+ {
166
+ InitializeComponent();
167
+
168
+ var formsPlot1 = new FormsPlot { Dock = DockStyle.Fill, Parent = this, };
169
+ formsPlot1.Plot.Title("Plot Title");
170
+
171
+ formsPlot1.Plot.Axes.Remove(formsPlot1.Plot.Axes.Left);
172
+ formsPlot1.Plot.Axes.AddLeftAxis(new HorizontalLabelYAxis(Edge.Left));
173
+
174
+ var sig1 = formsPlot1.Plot.Add.Signal(Generate.Sin(mult: 0.01));
175
+ sig1.Axes.YAxis = formsPlot1.Plot.Axes.Left;
176
+ formsPlot1.Plot.Axes.Left.Label.Text = "Left Axis";
177
+ formsPlot1.Plot.Axes.Left.Label.ForeColor = sig1.Color;
178
+
179
+
180
+ formsPlot1.Plot.Axes.Remove(formsPlot1.Plot.Axes.Right);
181
+ formsPlot1.Plot.Axes.AddRightAxis(new HorizontalLabelYAxis(Edge.Right));
182
+
183
+ var sig2 = formsPlot1.Plot.Add.Signal(Generate.Cos(mult: 100));
184
+ sig2.Axes.YAxis = formsPlot1.Plot.Axes.Right;
185
+ formsPlot1.Plot.Axes.Right.Label.Text = "Right Axisssssssssssssss";
186
+ formsPlot1.Plot.Axes.Right.Label.ForeColor = sig2.Color;
187
+
188
+
189
+ var sig3 = formsPlot1.Plot.Add.Signal(Generate.RandomSample(50));
190
+ var left2 = new HorizontalLabelYAxis(Edge.Left) { LabelText = "Secondary Left Axis", LabelFontColor = sig3.Color, };
191
+ sig3.Axes.YAxis = left2;
192
+ formsPlot1.Plot.Axes.AddLeftAxis(left2);
193
+ }
194
+ }
195
+
196
+ internal class HorizontalLabelYAxis : YAxisBase
197
+ {
198
+ public override Edge Edge { get; }
199
+ public PixelSize AxisLabelSize { get; private set; }
200
+
201
+ public HorizontalLabelYAxis(Edge edge)
202
+ {
203
+ if (edge != Edge.Left && edge != Edge.Right) throw new InvalidOperationException();
204
+
205
+ Edge = edge;
206
+ TickGenerator = new ScottPlot.TickGenerators.NumericAutomatic();
207
+ LabelAlignment = Alignment.UpperCenter; // 軸に対して上部中央
208
+ LabelRotation = 0; // 回転なし
209
+ }
210
+
211
+ public override float Measure(Paint paint)
212
+ {
213
+ if (!IsVisible) return 0;
214
+ if (!Range.HasBeenSet) return SizeWhenNoData;
215
+
216
+ float maxTickLabelWidth = TickGenerator.Ticks.Length > 0
217
+ ? TickGenerator.Ticks.Select(x => TickLabelStyle.Measure(x.Label, paint).Width).Max() : 0;
218
+
219
+ // 軸ラベルサイズ
220
+ AxisLabelSize = string.IsNullOrEmpty(LabelStyle.Text) && LabelStyle.Image is null
221
+ ? PixelSize.Zero : LabelStyle.Measure(LabelText, paint).Size;
222
+
223
+ // 目盛りラベル幅と軸ラベル幅半分の大きい方を採用+適当にパディング
224
+ return MathF.Max(maxTickLabelWidth, AxisLabelSize.Width / 2)
225
+ + PaddingBetweenTickAndAxisLabels.Horizontal
226
+ + PaddingOutsideAxisLabels.Horizontal;
227
+ }
228
+
229
+ public override void Render(RenderPack rp, float size, float offset)
230
+ {
231
+ if (!IsVisible) return;
232
+
233
+ PixelRect panelRect = GetPanelRect(rp.DataRect, size, offset, rp.Paint);
234
+ float x = Edge == Edge.Left ? panelRect.Right : panelRect.Left;
235
+ Pixel labelPoint = new(x, rp.DataRect.Top);
236
+ //Drawing.DrawDebugRectangle(rp.Canvas, rp.Paint, panelRect, labelPoint, LabelFontColor);
237
+
238
+ // 上にずらす座標計算(内側の軸から順に上に乗っていく仕様)
239
+ var axes = Edge == Edge.Left
240
+ ? rp.Plot.Axes.GetAxes(Edge.Left).OfType<HorizontalLabelYAxis>().ToList()
241
+ : rp.Plot.Axes.GetAxes(Edge.Right).OfType<HorizontalLabelYAxis>().ToList();
242
+ var offsetY = axes.Take(axes.IndexOf(this) + 1).Sum(x => x.AxisLabelSize.Height);
243
+ LabelStyle.Render(rp.Canvas, labelPoint.MovedUp(offsetY), rp.Paint);
244
+
245
+ DrawTicks(rp, TickLabelStyle, panelRect, TickGenerator.Ticks, this, MajorTickStyle, MinorTickStyle);
246
+ DrawFrame(rp, panelRect, Edge, FrameLineStyle);
247
+ }
248
+ }
249
+ ```
250
+ ![アプリ画像](https://ddjkaamml8q8x.cloudfront.net/questions/2026-02-01/9734a22c-d69c-442b-8a8c-6b9c2ff96e15.png)