MS Chart Rectangular Annotation width in percent and not pixel(MS Chart Rectangular Annotation 宽度百分比而不是像素)
问题描述
为什么 MS 图表矩形注释宽度是百分比而不是像 msdn 所说的像素?
如您所见,大小保持不变.
还要注意我在 Paint
事件中绘制的彩色矩形以演示新功能!
这里是 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, 新尺寸(24, 36));}
这里是尺寸函数:
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;}
why is it that the MS chart rectangular annotation width is in percent and not pixel like msdn says it is? https://msdn.microsoft.com/en-us/library/system.windows.forms.datavisualization.charting.annotation.width(v=vs.110).aspx
This is what msdn says Gets or sets the width, in pixels, of an annotation.
I'd like to set my width to be pixels like it states. Am I missing something here?
Congratulations, you have found a bug in the documentation! Easy to spot simply by following the link to the Annotation.Height docs..
The dimensions of an Annotation
, as many others in a Chart
control, are indeed given in percentages. This has the advantage that they quite cleverly grow and shrink with the Chart
control just like many other elements.
So if you double the width of the chart you basically double the space for the shown DataPoints
and if your Annotation
went over a 1/3 of the width before it will still do that after you have resized the chart..
Which is nice.
But not what you wanted..
So to set the size to a fixed size in pixels you need to do this:
- Calculate the size you want in percentages and set it
- Repeat whenever you resize the chart or its layout
The real problem is the calculation: If you look at the Chart.ClientSize
you get the size in pixels and to get n pixels you need to do something like this:
float WidthInPercent = 100f * n / Chart.ClientSize.width;
This however does not take into account the various elements your Chart
probably has : The Size
of an Annotation
is not really calculated as direct percentages of the Chart's size.
Instead it is calulated as percentages of the InnerPlotPosition
of the ChartArea CA
.
InnerPlotPosition
by default is set to Auto
so accessing its values, e.g. CA.InnerPlotPosition.Width
will return 0f
; but you can get at the (current!!) values by doing this:
RectangleF IPP = CA.InnerPlotPosition.ToRectangleF();
The same goes for the Size/Position
of the ChartArea
itself:
RectangleF CAP = CA.Position.ToRectangleF();
Now you can combine these percentages with the (current!) Chart.ClientSize
to find out which percentage you need to achieve a certain pixel size..
Note that these values will change when resizing because the outer extras, like Legend
and Axis
and Labels
etc. will not resize, so their relative sizes will grow or shink in relation to their containing elements..
So you need to recalculate upon each Resize
event, or, better: write a function to do it for you which you can call wheneber needed..
The result is an Annotation
that will (pretty much, due to rounding) maintain its size, no matter how you resize the Chart
..
Here are some helpful functions:
This one returns the current ClientRectangle
of a ChartArea
in pixels
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);
}
This one is similar and returns the current ClientRectangle
of a ChartArea's InnerplotPosition
in pixels:
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);
}
Finally one that converts a size in pixels to one in percentages, again valid only currently, i.e. until the next changes in size or layout..:
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);
}
Lets have a look at the result before and after some resizing:
As you can see the size stay the same.
Also note the colored rectangles I draw in the Paint
event to demostrate the new functions!
Here is the Paint
event:
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)));
}
Here is the Resize
event:
private void chart1_Resize(object sender, EventArgs e)
{
sizeAnn(ra, new Size(24, 36));
}
And here the sizing 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;
}
这篇关于MS Chart Rectangular Annotation 宽度百分比而不是像素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:MS Chart Rectangular Annotation 宽度百分比而不是像素
基础教程推荐
- 如何在 IDE 中获取 Xamarin Studio C# 输出? 2022-01-01
- 为什么Flurl.Http DownloadFileAsync/Http客户端GetAsync需要 2022-09-30
- SSE 浮点算术是否可重现? 2022-01-01
- c# Math.Sqrt 实现 2022-01-01
- 如何激活MC67中的红灯 2022-01-01
- MS Visual Studio .NET 的替代品 2022-01-01
- rabbitmq 的 REST API 2022-01-01
- 将 XML 转换为通用列表 2022-01-01
- 将 Office 安装到 Windows 容器 (servercore:ltsc2019) 失败,错误代码为 17002 2022-01-01
- 有没有办法忽略 2GB 文件上传的 maxRequestLength 限制? 2022-01-01