gpt4 book ai didi

c# - 如何根据图表栏大小更改数据点标签的颜色?

转载 作者:行者123 更新时间:2023-11-30 23:00:59 25 4
gpt4 key购买 nike

我添加了一个带有 ChartType Bar 的新图表控件 (System.Windows.Forms.DataVisualiation.Charting)。根据要求,标签文本必须是白色的并且进入条形值。因此,我将 DataPoint 对象的 CustomProperties 中的 BarLabelStyle=RightLabelForeColor 设置为白色。请参阅下面的图片。

enter image description here

第二个灰色条中的标签已正确显示。
第一个栏太小,白色文本显示在右侧但不可见。

enter image description here

但是,当栏太短时,标签文本位于栏外,使用白色无法看到文本。有没有办法检查标签文本何时绘制在条形值之外,以便我可以更改颜色(例如黑色)?

谢谢。

最佳答案

不幸的是,MCChart 几乎没有处理动态表达式的能力。

要变通,您可以..:

  • 根据 DataPoints 的 y 值对 ForeColor 进行编码。无论是在您添加它们时,还是在循环遍历所有点的函数中,无论您何时调用它。- 根据字体、轴范围和标签文本,这可能是您必须确定的某个阈值数字。

例子:

int p = yourSeries.Points.AddXY(...);
yourSeries.Points[p].LabelForeColor = yourSeries.Points[p].YValues[0] < threshold ?
Color.Black : Color.White;
  • 或者你可以作弊 ;-)

您可以将 LabelBackColor 设置为与 Series 相同的颜色,即条形本身。以下是如何做到这一点:

要访问 Series.Color,我们必须调用:

chart.ApplyPaletteColors();

现在我们可以设置

yourSeries.LabelForeColor = Color.White;
yourSeries.LabelBackColor = yourSeries.Color;

例子:

enter image description here


更新:

由于您不能使用作弊功能,因此您必须设置颜色。

挑战是要知道每个标签的文本需要多少空间,而条形有多少空间。前者可以测量(TextRenderer.MeasureString()),后者可以从 y 轴上提取(Axis.ValueToPixelPosition())。

这里有一个函数可以做到这一点;它比我希望的要复杂一些,主要是因为它试图变得通用..

void LabelColors(Chart chart, ChartArea ca, Series s)
{
if (chart.Series.Count <= 0 || chart.Series[0].Points.Count <= 0) return;
Axis ay = ca.AxisY;

// get the maximum & minimum values
double maxyv = ay.Maximum;
if (maxyv == double.NaN) maxyv = s.Points.Max(v => v.YValues[0]);
double minyv = s.Points.Min(v => v.YValues[0]);

// get the pixel positions of the minimum
int y0x = (int)ay.ValueToPixelPosition(0);

for (int i = 0; i < s.Points.Count; i++)
{
DataPoint dp = s.Points[i];
// pixel position of the bar right
int vx = (int)ay.ValueToPixelPosition(dp.YValues[0]);
// now we knowe the bar's width
int barWidth = vx - y0x;
// find out what the label text actauly is
string t = dp.LabelFormat != "" ?
String.Format(dp.LabelFormat, dp.YValues[0]) : dp.YValues[0].ToString();
string text = dp.Label != "" ? dp.Label : t;
// measure the (formatted) text
SizeF rect = TextRenderer.MeasureText(text, dp.Font);
Console.WriteLine(text);
dp.LabelForeColor = barWidth < rect.Width ? Color.Black : Color.White;
}
}

我可能过于复杂地获取了应该显示的文本;您当然可以决定是否可以简化您的案例。

注意:你必须调用这个函数..

  • 当您的数据可能发生变化时
  • 仅在图表轴完成布局后 (!)

前一点很明显,后一点则不然。这意味着您不能在添加积分后立即调用该功能!相反,您必须在稍后的某个地方执行此操作,否则获取条形大小所需的轴函数将不起作用。

MSDN 说它只能发生在 PaintXXX 事件中;我发现所有的鼠标事件也有效,然后是一些......

为了保存,我将把它放在 PostPaint 事件中:

private void chart_PostPaint(object sender, ChartPaintEventArgs e)
{
LabelColors(chart, chart.ChartAreas[0], chart.Series[0]);
}

enter image description here

关于c# - 如何根据图表栏大小更改数据点标签的颜色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51287181/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com