C# 平滑叠层线图

C# 平滑叠层线图,c#,.net,winforms,charts,mschart,C#,.net,Winforms,Charts,Mschart,我有一个c#Windows窗体应用程序,它使用标准MS图表控件生成一个堆叠的折线图,如下例所示 是否有一种通过格式化序列或其他属性来“平滑”线条的方法 看看MSDN和谷歌,我似乎找不到一个方法来做到这一点,在Excel中有一个系列 我错过了还是不可能 如果您喜欢样条区域的平滑外观您可以计算必要的值以获得该外观: 请注意: 我颠倒了序列的顺序;有很多方法可以使颜色正确。。(相反,可能应该反向累积) 堆叠的数据点需要像往常一样对齐,任何空的数据点的Y值应为0 当然,在新的系列中,您不能再访问实际

我有一个c#Windows窗体应用程序,它使用标准MS图表控件生成一个堆叠的折线图,如下例所示

是否有一种通过格式化序列或其他属性来“平滑”线条的方法

看看MSDN和谷歌,我似乎找不到一个方法来做到这一点,在Excel中有一个
系列

我错过了还是不可能


如果您喜欢
样条区域的平滑外观
您可以计算必要的值以获得该外观:

请注意:

  • 我颠倒了序列的顺序;有很多方法可以使颜色正确。。(相反,可能应该反向累积)
  • 堆叠的
    数据点
    需要像往常一样对齐,任何空的
    数据点
    Y值
    应为
    0
  • 当然,在新的系列中,您不能再访问实际的数据值,因为您现在拥有的是累积值;至少在不逆转计算的情况下。所以如果需要的话,把它们放在某个地方。新的
    DataPoints'标记
    属性是一个选项
  • 您可以通过设置其
    LineTension
    自定义属性来控制每个
    系列的“平滑度”:

下面是一个完整的示例代码,它创建了上面的截图,根据堆叠区域图表1中的数据计算“堆叠”样条区域图表2

// preparation
for (int i = 0; i < 4; i++)
{
    Series s = chart1.Series.Add("S" + i);
    s.ChartType = SeriesChartType.StackedArea;

    Series s2 = chart2.Series.Add("S" + i);
    s2.ChartType = SeriesChartType.SplineArea;

}

for (int i = 0; i < 30; i++)   // some test data
{
    chart1.Series[0].Points.AddXY(i, Math.Abs(Math.Sin(i / 8f)));
    chart1.Series[1].Points.AddXY(i, Math.Abs(Math.Sin(i / 4f)));
    chart1.Series[2].Points.AddXY(i, Math.Abs(Math.Sin(i / 1f)));
    chart1.Series[3].Points.AddXY(i, Math.Abs(Math.Sin(i / 0.5f)));
}

// the actual calculations:

int sCount = chart1.Series.Count; 
for (int i = 0; i < chart1.Series[0].Points.Count ; i++)
{
    double v = chart1.Series[0].Points[i].YValues[0];
    chart2.Series[sCount - 1].Points.AddXY(i, v);
    for (int j = 1; j < sCount; j++)
    {
        v += chart1.Series[j].Points[i].YValues[0];
        chart2.Series[sCount - j - 1].Points.AddXY(i, v);
    }
}

// optionally control the tension:
chart2.Series[0].SetCustomProperty("LineTension", "0.15");
//准备
对于(int i=0;i<4;i++)
{
系列s=图表1.系列.添加(“s”+i);
s、 ChartType=SerieChartType.StackedArea;
s2系列=图表2.系列添加(“S”+i);
s2.ChartType=SerieChartType.SplineArea;
}
对于(int i=0;i<30;i++)//一些测试数据
{
chart1.Series[0].Points.AddXY(i,Math.Abs(Math.Sin(i/8f));
chart1.Series[1].Points.AddXY(i,Math.Abs(Math.Sin(i/4f));
chart1.Series[2].Points.AddXY(i,Math.Abs(Math.Sin(i/1f));
chart1.Series[3].Points.AddXY(i,Math.Abs(Math.Sin(i/0.5f));
}
//实际计算:
int scont=chart1.Series.Count;
对于(int i=0;i
如果您喜欢
样条区域的平滑外观
,您可以计算必要的值以获得该外观:

请注意:

  • 我颠倒了序列的顺序;有很多方法可以使颜色正确。。(相反,可能应该反向累积)
  • 堆叠的
    数据点
    需要像往常一样对齐,任何空的
    数据点
    Y值
    应为
    0
  • 当然,在新的系列中,您不能再访问实际的数据值,因为您现在拥有的是累积值;至少在不逆转计算的情况下。所以如果需要的话,把它们放在某个地方。新的
    DataPoints'标记
    属性是一个选项
  • 您可以通过设置其
    LineTension
    自定义属性来控制每个
    系列的“平滑度”:

下面是一个完整的示例代码,它创建了上面的截图,根据堆叠区域图表1中的数据计算“堆叠”样条区域图表2

// preparation
for (int i = 0; i < 4; i++)
{
    Series s = chart1.Series.Add("S" + i);
    s.ChartType = SeriesChartType.StackedArea;

    Series s2 = chart2.Series.Add("S" + i);
    s2.ChartType = SeriesChartType.SplineArea;

}

for (int i = 0; i < 30; i++)   // some test data
{
    chart1.Series[0].Points.AddXY(i, Math.Abs(Math.Sin(i / 8f)));
    chart1.Series[1].Points.AddXY(i, Math.Abs(Math.Sin(i / 4f)));
    chart1.Series[2].Points.AddXY(i, Math.Abs(Math.Sin(i / 1f)));
    chart1.Series[3].Points.AddXY(i, Math.Abs(Math.Sin(i / 0.5f)));
}

// the actual calculations:

int sCount = chart1.Series.Count; 
for (int i = 0; i < chart1.Series[0].Points.Count ; i++)
{
    double v = chart1.Series[0].Points[i].YValues[0];
    chart2.Series[sCount - 1].Points.AddXY(i, v);
    for (int j = 1; j < sCount; j++)
    {
        v += chart1.Series[j].Points[i].YValues[0];
        chart2.Series[sCount - j - 1].Points.AddXY(i, v);
    }
}

// optionally control the tension:
chart2.Series[0].SetCustomProperty("LineTension", "0.15");
//准备
对于(int i=0;i<4;i++)
{
系列s=图表1.系列.添加(“s”+i);
s、 ChartType=SerieChartType.StackedArea;
s2系列=图表2.系列添加(“S”+i);
s2.ChartType=SerieChartType.SplineArea;
}
对于(int i=0;i<30;i++)//一些测试数据
{
chart1.Series[0].Points.AddXY(i,Math.Abs(Math.Sin(i/8f));
chart1.Series[1].Points.AddXY(i,Math.Abs(Math.Sin(i/4f));
chart1.Series[2].Points.AddXY(i,Math.Abs(Math.Sin(i/1f));
chart1.Series[3].Points.AddXY(i,Math.Abs(Math.Sin(i/0.5f));
}
//实际计算:
int scont=chart1.Series.Count;
对于(int i=0;i
尝试
SplineArea
图表类型。如果你想去掉尖角边,你可以计算数据点,然后将区域绘制为由曲线和直线组成的填充路径。是一个计算堆叠坐标的示例。@jstreet,不幸的是,这不是一个堆叠图,否则它会很好,但是结果看起来很有趣!谢谢你的建议。@TaW谢谢你的建议,我希望有一个简单的解决方案:(SplineArea数据可以计算为与StackedArea图表相似!请尝试
SplineArea
图表类型。如果要去除尖角,可以计算数据点并将区域绘制为由曲线和直线组成的填充路径。这是计算堆叠坐标的示例。@jstreet,不幸的是,这不是。)如果是堆叠图,那就太棒了,不过结果看起来很有趣!谢谢你的建议。@TaW谢谢你的建议,我希望有一个简单的解决方案:(SplineArea数据可以计算出来,与你的堆叠图相似!