我用ChartType Bar添加了一个新的图表控件(System.Windows.Forms.DataVisualiation.Charting
)。
根据要求,标签文本必须为白色并且在条形值内。因此,我将BarLabelStyle=Right
对象的CustomProperties
中的DataPoint
和LabelForeColor
设置为White。
请参见下面的图像。
第二个灰色栏中的标签正确显示。
相反,第一个栏太小,白色文本显示在右侧,但不可见。
但是,如果栏太短,则标签文本将位于栏的外部,并且无法使用白色看到文本。 有没有办法检查标签文本何时绘制在条形值之外,以便我可以更改颜色(例如黑色)?
谢谢。
答案 0 :(得分:2)
不幸的是,MCChart
几乎没有动态表达的能力。
要变通,您可以..:
ForeColor
的y值对DataPoints
进行编码。添加它们时或者在调用该函数的所有点上循环的函数中都可以。-根据字体,轴范围和标签文本的不同,这可能是您必须确定的一些阈值。示例:
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;
// 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;
}
}
我可能已经太复杂了获取应该显示的文字的方式;您当然可以决定是否可以简化案件。
注意:您必须调用此函数。
前一点很明显,而后者没有。这意味着添加点后不能立即调用该函数!相反,您必须在以后的某个位置进行操作,否则获取条形尺寸所需的ais函数将无法正常工作。
MSDN表示只能在PaintXXX
事件中发生;我发现所有鼠标事件也都起作用,然后再起作用。
为保存起见,我将其放在PostPaint
事件中:
private void chart_PostPaint(object sender, ChartPaintEventArgs e)
{
LabelColors(chart, chart.ChartAreas[0], chart.Series[0]);
}