pmartin wrote: ↑Thu Aug 08, 2019 2:56 pm
Can you please help me understand the best way to shade the area under the curve with a sloped baseline?
I think the only way you're going to be able to do this is to derive a new Tool from our SeriesRegionTool and then adapt it to your needs. Unfortunately some of the key methods of the SeriesRegionTool are private rather than protected virtual, but in order to help you we can share some of our source code with you:
Code: Select all
public class MySeriesRegionTool : SeriesRegionTool
{
public MySeriesRegionTool(Chart c) : base(c) { }
protected override void ChartEvent(EventArgs e)
{
if (Series != null)
{
if (((e is BeforeDrawSeriesEventArgs) && (DrawBehindSeries))
|| (e is AfterDrawSeriesEventsArgs) && (!DrawBehindSeries))
{
DrawRegion();
}
}
}
/// <summary>
/// Using point x coordinate it calculates point y coordinate
/// </summary>
/// <param name="val">intersection point x coordinate</param>
/// <param name="y">returns intersection point y coordinate.</param>
/// <returns>Point index</returns>
private int IntersectionPoint(double val, out double y)
{
var i = 0;
y = Series.mandatory[i];
while ((val > Series.notMandatory[i]) && (i < Series.Count))
{
i++;
}
// We have two choices:
// #1: value is exactly at point coordinate
// #2: value is between two points - use linear interpolation to calculate y
if (val == Series.notMandatory[i])
{
y = Series.mandatory[i];
}
else
{
double k;
if ((i > 0) && (i < Series.Count))
{
k = Series.mandatory[i] - Series.mandatory[i - 1];
k /= (Series.notMandatory[i] - Series.notMandatory[i - 1]);
y = Series.mandatory[i - 1] + k * (val - Series.notMandatory[i - 1]);
}
}
return i;
}
private void DrawRegion()
{
if (Active && (Chart != null) && (Series != null))
{
var lb = Series.notMandatory.Minimum;
var ub = Series.notMandatory.Maximum;
if (!AutoBound)
{
lb = Math.Max(lb, LowerBound);
ub = Math.Min(ub, UpperBound);
}
// plot only if it makes sense
if ((ub > Series.notMandatory.Minimum) && (lb < Series.notMandatory.Maximum))
{
var first = IntersectionPoint(lb, out var yl);
var last = IntersectionPoint(ub, out var yu);
if (last < first)
{
Utils.SwapInteger(ref first, ref last);
}
var plen = last - first + 1;
var pts = new Point[plen + 4]; // need four extra points
for (var i = 0; i < plen; i++)
{
pts[i].X = Series.CalcXPos(i + first);
pts[i].Y = Series.CalcYPos(i + first);
}
// upper bound intersect point
pts[plen].X = Series.CalcXPosValue(ub);
pts[plen].Y = Series.CalcYPosValue(yu);
// upper bound origin point
pts[plen + 1].X = pts[plen].X;
pts[plen + 1].Y = UseOrigin ? Series.CalcYPosValue(Origin) : Series.GetVertAxis.IEndPos;
// lower bound origin point
pts[plen + 2].X = Series.CalcXPosValue(lb);
pts[plen + 2].Y = pts[plen + 1].Y;
// lower bound intersect point
pts[plen + 3].X = pts[plen + 2].X;
pts[plen + 3].Y = Series.CalcYPosValue(yl);
var gr = Chart.Graphics3D;
gr.Brush = Brush;
gr.Pen = Pen;
var zpos = DrawBehindSeries ? Series.EndZ : Series.StartZ;
var tmpR = gr.RectFromRectZ(Chart.ChartRect, zpos);
gr.ClipRectangle(tmpR);
gr.Polygon(zpos, pts);
gr.UnClip();
}
}
}
}
You can see this working by using this class in the example you mentioned, i.e.
Code: Select all
private void InitializeChart()
{
tChart1.Aspect.View3D = false;
var nSeries = 4;
var yPos = new int[nSeries];
var fast = new FastLine[nSeries];
var region = new MySeriesRegionTool[nSeries];
for (var i = 0; i < nSeries; i++)
{
yPos[i] = i * 5;
fast[i] = new FastLine(tChart1.Chart);
if (i % 2 == 0)
{
for (var j = 0; j < 200; j++) fast[i].Add(Math.Sin((double)j / 10) + yPos[i]);
}
else
{
for (var j = 0; j < 200; j++) fast[i].Add(Math.Cos((double)j / 10) + yPos[i]);
}
region[i] = new MySeriesRegionTool(tChart1.Chart);
region[i].Series = fast[i];
region[i].Origin = yPos[i];
region[i].UseOrigin = true;
region[i].Brush.Style = System.Drawing.Drawing2D.HatchStyle.Vertical;
region[i].Brush.Transparency = 100;
region[i].Pen.Visible = false;
region[i].Brush.ForegroundColor = fast[i].Color;
}
}
Please be aware that deriving TeeChart classes is perfectly valid under our license, although we do count it as 'source-code modification' and as such give no support to such classes. It is worth mentioning that there are a couple of options if you are not able to make the changes yourself to your satisfaction:
1) request a new feature request on
http://bugs.teechart.net/
2) ask
sales@steema.com for a quote from us for the work