Skip to content

Commit

Permalink
- (breaking changes) removed series types in Highchart control, now i…
Browse files Browse the repository at this point in the history
…t's separated classes;

- other minor changes;
  • Loading branch information
Meragon committed Apr 10, 2020
1 parent 65bc61b commit 7bbccab
Show file tree
Hide file tree
Showing 18 changed files with 611 additions and 421 deletions.
10 changes: 5 additions & 5 deletions Controls/Highcharts/DataCollection.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
using System;

namespace Highcharts
namespace Highcharts
{
using System;
using System.Collections;
using System.Collections.Generic;

public class DataCollection : IEnumerable
{
private static readonly double[] emptyArray = new double[0];
private readonly Series owner;

private double[] items = new double[0];
private readonly Series owner;

private double[] items = new double[0]; // TODO: nullable type.
private double max;
private double min;
private int size;
Expand Down
301 changes: 80 additions & 221 deletions Controls/Highcharts/Highchart.cs

Large diffs are not rendered by default.

66 changes: 23 additions & 43 deletions Controls/Highcharts/LegendButton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,20 @@

internal sealed class LegendButton : Button
{
internal bool seriesEnabled;

private readonly Pen seriesPen = new Pen(Color.Transparent, 2);
private const int DefaultTextMarginLeft = 16;

public LegendButton(Legend l, Series s)
{
Legend = l;
Series = s;
Text = s.name;

OnMouseClick(new MouseEventArgs(MouseButtons.Left, 1, 0, 0, 0));
TextLeftMargin = DefaultTextMarginLeft;
TextFromSeries();
}

public Legend Legend { get; private set; }
public Series Series { get; private set; }
public int TextLeftMargin { get; set; }

protected override void OnMouseClick(MouseEventArgs e)
{
Expand All @@ -29,11 +28,13 @@ protected override void OnMouseClick(MouseEventArgs e)
switch (e.Button)
{
case MouseButtons.Left:
seriesEnabled = !seriesEnabled;
Series.visible = !Series.visible;

Series.visible = seriesEnabled;
if (Parent != null) ((Highchart)Parent).RecalcCategories();
var highcharts = Parent as Highchart;
if (highcharts != null)
highcharts.UpdatePlot(); // Update plot min and max values range.
break;

case MouseButtons.Right:

var itemColor = new ToolStripMenuItem(Highchart.textLegendMenu_Color);
Expand All @@ -44,33 +45,23 @@ protected override void OnMouseClick(MouseEventArgs e)
form.ColorChanged += (sender2, args2) => Series.color = form.Color;
form.ShowDialog();
};

var itemType = new ToolStripMenuItem(Highchart.textLegendMenu_Type);

var seriesTypes = Highchart.textLegendMenu_TypeNames;
for (int i = 0; i < seriesTypes.Length; i++)
{
int index = i;
var item = new ToolStripMenuItem(seriesTypes[i]);
item.Click += (s, a) => { Series.type = (SeriesTypes)index; };
itemType.DropDownItems.Add(item);
}

var context = new ContextMenuStrip();
context.Items.Add(itemColor);
context.Items.Add(itemType);
context.Show(null, MousePosition);
break;
}
}

protected override void OnPaint(PaintEventArgs e)
{
var graphics = e.Graphics;

// User original series color or hidden color for icon and use styles for text.
var seriesColor = Series.color;
var textColor = Legend.itemStyle.color;
if (seriesEnabled == false)

if (!Series.visible)
{
seriesColor = Legend.itemHiddenStyle.color;
textColor = seriesColor;
Expand All @@ -80,30 +71,19 @@ protected override void OnPaint(PaintEventArgs e)
if (hovered)
textColor = Legend.itemHoverStyle.color;

switch (Series.type)
{
case SeriesTypes.areaSolid:
case SeriesTypes.areaSolidOutline:
graphics.uwfFillRectangle(seriesColor, 4, 8, 8, 8);
break;
case SeriesTypes.line:
seriesPen.Color = seriesColor;
graphics.DrawLine(seriesPen, 0, 11, 16, 11);
break;
case SeriesTypes.lineSolid:
seriesPen.Color = seriesColor;
graphics.DrawLine(seriesPen, 0, 11, 16, 11);
graphics.uwfDrawImage(ApplicationResources.Images.Circle, seriesColor, 4, 8, 8, 8);
break;
case SeriesTypes.point:
graphics.uwfDrawImage(ApplicationResources.Images.Circle, seriesColor, 4, 8, 8, 8);
break;
}
Series.PaintIcon(graphics, new Rectangle(0, 0, TextLeftMargin, 16));

graphics.uwfDrawString(Text, Font, textColor, 16, 0, Width - 16, Height, ContentAlignment.MiddleCenter);
graphics.uwfDrawString(Text, Font, textColor, TextLeftMargin, 0, Width - TextLeftMargin, Height, ContentAlignment.MiddleCenter);
}
protected override void OnPaintBackground(PaintEventArgs pevent)

protected override void OnPaintBackground(PaintEventArgs e)
{ }

private void TextFromSeries()
{
Text = Series.name != null
? Series.name
: "Series " + (Series.index + 1);
}
}
}
2 changes: 2 additions & 0 deletions Controls/Highcharts/PlotOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@
{
public class PlotOptions
{
public bool linearGradient { get; set; }
public object linearGradientMaterial { get; set; } // Gradient material for areaSolidOutline series type.
}
}
127 changes: 57 additions & 70 deletions Controls/Highcharts/Series.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,24 @@
using System;
using System.Drawing;

public enum SeriesTypes
public abstract class Series : IDisposable
{
None = 0,
internal SeriesCollection collection;
internal readonly Pen pen = new Pen(Color.Transparent);

areaSolid = 1,
areaSolidOutline = 2,
line = 3,
lineSolid = 4,
point = 5,
}
private string _name;

public class Series : IDisposable
{
internal SeriesCollection owner;
internal readonly Pen pen = new Pen(Color.Transparent);
internal bool _needRedraw = true;
protected Series() : this("")
{ }

private string _name;
private bool _linearGradient;
private float _pointInterval;
private SeriesTypes _type;
private bool _visible;

internal Series()
protected Series(string name)
{
color = Color.Gray;
data = new DataCollection(this);
pointInterval = 1;
type = SeriesTypes.line;
visible = true;
}
internal Series(string n) : this()
{
name = n;

this.name = name;
}

public event EventHandler NameChanged;
Expand All @@ -47,18 +31,7 @@ public Color color
set { pen.Color = value; }
}
public DataCollection data { get; private set; }
public bool linearGradient
{
get { return _linearGradient; }
set
{
if (_linearGradient == value)
return;

_linearGradient = value;
_needRedraw = true;
}
}
public int index { get; internal set; }
public string name
{
get { return _name; }
Expand All @@ -76,55 +49,69 @@ public string name
/// For example, if a series contains one value every decade starting from year 0, set pointInterval to 10.
/// Defaults to 1.
/// </summary>
public float pointInterval
public float pointInterval { get; set; }
public object tag { get; set; }
public bool visible { get; set; }
public int yAxis { get; set; }

public void Dispose()
{
get { return _pointInterval; }
set
{
if (_pointInterval == value)
return;
if (pen != null) pen.Dispose();
}

_pointInterval = value;
_needRedraw = true;
}
public override string ToString()
{
return "{name=" + name + "}";
}
public object tag { get; set; }
public SeriesTypes type

internal void Paint(Graphics g, Rectangle clipRectangle)
{
get { return _type; }
set
{
if (_type == value)
return;
if (!visible || data.Count == 0 || pointInterval <= 0) return;

OnPaint(g, clipRectangle);
}

_type = value;
_needRedraw = true;
}
internal void PaintIcon(Graphics g, Rectangle clipRectangle)
{
OnPaintIcon(g, clipRectangle);
}
public bool visible

public double GetValueRange()
{
get { return _visible; }
set
{
if (_visible == value)
return;

_visible = value;
_needRedraw = true;
}
return collection.chart.cachedPlotMax - collection.chart.cachedPlotMin;
}
public int yAxis { get; set; }

public void Dispose()
public float GetXFromIndex(float dataIndex, float xStep, Rectangle clipRectangle)
{
if (pen != null) pen.Dispose();
return (float) Math.Ceiling(clipRectangle.Left + xStep * dataIndex);
}

public float GetXStep()
{
var chartDataAmount = collection.chart.GetSeriesMaximumDataAmount();
if (chartDataAmount < 1)
return collection.chart.cachedPlotWidth / 2f; // Middle point of the plot.

return (float) collection.chart.cachedPlotWidth / (chartDataAmount - 1);
}

public float GetYFromValue(double value, double range, Rectangle clipRectangle)
{
return (float) Math.Ceiling(clipRectangle.Bottom - clipRectangle.Height * GetYModFromValue(value, range));
}

public float GetYModFromValue(double value, double range)
{
return (float) ((value - collection.chart.cachedPlotMin) / range);
}

protected virtual void OnNameChanged(EventArgs e)
{
var handler = NameChanged;
if (handler != null)
handler(this, e);
}
protected abstract void OnPaint(Graphics g, Rectangle clipRectangle);
protected abstract void OnPaintIcon(Graphics g, Rectangle clipRectangle);
}
}
}
56 changes: 56 additions & 0 deletions Controls/Highcharts/SeriesAreaSolid.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
namespace Highcharts
{
using System.Drawing;

public class SeriesAreaSolid : Series
{
public SeriesAreaSolid() : this("")
{ }

public SeriesAreaSolid(string name) : base(name)
{ }

protected override void OnPaint(Graphics g, Rectangle clipRectangle)
{
if (data.Count == 1)
{
SeriesPaint.PaintPoint(this, g, clipRectangle, 0);
return;
}

var valueRange = GetValueRange();
var xStep = GetXStep();
var areaColorAlpha = collection.GetColorAlpha();
var areaColor = Color.FromArgb(areaColorAlpha, color);

var prevValue = data[0];
var prevValueX = GetXFromIndex(0, xStep, clipRectangle);
var prevValueY = GetYFromValue(prevValue, valueRange, clipRectangle);

for (float dataIterator = pointInterval; dataIterator < data.Count; dataIterator += pointInterval)
{
double currentValue = data[(int) dataIterator];

float currentValueX = GetXFromIndex(dataIterator, xStep, clipRectangle);
float currentValueY = GetYFromValue(currentValue, valueRange, clipRectangle);

float width = currentValueX - prevValueX;

g.uwfFillRectangle(areaColor, prevValueX, prevValueY, width, clipRectangle.Bottom - prevValueY);

if (dataIterator + pointInterval >= data.Count)
g.uwfFillRectangle(areaColor, currentValueX, currentValueY, xStep, clipRectangle.Bottom - currentValueY);

prevValueX = currentValueX;
prevValueY = currentValueY;

SeriesPaint.PaintHoveredValueRect(this, g, currentValueX, currentValueY, xStep);
}
}

protected override void OnPaintIcon(Graphics g, Rectangle clipRectangle)
{
g.uwfFillRectangle(color, clipRectangle.Left + 4, clipRectangle.Top + 4, 8, 8);
}
}
}
Loading

0 comments on commit 7bbccab

Please sign in to comment.