MS图表矩形注释宽度,以百分比表示,而不是像素
为什么MS图表的矩形注释宽度是百分比而不是像msdn这样的像素呢? https://msdn.microsoft.com/en-us/library/system.windows.forms.datavisualization.charting.annotation.width(v=vs.110).aspx
这就是msdn所说的获取或设置注释的宽度(以像素为单位)。
我想将宽度设置为像它所说的像素。 我在这里错过了什么吗?
恭喜,您在文档中发现了一个错误! 只需按照Annotation.Height文档的链接即可轻松识别..
与Chart
控件中的许多其他维度一样, Annotation
的维度确实以百分比forms给出 。 这有一个优点,就像许多其他元素一样,它们使用Chart
控件非常巧妙地增长和缩小。
因此,如果您将图表的宽度加倍,则基本上会使显示的DataPoints
的空间加倍,如果您的Annotation
超过了宽度的1/3,那么在调整图表大小之后它仍然会这样做。
这很好。
但不是你想要的……
因此,要将大小设置为固定大小(以像素为单位),您需要执行以下操作:
- 以百分比计算所需的大小并进行设置
- 每当您调整图表或其布局的大小时重复
真正的问题是计算:如果您查看Chart.ClientSize
您将获得以像素为单位的大小,并获得n个像素,您需要执行以下操作:
float WidthInPercent = 100f * n / Chart.ClientSize.width;
但是,这并未考虑Chart
可能具有的各种元素: Annotation
的Size
并未真正计算为图表大小的直接百分比 。
相反,它被计算为ChartArea CA
的InnerPlotPosition
的百分比。
默认情况下, InnerPlotPosition
设置为Auto
因此访问其值,例如CA.InnerPlotPosition.Width
将返回0f
; 但你可以通过这样做得到(当前!!)值:
RectangleF IPP = CA.InnerPlotPosition.ToRectangleF();
ChartArea
本身的Size/Position
也是如此:
RectangleF CAP = CA.Position.ToRectangleF();
现在,您可以将这些百分比与( 当前! ) Chart.ClientSize
结合起来,找出实现特定像素大小所需的百分比。
请注意, resize时这些值会发生变化,因为外部附加内容(如Legend
和Axis
和Labels
等)不会resize,因此它们的相对大小将相对于其包含元素增大或闪烁。
因此, 您需要在每次Resize
事件时重新计算 ,或者更好:编写一个函数来为您执行此操作,您可以调用所需的函数。
无论你如何调整Chart
大小,结果都是一个Annotation
(几乎是由于四舍五入)保持它的大小。
以下是一些有用的function:
这个返回ChartArea
的当前 ClientRectangle
(以像素为单位)
RectangleF ChartAreaClientRectangle(Chart chart, ChartArea CA) { RectangleF CAR = CA.Position.ToRectangleF(); float pw = chart.ClientSize.Width / 100f; float ph = chart.ClientSize.Height / 100f; return new RectangleF(pw * CAR.X, ph * CAR.Y, pw * CAR.Width, ph * CAR.Height); }
这个是类似的,并以像素为单位返回ChartArea's InnerplotPosition
的当前ClientRectangle
:
RectangleF InnerPlotPositionClientRectangle(Chart chart, ChartArea CA) { RectangleF IPP = CA.InnerPlotPosition.ToRectangleF(); RectangleF CArp = ChartAreaClientRectangle(chart, CA); float pw = CArp.Width / 100f; float ph = CArp.Height / 100f; return new RectangleF(CArp.X + pw * IPP.X, CArp.Y + ph * IPP.Y, pw * IPP.Width, ph * IPP.Height); }
最后一个将像素大小转换为百分比的一个,再次仅在当前有效,即直到下一个大小或布局发生变化..:
SizeF Pixels2Percent( ChartArea CA, int w, int h) { RectangleF IPPR = InnerPlotPositionClientRectangle(chart1, CA); float pw = 100f * w / IPPR.Width ; float ph = 100f * h / IPPR.Height ; return new SizeF(pw, ph); }
让我们看一下resize之前和之后的结果:
如你所见,尺寸保持不变。
还要注意我在Paint
事件中绘制的彩色矩形以说明新function!
这是Paint
事件:
private void chart1_Paint(object sender, PaintEventArgs e) { ChartArea CA = chart1.ChartAreas[0]; e.Graphics.DrawRectangle(Pens.Violet, Rectangle.Round(ChartAreaClientRectangle(chart1, CA))); e.Graphics.DrawRectangle(Pens.LimeGreen, Rectangle.Round(InnerPlotPositionClientRectangle(chart1, CA))); }
这是Resize
事件:
private void chart1_Resize(object sender, EventArgs e) { sizeAnn(ra, new Size(24, 36)); }
这里的尺寸调整function:
void sizeAnn(RectangleAnnotation ra, Size sz) { ChartArea CA = chart1.ChartAreas[0]; SizeF pixelPercent = Pixels2Percent(CA, sz.Width, sz.Height); ra.Width = pixelPercent.Width; ra.Height = pixelPercent.Height; }
是的,我们无法将其设置为%或px,因为属性值设置为double。 其次,pixle = H乘以W.但你只是设置图表的宽度然后你怎么能用pixle设置它? 从根本上说,这是不可能的。 我希望你能明白我的意思。