MS Chart 矩形注释宽度百分比而不是像素
MS Chart Rectangular Annotation width in percent and not pixel
为什么 MS 图表矩形注释宽度是百分比而不是 msdn 所说的像素? https://msdn.microsoft.com/en-us/library/system.windows.forms.datavisualization.charting.annotation.width(v=vs.110).aspx
msdn 是这么说的
获取或设置注释的宽度(以像素为单位)。
我想将我的宽度设置为它声明的像素。我在这里错过了什么吗?
是的,我们不能将其设置为 % 或 px,因为 属性 值设置为双倍。
其次,pixle = H乘以W。但你只是设置图表的宽度,那你怎么能设置成pixle呢?根本不可能。我希望你能明白我的意思。
恭喜,您在文档中发现了一个错误!只需按照 link 到 Annotation.Height 文档即可轻松发现..
Annotation
的维度与 Chart
控件中的许多其他维度一样,确实以百分比给出。这样做的好处是它们可以像许多其他元素一样通过 Chart
控件巧妙地增长和收缩。
因此,如果您将图表的宽度加倍,则基本上是显示的 DataPoints
的 space 加倍,如果您的 Annotation
超过了它之前宽度的 1/3调整图表大小时仍会执行此操作..
这很好。
但不是你想要的..
因此,要将尺寸设置为以像素为单位的固定尺寸,您需要这样做:
- 以百分比计算你想要的大小并设置它
- 每当您调整图表大小时或其布局时重复
真正的问题是计算:如果您查看 Chart.ClientSize
,您会得到以像素为单位的大小,要获得 n 个像素,您需要执行以下操作:
float WidthInPercent = 100f * n / Chart.ClientSize.width;
然而,这并没有考虑到您的 Chart
可能具有的各种元素: Annotation
的 Size
确实 而不是 计算为图表大小的直接百分比。
而是计算为 InnerPlotPosition
占 ChartArea CA
的百分比。
InnerPlotPosition
默认设置为 Auto
所以访问它的值,例如CA.InnerPlotPosition.Width
将 return 0f
;但是你可以通过这样做得到(当前!!)值:
RectangleF IPP = CA.InnerPlotPosition.ToRectangleF();
ChartArea
本身的 Size/Position
也是如此:
RectangleF CAP = CA.Position.ToRectangleF();
现在您可以将这些百分比与 (current!) Chart.ClientSize
结合起来,找出达到特定像素大小所需的百分比..
请注意,在调整 大小时,这些值会 发生变化,因为 Legend
和 Axis
以及 Labels
等外部额外内容不会调整大小,因此它们的相对大小将相对于它们包含的元素增大或缩小..
所以你需要在每个Resize
事件上重新计算,或者,更好的是:写一个函数来为你做,你可以在需要的时候调用..
结果是一个 Annotation
,无论您如何调整 Chart
..
的大小,它(由于四舍五入,基本上)都会保持其大小
以下是一些有用的函数:
这个return是一个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);
}
这个是相似的,returns 当前 ClientRectangle
的 ChartArea's InnerplotPosition
以像素为单位:
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);
}
最后一个将以像素为单位的大小转换为以百分比为单位的大小,再次仅在当前有效,即直到下一次更改大小或布局..:[=52=]
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);
}
让我们看看调整大小前后的结果:
如您所见,大小保持不变。
另请注意我在 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, new Size(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;
}
我知道 OP 想要以像素为单位设置宽度,但如果有些人(比如我)不想以像素或百分比为单位设置宽度,而是根据实际值设置,只需设置 :
annotation.IsSizeAlwaysRelative = False
annotation.Width = whatEverValue
为什么 MS 图表矩形注释宽度是百分比而不是 msdn 所说的像素? https://msdn.microsoft.com/en-us/library/system.windows.forms.datavisualization.charting.annotation.width(v=vs.110).aspx
msdn 是这么说的 获取或设置注释的宽度(以像素为单位)。
我想将我的宽度设置为它声明的像素。我在这里错过了什么吗?
是的,我们不能将其设置为 % 或 px,因为 属性 值设置为双倍。 其次,pixle = H乘以W。但你只是设置图表的宽度,那你怎么能设置成pixle呢?根本不可能。我希望你能明白我的意思。
恭喜,您在文档中发现了一个错误!只需按照 link 到 Annotation.Height 文档即可轻松发现..
Annotation
的维度与 Chart
控件中的许多其他维度一样,确实以百分比给出。这样做的好处是它们可以像许多其他元素一样通过 Chart
控件巧妙地增长和收缩。
因此,如果您将图表的宽度加倍,则基本上是显示的 DataPoints
的 space 加倍,如果您的 Annotation
超过了它之前宽度的 1/3调整图表大小时仍会执行此操作..
这很好。
但不是你想要的..
因此,要将尺寸设置为以像素为单位的固定尺寸,您需要这样做:
- 以百分比计算你想要的大小并设置它
- 每当您调整图表大小时或其布局时重复
真正的问题是计算:如果您查看 Chart.ClientSize
,您会得到以像素为单位的大小,要获得 n 个像素,您需要执行以下操作:
float WidthInPercent = 100f * n / Chart.ClientSize.width;
然而,这并没有考虑到您的 Chart
可能具有的各种元素: Annotation
的 Size
确实 而不是 计算为图表大小的直接百分比。
而是计算为 InnerPlotPosition
占 ChartArea CA
的百分比。
InnerPlotPosition
默认设置为 Auto
所以访问它的值,例如CA.InnerPlotPosition.Width
将 return 0f
;但是你可以通过这样做得到(当前!!)值:
RectangleF IPP = CA.InnerPlotPosition.ToRectangleF();
ChartArea
本身的 Size/Position
也是如此:
RectangleF CAP = CA.Position.ToRectangleF();
现在您可以将这些百分比与 (current!) Chart.ClientSize
结合起来,找出达到特定像素大小所需的百分比..
请注意,在调整 大小时,这些值会 发生变化,因为 Legend
和 Axis
以及 Labels
等外部额外内容不会调整大小,因此它们的相对大小将相对于它们包含的元素增大或缩小..
所以你需要在每个Resize
事件上重新计算,或者,更好的是:写一个函数来为你做,你可以在需要的时候调用..
结果是一个 Annotation
,无论您如何调整 Chart
..
以下是一些有用的函数:
这个return是一个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);
}
这个是相似的,returns 当前 ClientRectangle
的 ChartArea's InnerplotPosition
以像素为单位:
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);
}
最后一个将以像素为单位的大小转换为以百分比为单位的大小,再次仅在当前有效,即直到下一次更改大小或布局..:[=52=]
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);
}
让我们看看调整大小前后的结果:
如您所见,大小保持不变。
另请注意我在 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, new Size(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;
}
我知道 OP 想要以像素为单位设置宽度,但如果有些人(比如我)不想以像素或百分比为单位设置宽度,而是根据实际值设置,只需设置 :
annotation.IsSizeAlwaysRelative = False
annotation.Width = whatEverValue