C# 图表:在时间图中将布尔标志显示为填充矩形(而不是直线)
我在WinForms中使用C#图表,使用“线”图表类型实时绘制各种变量。这对于模拟值很有效,但对于开/关标志来说并不理想。 我想将多个标志绘制为水平条,当值为“1”时填充,当值为“0”时清除。 在我从头开始编写解决方案之前,您对我如何利用“图表”对象的任何特性来更有效地实现这一点有何建议 编辑:我正在玩区域类型,它似乎很有前途。C# 图表:在时间图中将布尔标志显示为填充矩形(而不是直线),c#,winforms,charts,flags,C#,Winforms,Charts,Flags,我在WinForms中使用C#图表,使用“线”图表类型实时绘制各种变量。这对于模拟值很有效,但对于开/关标志来说并不理想。 我想将多个标志绘制为水平条,当值为“1”时填充,当值为“0”时清除。 在我从头开始编写解决方案之前,您对我如何利用“图表”对象的任何特性来更有效地实现这一点有何建议 编辑:我正在玩区域类型,它似乎很有前途。 编辑2:这不起作用,因为区域类型中的区域总是从图表的底部开始,隐藏其他行。我现在正在尝试范围列类型,有几种方法可以解决这个问题。StackedBars,AreaCh
编辑2:这不起作用,因为区域类型中的区域总是从图表的底部开始,隐藏其他行。我现在正在尝试范围列类型,有几种方法可以解决这个问题。
StackedBars
,AreaChart
,注释
,但我认为最简单的方法是使用LineChartType
第一个问题是:如何创建间隙?最简单的方法是将它们绘制为线,但使用颜色。透明
。因此,我们不使用标志值作为y值,而是使用它来设置颜色
所以我们可以使用这样的函数:
void AddFlagLine(Chart chart, int series, int flag, int x)
{
Series s = chart.Series[series];
int px = s.Points.AddXY(x, series);
s.Points[px].Color = s.Color;
if (px > 0) s.Points[px - 1].Color = flag == 1 ? s.Color : Color.Transparent;
}
private void chart_PostPaint(object sender, ChartPaintEventArgs e)
{
Graphics g = e.ChartGraphics.Graphics;
Axis ax = chart.ChartAreas[0].AxisX;
Axis ay = chart.ChartAreas[0].AxisY;
for (int si = 0; si < chart.Series.Count; si++ )
{
Series s = chart.Series[si];
for (int pi = 1; pi < s.Points.Count - 1; pi++)
{
DataPoint dp = s.Points[pi];
int y = (int) ay.ValueToPixelPosition(dp.YValues[0]+1); ///*1*
int x0 = (int)ax.ValueToPixelPosition(ax.Minimum);
int x1 = (int)ax.ValueToPixelPosition(s.Points[pi-1].XValue); ///*2*
int x2 = (int)ax.ValueToPixelPosition(dp.XValue);
x1 = Math.Max(x1, x0);
x2 = Math.Max(x2, x0);
using (Pen pen = new Pen(dp.Color, 40) ///*3*
{ StartCap = System.Drawing.Drawing2D.LineCap.Flat,
EndCap = System.Drawing.Drawing2D.LineCap.Flat })
{
g.DrawLine(pen, x1, y, x2, y);
}
}
}
它采用系列的索引
,并使用标志
确定颜色;请注意,线段的颜色由端点的颜色控制
因此,如果您想让线从新点开始,以获得其标志颜色,则需要在添加下一个时设置它
这很简单,对于厚度为1-10的线条来说效果很好。但是如果你想要更大的宽度,事情会变得有点难看
圆顶开始变得越来越大,直到它们真正接触,或多或少地缩小了间隙
不幸的是,似乎无法控制线条的大写样式。有许多样式,包括DashStyles
,但不是这一个。因此,我们必须求助于所有者绘图。这对于折线图来说相当简单。以下是一个示例:
xxxPaint事件如下所示:
void AddFlagLine(Chart chart, int series, int flag, int x)
{
Series s = chart.Series[series];
int px = s.Points.AddXY(x, series);
s.Points[px].Color = s.Color;
if (px > 0) s.Points[px - 1].Color = flag == 1 ? s.Color : Color.Transparent;
}
private void chart_PostPaint(object sender, ChartPaintEventArgs e)
{
Graphics g = e.ChartGraphics.Graphics;
Axis ax = chart.ChartAreas[0].AxisX;
Axis ay = chart.ChartAreas[0].AxisY;
for (int si = 0; si < chart.Series.Count; si++ )
{
Series s = chart.Series[si];
for (int pi = 1; pi < s.Points.Count - 1; pi++)
{
DataPoint dp = s.Points[pi];
int y = (int) ay.ValueToPixelPosition(dp.YValues[0]+1); ///*1*
int x0 = (int)ax.ValueToPixelPosition(ax.Minimum);
int x1 = (int)ax.ValueToPixelPosition(s.Points[pi-1].XValue); ///*2*
int x2 = (int)ax.ValueToPixelPosition(dp.XValue);
x1 = Math.Max(x1, x0);
x2 = Math.Max(x2, x0);
using (Pen pen = new Pen(dp.Color, 40) ///*3*
{ StartCap = System.Drawing.Drawing2D.LineCap.Flat,
EndCap = System.Drawing.Drawing2D.LineCap.Flat })
{
g.DrawLine(pen, x1, y, x2, y);
}
}
}
private void chart_PostPaint(对象发送方,ChartPaintEventArgs e)
{
图形g=e.ChartGraphics.Graphics;
Axis ax=图表。图表区域[0]。AxisX;
ay轴=图表。图表区域[0]。Axis;
对于(int-si=0;si
请注意:
- 1:我已经决定将序列上移1;这取决于您是否使用或关闭y轴标签,或者是否用自定义标签替换它们
- 2:这里我们使用上一点的x位置
- 3:请注意,与其硬编码40像素的宽度,您实际上应该决定计算的宽度。这是一个几乎填满该区域的示例: int宽度=(int)((Y.值像素位置(Y.最小值)- ay.ValueToPixelPosition(ay.Maximum))/(chart7.Series.Count+2)
我已经将所有的
边框宽度都改为0
,所以只有画好的线条才能显示出来。有几种方法可以解决这个问题。堆叠条形图
,面积图
,注释
,但我认为目前为止最简单的方法是使用线形图类型
第一个问题是:如何创建间隙?最简单的方法是将它们绘制为线,但使用颜色。透明
。因此,我们不使用标志值作为y值,而是使用它来设置颜色
所以我们可以使用这样的函数:
void AddFlagLine(Chart chart, int series, int flag, int x)
{
Series s = chart.Series[series];
int px = s.Points.AddXY(x, series);
s.Points[px].Color = s.Color;
if (px > 0) s.Points[px - 1].Color = flag == 1 ? s.Color : Color.Transparent;
}
private void chart_PostPaint(object sender, ChartPaintEventArgs e)
{
Graphics g = e.ChartGraphics.Graphics;
Axis ax = chart.ChartAreas[0].AxisX;
Axis ay = chart.ChartAreas[0].AxisY;
for (int si = 0; si < chart.Series.Count; si++ )
{
Series s = chart.Series[si];
for (int pi = 1; pi < s.Points.Count - 1; pi++)
{
DataPoint dp = s.Points[pi];
int y = (int) ay.ValueToPixelPosition(dp.YValues[0]+1); ///*1*
int x0 = (int)ax.ValueToPixelPosition(ax.Minimum);
int x1 = (int)ax.ValueToPixelPosition(s.Points[pi-1].XValue); ///*2*
int x2 = (int)ax.ValueToPixelPosition(dp.XValue);
x1 = Math.Max(x1, x0);
x2 = Math.Max(x2, x0);
using (Pen pen = new Pen(dp.Color, 40) ///*3*
{ StartCap = System.Drawing.Drawing2D.LineCap.Flat,
EndCap = System.Drawing.Drawing2D.LineCap.Flat })
{
g.DrawLine(pen, x1, y, x2, y);
}
}
}
它采用系列的索引
,并使用标志
确定颜色;请注意,线段的颜色由端点的颜色控制
因此,如果您想让线从新点开始,以获得其标志颜色,则需要在添加下一个时设置它
这很简单,对于厚度为1-10的线条来说效果很好。但是如果你想要更大的宽度,事情会变得有点难看
圆顶开始变得越来越大,直到它们真正接触,或多或少地缩小了间隙
不幸的是,似乎无法控制线条的大写样式。有许多样式,包括DashStyles
,但不是这一个。因此,我们必须求助于所有者绘图。这对于折线图来说相当简单。以下是一个示例:
xxxPaint事件如下所示:
void AddFlagLine(Chart chart, int series, int flag, int x)
{
Series s = chart.Series[series];
int px = s.Points.AddXY(x, series);
s.Points[px].Color = s.Color;
if (px > 0) s.Points[px - 1].Color = flag == 1 ? s.Color : Color.Transparent;
}
private void chart_PostPaint(object sender, ChartPaintEventArgs e)
{
Graphics g = e.ChartGraphics.Graphics;
Axis ax = chart.ChartAreas[0].AxisX;
Axis ay = chart.ChartAreas[0].AxisY;
for (int si = 0; si < chart.Series.Count; si++ )
{
Series s = chart.Series[si];
for (int pi = 1; pi < s.Points.Count - 1; pi++)
{
DataPoint dp = s.Points[pi];
int y = (int) ay.ValueToPixelPosition(dp.YValues[0]+1); ///*1*
int x0 = (int)ax.ValueToPixelPosition(ax.Minimum);
int x1 = (int)ax.ValueToPixelPosition(s.Points[pi-1].XValue); ///*2*
int x2 = (int)ax.ValueToPixelPosition(dp.XValue);
x1 = Math.Max(x1, x0);
x2 = Math.Max(x2, x0);
using (Pen pen = new Pen(dp.Color, 40) ///*3*
{ StartCap = System.Drawing.Drawing2D.LineCap.Flat,
EndCap = System.Drawing.Drawing2D.LineCap.Flat })
{
g.DrawLine(pen, x1, y, x2, y);
}
}
}
private void chart_PostPaint(对象发送方,ChartPaintEventArgs e)
{
图形g=e.ChartGraphics.Graphics;
Axis ax=图表。图表区域[0]。AxisX;
ay轴=图表。图表区域[0]。Axis;
对于(int-si=0;si