From 41a19f03b9f72da590f6250f3d01c9fd9ba47031 Mon Sep 17 00:00:00 2001 From: firedef Date: Fri, 22 Jul 2022 01:06:04 +0300 Subject: [PATCH] Add 2D chart data --- SomeChartsUi/src/data/IChart2DData.cs | 176 ++++++++++++++++++++++++++ SomeChartsUi/src/data/IChartData.cs | 7 + 2 files changed, 183 insertions(+) create mode 100644 SomeChartsUi/src/data/IChart2DData.cs diff --git a/SomeChartsUi/src/data/IChart2DData.cs b/SomeChartsUi/src/data/IChart2DData.cs new file mode 100644 index 0000000..cc6b6b1 --- /dev/null +++ b/SomeChartsUi/src/data/IChart2DData.cs @@ -0,0 +1,176 @@ +using MathStuff.vectors; + +namespace SomeChartsUi.data; + +public interface IChart2DManagedData { + public void GetValues(int2 start, int2 count, int downsample, T[] dest); + public T GetValue(int2 i); + public int2 GetLength(); + public int GetHashCode(); +} + +public interface IChart2DData : IChart2DManagedData where T : unmanaged { + public unsafe void GetValues(int2 start, int2 count, int downsample, T* dest); +} + +public class ArrayChart2DManagedData : IChart2DManagedData { + public readonly T[] data; + public readonly int2 length; + + public ArrayChart2DManagedData(T[] data, int2 length) { + this.data = data; + this.length = length; + } + + public void GetValues(int2 start, int2 count, int downsample, T[] dest) { + for (int x = 0; x < count.x; x++) { + int xDestInd = x * count.y; + int xSrcInd = (start.x + (x << downsample)) * count.y; + + for (int y = 0; y < count.y; y++) { + int ySrc = start.y + (y << downsample); + + int indexDest = xDestInd + y; + int indexSrc = xSrcInd + ySrc; + dest[indexDest] = data[indexSrc]; + } + } + } + public T GetValue(int2 i) => data[i.x * length.y + i.y]; + public int2 GetLength() => length; +} + +public class ArrayChart2DData : ArrayChart2DManagedData, IChart2DData where T : unmanaged { + public ArrayChart2DData(T[] data, int2 length) : base(data, length) { } + + public unsafe void GetValues(int2 start, int2 count, int downsample, T* dest) { + for (int x = 0; x < count.x; x++) { + int xSrcInd = (start.x + (x << downsample)) * count.y; + + for (int y = 0; y < count.y; y++) { + int ySrc = start.y + (y << downsample); + + int indexSrc = xSrcInd + ySrc; + *dest++ = data[indexSrc]; + } + } + } +} + +public class CollectionChart2DManagedData : IChart2DManagedData { + public readonly IEnumerable data; + public readonly int2 length; + + public CollectionChart2DManagedData(T[] data, int2 length) { + this.data = data; + this.length = length; + } + + public void GetValues(int2 start, int2 count, int downsample, T[] dest) { + for (int x = 0; x < count.x; x++) { + int xDestInd = x * count.y; + int xSrcInd = (start.x + (x << downsample)) * count.y; + + for (int y = 0; y < count.y; y++) { + int ySrc = start.y + (y << downsample); + + int indexDest = xDestInd + y; + int indexSrc = xSrcInd + ySrc; + dest[indexDest] = data.ElementAt(indexSrc); + } + } + } + + public T GetValue(int2 i) => data.ElementAt(i.x * length.y + i.y); + public int2 GetLength() => length; +} + +public class CollectionChart2DData : CollectionChart2DManagedData, IChart2DData where T : unmanaged { + public CollectionChart2DData(T[] data, int2 length) : base(data, length) { } + + public unsafe void GetValues(int2 start, int2 count, int downsample, T* dest) { + for (int x = 0; x < count.x; x++) { + int xSrcInd = (start.x + (x << downsample)) * count.y; + + for (int y = 0; y < count.y; y++) { + int ySrc = start.y + (y << downsample); + + int indexSrc = xSrcInd + ySrc; + *dest++ = data.ElementAt(indexSrc); + } + } + } +} + +public class FuncChart2DManagedData : IChart2DManagedData { + public readonly Func sample; + public readonly int2 length; + + public FuncChart2DManagedData(Func sample, int2 length) { + this.sample = sample; + this.length = length; + } + + public void GetValues(int2 start, int2 count, int downsample, T[] dest) { + for (int x = 0; x < count.x; x++) { + int xDestInd = x * count.y; + int xSrc= start.x + (x << downsample); + + for (int y = 0; y < count.y; y++) { + int ySrc = start.y + (y << downsample); + + int indexDest = xDestInd + y; + dest[indexDest] = sample(new(xSrc, ySrc)); + } + } + } + + public T GetValue(int2 i) => sample(i); + public int2 GetLength() => length; +} + +public class FuncChart2DData : FuncChart2DManagedData, IChart2DData where T : unmanaged { + public FuncChart2DData(Func sample, int2 length) : base(sample, length) { } + + public unsafe void GetValues(int2 start, int2 count, int downsample, T* dest) { + for (int x = 0; x < count.x; x++) { + int xSrc = start.x + (x << downsample); + + for (int y = 0; y < count.y; y++) { + int ySrc = start.y + (y << downsample); + *dest++ = sample(new(xSrc, ySrc)); + } + } + } +} + + +public class ConstChart2DManagedData : IChart2DManagedData { + public T value; + public int2 length; + + public ConstChart2DManagedData(T value, int2 length) { + this.value = value; + this.length = length; + } + + public ConstChart2DManagedData(T value) { + this.value = value; + length = int2.one; + } + + public void GetValues(int2 start, int2 count, int downsample, T[] dest) { + for (int i = 0; i < count.x * count.y; i++) dest[i] = value; + } + public T GetValue(int2 i) => value; + public int2 GetLength() => length; +} + +public class ConstChart2DData : ConstChart2DManagedData, IChart2DData where T : unmanaged { + public ConstChart2DData(T value, int2 length) : base(value, length) { } + public ConstChart2DData(T value) : base(value) { } + + public unsafe void GetValues(int2 start, int2 count, int downsample, T* dest) { + for (int i = 0; i < count.x * count.y; i++) dest[i] = value; + } +} \ No newline at end of file diff --git a/SomeChartsUi/src/data/IChartData.cs b/SomeChartsUi/src/data/IChartData.cs index 119c8b8..3b2e2c4 100644 --- a/SomeChartsUi/src/data/IChartData.cs +++ b/SomeChartsUi/src/data/IChartData.cs @@ -1,4 +1,5 @@ using MathStuff; +using MathStuff.vectors; using SomeChartsUi.themes.colors; namespace SomeChartsUi.data; @@ -110,6 +111,12 @@ public static class ChartDataExtensions { v.GetValues(start, count, downsample, arr); return arr; } + + public static T[] GetValues(this IChart2DManagedData v, int2 start, int2 count, int downsample) { + T[] arr = new T[count.x * count.y]; + v.GetValues(start, count, downsample, arr); + return arr; + } /// get values using stride /// data source