很不幸,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
示例:
更新:
由于无法使用作弊,您需要设置颜色。
挑战在于知道每个标签文本所需的空间大小与条形图拥有的空间大小相比。前者可以测量 (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;
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]);
int y0x = (int)ay.ValueToPixelPosition(0);
for (int i = 0; i < s.Points.Count; i++)
{
DataPoint dp = s.Points[i];
int vx = (int)ay.ValueToPixelPosition(dp.YValues[0]);
int barWidth = vx - y0x;
string t = dp.LabelFormat != "" ?
String.Format(dp.LabelFormat, dp.YValues[0]) : dp.YValues[0].ToString();
string text = dp.Label != "" ? dp.Label : t;
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]);
}