Page 1 of 1
Adding area to chart modifies its StartColor
Posted: Tue Aug 30, 2016 11:48 am
by 15678926
When I use area series, set up its gradient colors and then add it to chart, its gradient's StartColor is reset to some default value. MiddleColor and EndColor are correct. Please see the example below to reproduce:
Code: Select all
Area area = new Area();
area.AreaBrush.Gradient.StartColor = Color.GreenYellow;
area.AreaBrush.Gradient.MiddleColor = Color.BlueViolet;
area.AreaBrush.Gradient.EndColor = Color.Crimson;
area.AreaBrush.Gradient.UseMiddle = true;
area.AreaBrush.Gradient.Visible = true;
area.FillSampleValues();
chart.Series.Add(area);
I'm using version 4.1.2016.05120 and it worked fine in 2.0.2652.22325.
Re: Adding area to chart modifies its StartColor
Posted: Tue Aug 30, 2016 1:51 pm
by Christopher
Hello,
This defect has now been fixed, but as a workaround you can either do this:
Code: Select all
private void InitializeChart()
{
Area area = new Area();
area.Color = Color.GreenYellow;
area.AreaBrush.Gradient.StartColor = Color.GreenYellow;
area.AreaBrush.Gradient.MiddleColor = Color.BlueViolet;
area.AreaBrush.Gradient.EndColor = Color.Crimson;
area.AreaBrush.Gradient.UseMiddle = true;
area.AreaBrush.Gradient.Visible = true;
area.FillSampleValues();
tChart1.Series.Add(area);
}
or this:
Code: Select all
private void InitializeChart()
{
Area area = new Area(tChart1.Chart);
area.AreaBrush.Gradient.StartColor = Color.GreenYellow;
area.AreaBrush.Gradient.MiddleColor = Color.BlueViolet;
area.AreaBrush.Gradient.EndColor = Color.Crimson;
area.AreaBrush.Gradient.UseMiddle = true;
area.AreaBrush.Gradient.Visible = true;
area.FillSampleValues();
}
Re: Adding area to chart modifies its StartColor
Posted: Wed Aug 31, 2016 10:42 am
by 15678926
Thanks for reply, the first workaround works. However, I have another problem. When I use transparency and want to hide area lines, 1px-wide gaps appear. Can be reproduced with:
Code: Select all
Area area = new Area();
area.Color = Color.GreenYellow;
area.AreaBrush.Gradient.StartColor = Color.GreenYellow;
area.AreaBrush.Gradient.MiddleColor = Color.BlueViolet;
area.AreaBrush.Gradient.EndColor = Color.Crimson;
area.AreaBrush.Gradient.UseMiddle = true;
area.AreaBrush.Gradient.Visible = true;
area.AreaBrush.Gradient.Transparency = 20;
area.AreaLines.Visible = false;
area.FillSampleValues();
chart.Series.Add(area);
This is how it looks:
- teechart-lines.png (34.93 KiB) Viewed 18692 times
This only happens if transparency is used. If I set GradientRelative to false, gaps dissapear, but some other problem pops up, so I'd like to avoid it. It worked in 2.0.2652.22325.
Re: Adding area to chart modifies its StartColor
Posted: Wed Aug 31, 2016 1:26 pm
by Christopher
Hello,
Yes, I can reproduce this issue here. However, it seems specific to a theme that did not exist in version 2. If you use an older theme, then this effect is not present, e.g.
Code: Select all
private void InitializeChart()
{
tChart1.CurrentTheme = ThemeType.Opera;
tChart1.Aspect.View3D = false;
Area area = new Area();
area.Color = Color.GreenYellow;
area.AreaBrush.Gradient.StartColor = Color.GreenYellow;
area.AreaBrush.Gradient.MiddleColor = Color.BlueViolet;
area.AreaBrush.Gradient.EndColor = Color.Crimson;
area.AreaBrush.Gradient.UseMiddle = true;
area.AreaBrush.Gradient.Visible = true;
area.AreaBrush.Gradient.Transparency = 20;
area.AreaLines.Visible = false;
area.FillSampleValues();
tChart1.Series.Add(area);
tChart1.Panel.Gradient.Visible = false;
tChart1.Panel.Color = Color.White;
tChart1.Walls.Back.Gradient.Visible = false;
tChart1.Walls.Back.Color = Color.White;
}
- 636082537139561153.jpg (134.54 KiB) Viewed 18676 times
Re: Adding area to chart modifies its StartColor
Posted: Wed Aug 31, 2016 2:09 pm
by 15678926
Unfortunately, this doesn't work for me if the data is irregular:
Code: Select all
Area area = new Area();
area.Color = Color.GreenYellow;
area.AreaBrush.Gradient.StartColor = Color.GreenYellow;
area.AreaBrush.Gradient.MiddleColor = Color.BlueViolet;
area.AreaBrush.Gradient.EndColor = Color.Crimson;
area.AreaBrush.Gradient.UseMiddle = true;
area.AreaBrush.Gradient.Visible = true;
area.AreaBrush.Gradient.Transparency = 20;
area.AreaLines.Visible = false;
var x = 0d;
for (int i = 0; i < 30; i++)
{
x = random.NextDouble()*10 + x;
var y = random.NextDouble()*5;
area.Add(x, y);
}
chart.CurrentTheme = ThemeType.Opera;
chart.Series.Add(area);
This produces:
- teechart-lines-2.png (39.8 KiB) Viewed 18670 times
Re: Adding area to chart modifies its StartColor
Posted: Thu Sep 01, 2016 10:08 am
by Christopher
Hello,
The answer here is to change the SmoothingMode, e.g.
Code: Select all
Random random = new Random();
private void InitializeChart()
{
tChart1.CurrentTheme = ThemeType.Opera;
tChart1.Graphics3D.SmoothingMode = SmoothingMode.HighSpeed;
Area area = new Area();
area.Color = Color.GreenYellow;
area.AreaBrush.Gradient.StartColor = Color.GreenYellow;
area.AreaBrush.Gradient.MiddleColor = Color.BlueViolet;
area.AreaBrush.Gradient.EndColor = Color.Crimson;
area.AreaBrush.Gradient.UseMiddle = true;
area.AreaBrush.Gradient.Visible = true;
area.AreaBrush.Gradient.Transparency = 20;
area.AreaBrush.Gradient.GammaCorrection = true;
area.LinePen.Visible = false;
area.AreaLines.Visible = false;
var x = 0d;
for (int i = 0; i <= 30; i++)
{
x = random.NextDouble() * 10 + x;
var y = random.NextDouble() * 5;
area.Add(x, y);
}
tChart1.Series.Add(area);
}
which gives me:
- 636083281774883694.jpg (119.01 KiB) Viewed 18663 times
FYI, you can see this effect outside of TeeChart, e.g. in a UserControl:
Code: Select all
public partial class UserControl2 : UserControl
{
public UserControl2()
{
InitializeComponent();
}
Random rnd = new Random();
protected override void OnPaint(PaintEventArgs e)
{
Func<Rectangle, Color, Color, Color, LinearGradientBrush> Gradient = (rect, startColor, middleColor, endColor) =>
{
LinearGradientBrush result = new LinearGradientBrush(rect, startColor, endColor, LinearGradientMode.Vertical);
ColorBlend blend = new ColorBlend(3);
blend.Colors[0] = startColor;
blend.Colors[1] = middleColor;
blend.Colors[2] = endColor;
blend.Positions[0] = 0;
blend.Positions[1] = 0.5F;
blend.Positions[2] = 1;
result.InterpolationColors = blend;
result.GammaCorrection = false;
return result;
};
Func<Point[], Rectangle> BoundingRect = (p) =>
{
Rectangle r = new Rectangle();
if (p.GetUpperBound(0) > 1)
{
r.X = p[0].X;
r.Width = 0;
r.Y = p[0].Y;
r.Height = 0;
for (int t = 1; t <= p.GetUpperBound(0); t++)
{
if (p[t].X < r.Left)
{
r.Width = r.Right - p[t].X;
r.X = p[t].X;
}
if (p[t].X > r.Right)
{
r.Width = r.Width + p[t].X - r.Right;
}
if (p[t].Y < r.Top)
{
r.Height = r.Bottom - p[t].Y;
r.Y = p[t].Y;
}
if (p[t].Y > r.Bottom)
{
r.Height = r.Height + p[t].Y - r.Bottom;
}
}
}
return r;
};
Graphics g = e.Graphics;
g.SmoothingMode = SmoothingMode.HighQuality;
Rectangle bounds = this.Bounds;
int count = 30;
int width = bounds.Width / count;
int trans = (int)Math.Round(255 * 0.6);
Point oldTopRight = Point.Empty;
for (int i = 0; i < count; i++)
{
int x0 = width * i;
int y0 = rnd.Next(bounds.Height);
int x1 = x0 + width;
int y1 = bounds.Height;
Point topLeft = new Point(x0, y0);
Point topRight = new Point(x1, y0);
Point bottomRight = new Point(x1, y1);
Point bottomLeft = new Point(x0, y1);
Point[] poly = new Point[] { oldTopRight == Point.Empty ? topLeft : oldTopRight, topRight, bottomRight, bottomLeft};
Rectangle rect = new Rectangle(x0, y0, width, bounds.Height - (oldTopRight == Point.Empty ? y0 : Math.Min(oldTopRight.Y, y0)));
LinearGradientBrush grad = Gradient(BoundingRect(poly), Color.FromArgb(trans, Color.GreenYellow), Color.FromArgb(trans, Color.BlueViolet), Color.FromArgb(trans, Color.Crimson));
g.FillPolygon(grad, poly);
oldTopRight = topRight;
}
}
}
use of which gives me:
- usercontrol.PNG (69.68 KiB) Viewed 18662 times
Re: Adding area to chart modifies its StartColor
Posted: Mon Sep 05, 2016 8:48 am
by 15678926
Is it possible to disable antialiasing for area series but enable it for line series on the same chart? I'd like to try to work around the problem by drawing antialiased line series over not antialiased area. Or maybe there is a better workaround? Not antialiased area doesn't look too well...
Re: Adding area to chart modifies its StartColor
Posted: Tue Sep 06, 2016 7:38 am
by Christopher
Matis wrote:Is it possible to disable antialiasing for area series but enable it for line series on the same chart? I'd like to try to work around the problem by drawing antialiased line series over not antialiased area. Or maybe there is a better workaround? Not antialiased area doesn't look too well...
Unfortunately the GDI+ graphics SmoothingMode cannot be set to different values for different areas of the canvas. The workaround we offer is the one you discovered near the beginning of this thread - setting GradientRelative to true. Which problems did you experience with this setting?
Re: Adding area to chart modifies its StartColor
Posted: Wed Sep 07, 2016 6:52 am
by 15678926
When I used GradientRelative then area's color became solid below y-value of 1. But nevermind, we decided to simply disable area's antialiasing for the time being. Thanks for the assistance.
Re: Adding area to chart modifies its StartColor
Posted: Wed Sep 07, 2016 8:42 am
by Christopher
Using the following code:
Code: Select all
Random random = new Random();
private void InitializeChart()
{
tChart1.CurrentTheme = ThemeType.Opera;
Area area = new Area();
area.Color = Color.GreenYellow;
area.AreaBrush.Gradient.StartColor = Color.GreenYellow;
area.AreaBrush.Gradient.MiddleColor = Color.BlueViolet;
area.AreaBrush.Gradient.EndColor = Color.Crimson;
area.AreaBrush.Gradient.UseMiddle = true;
area.AreaBrush.Gradient.Visible = true;
area.AreaBrush.Gradient.Transparency = 20;
area.GradientRelative = false;
area.LinePen.Visible = false;
area.AreaLines.Visible = false;
area.Origin = 0;
area.UseOrigin = true;
var x = 0d;
for (int i = 0; i <= 30; i++)
{
x = random.NextDouble() * 10 + x;
double y = random.NextDouble();
bool flag = random.NextDouble() < 0.5;
y = flag ? y : y * -1;
area.Add(x, y);
}
tChart1.Series.Add(area);
}
I get this chart:
- 636088416560987456.jpg (110.95 KiB) Viewed 18614 times
Is this not what you expect?
Re: Adding area to chart modifies its StartColor
Posted: Thu Sep 08, 2016 8:15 am
by 15678926
I reproduced the problem in a sample app. It's not actually below 1 and not solid color (that was true for the data and settings in my actual application), but rather a "restarted" gradient below lowest y-value of an area. It happens when there are more multiple series. It looks like a rectangle is drawn below an area chart and its gradient is drawn separately from area above it:
- teechart-gradient.png (46.44 KiB) Viewed 18605 times
Code: Select all
var data = GetData();
Area area = new Area();
area.Color = StartColor;
area.AreaBrush.Gradient.StartColor = Color.GreenYellow;
area.AreaBrush.Gradient.MiddleColor = Color.BlueViolet;
area.AreaBrush.Gradient.EndColor = Color.Crimson;
area.AreaBrush.Gradient.UseMiddle = true;
area.AreaBrush.Gradient.Visible = true;
area.AreaBrush.Gradient.Transparency = 20;
area.AreaLines.Visible = false;
area.GradientRelative = false;
SetData(area, data);
Line line = new Line();
line.Color = Color.AliceBlue;
var newData = data.Select(p => new Point(p.X, p.Y - 3));
SetData(line, newData);
chart.Series.Add(area);
chart.Series.Add(line);
Re: Adding area to chart modifies its StartColor
Posted: Thu Sep 08, 2016 9:12 am
by Christopher
Hello,
Okay, thank you, I think I can see what's happening - if I use this code:
Code: Select all
Random random = new Random();
private void InitializeChart()
{
tChart1.CurrentTheme = ThemeType.Opera;
tChart1.Aspect.View3D = false;
Area area = new Area();
area.Color = Color.GreenYellow;
area.AreaBrush.Gradient.StartColor = Color.GreenYellow;
area.AreaBrush.Gradient.MiddleColor = Color.BlueViolet;
area.AreaBrush.Gradient.EndColor = Color.Crimson;
area.AreaBrush.Gradient.UseMiddle = true;
area.AreaBrush.Gradient.Visible = true;
area.AreaBrush.Gradient.Transparency = 20;
area.GradientRelative = false;
area.LinePen.Visible = false;
area.AreaLines.Visible = false;
//area.Origin = 0;
//area.UseOrigin = true;
var x = 0d;
for (int i = 0; i <= 30; i++)
{
x = random.NextDouble() * 10 + x;
double y = random.NextDouble();
bool flag = random.NextDouble() < 0.5;
y = flag ? y : y * -1;
area.Add(x, y);
}
tChart1.Series.Add(area);
}
and then use the mouse to scroll the chart upwards, I get this:
- 636089297353293595.jpg (93.83 KiB) Viewed 18596 times
I have added this to our issue tracker with
id=1625.