c# – Teafiles和茶馆图表库背后的架构?

c# – Teafiles和茶馆图表库背后的架构?,第1张

概述我遇到了一个名为Teafiles.net的开源.Net库,它处理时间序列的存储和检索.专有产品茶馆可以绘制这样的时间序列.我想知道茶馆产品是否也可以作为源代码,无论是开源还是付费许可.我对能够仅加载当前图表视图中可见的数据点以及如何实现类似解决方案的技术感兴趣. 我正在寻找类似的东西,并想知道是否有人遇到过类似的技术,或者知道付费的茶馆许可证是否也有源代码. 我目前正在开发基于 ZedGraph库 我遇到了一个名为Tea@[email protected]的开源.Net库,它处理时间序列的存储和检索.专有产品茶馆可以绘制这样的时间序列.我想知道茶馆产品是否也可以作为源代码,无论是开源还是付费许可.我对能够仅加载当前图表视图中可见的数据点以及如何实现类似解决方案的技术感兴趣.

我正在寻找类似的东西,并想知道是否有人遇到过类似的技术,或者知道付费的茶馆许可证是否也有源代码.

解决方法 我目前正在开发基于 ZedGraph库的趋势解决方案,我正在使用Tea@R_404_6852@s来缓存来自数据库的大量数据.

我不确切知道TeaHouse解决方案背后的技术类型.但我也使用了一种方法来显示一组点,这些点位于来自Tea@R_404_6852@的大量数据的两个日期之间.

ZedGraph库有一个FilteredPointList对象,它执行自动数据点抽取.它包含一个SetBounds方法,允许您选择要显示的日期范围以及要显示的最大点数.通常,它对应于视图的实际宽度.

FilteredPointList (original source code)使用两个包含XY数据的double数组.通过使用Tea@R_404_6852@对象替换数组,将此类调整为Tea@R_404_6852@PointList很容易,将T视为包含DateTime和double属性的结构.

实施不是最佳的,但我是这样开始的.我稍后可能会更新此代码以包含Tea@R_404_6852@的MemoryMapped@R_404_6852@功能.这种方式会快得多.

public class Tea@R_404_6852@PointList : IPointList{    Tea@R_404_6852@<point> tf;    private int _maxPts = -1;    private int _minBoundindex = -1;    private int _maxBoundindex = -1;    struct point    {        public TeaTime.Time x;        public double y;    }    public Tea@R_404_6852@PointList(DateTime[] x,double[] y)    {        tf = Tea@R_404_6852@<point>.Create(Path.GetRandom@R_404_6852@name() + ".tea");        for (var i = 0; i < x.Length; i++)            tf.Write(new point() { x = x[i],y = y[i] });    }    public voID SetBounds(double min,double max,int maxPts)    {        _maxPts = maxPts;        // find the index of the start and end of the bounded range        var xmin = (DateTime)new XDate(min);        var xmax = (DateTime)new XDate(max);        int first = tf.BinarySearch(xmin,item => (DateTime)item.x);        int last = tf.BinarySearch(xmax,item => (DateTime)item.x);        // Make sure the bounded indices are legitimate        // if BinarySearch() doesn't find the value,it returns the bitwise        // complement of the index of the 1st element larger than the sought value        if (first < 0)        {            if (first == -1)                first = 0;            else                first = ~(first + 1);        }        if (last < 0)            last = ~last;        _minBoundindex = first;        _maxBoundindex = last;    }    public int Count    {        get        {            int arraySize = (int)tf.Count;            // Is the filter active?            if (_minBoundindex >= 0 && _maxBoundindex >= 0 && _maxPts > 0)            {                // get the number of points within the filter bounds                int boundSize = _maxBoundindex - _minBoundindex + 1;                // limit the point count to the filter bounds                if (boundSize < arraySize)                    arraySize = boundSize;                // limit the point count to the declared max points                if (arraySize > _maxPts)                    arraySize = _maxPts;            }            return arraySize;        }    }    public PointPair this[int index]    {        get        {            if (_minBoundindex >= 0 && _maxBoundindex >= 0 && _maxPts >= 0)            {                // get number of points in bounded range                int nPts = _maxBoundindex - _minBoundindex + 1;                if (nPts > _maxPts)                {                    // if we're skipPing points,then calculate the new index                    index = _minBoundindex + (int)((double)index * (double)nPts / (double)_maxPts);                }                else                {                    // otherwise,index is just offset by the start of the bounded range                    index += _minBoundindex;                }            }            double xVal,yVal;            if (index >= 0 && index < tf.Count)                xVal = new XDate(tf.Items[index].x);            else                xVal = PointPair.Missing;            if (index >= 0 && index < tf.Count)                yVal = tf.Items[index].y;            else                yVal = PointPair.Missing;            return new PointPair(xVal,yVal,PointPair.Missing,null);        }    }    public object Clone()    {        throw new NotImplementedException(); // I'm lazy...    }    public voID Close()    {        tf.Close();        tf.dispose();        @[email protected](tf.name);    }}

最难的部分是为Tea@R_404_6852@实现BinarySearch,使用DateTime快速搜索记录.我使用反编译器查看了Array.BinarySearch实现,并在下面编写了扩展:

public static int BinarySearch<T,U>(this Tea@R_404_6852@<T> tf,U target,Func<T,U> indexer) where T : struct{    var lo = 0;    var hi = (int)tf.Count - 1;    var comp = Comparer<U>.Default;    while(lo <= hi)    {        var median = lo + (hi - lo >> 1);        var num = comp.Compare(indexer(tf.Items[median]),target);        if (num == 0)            return median;        if (num < 0)            lo = median + 1;        else            hi = median - 1;    }    return ~lo;}

如果ZedGraph不符合您的需求,至少您明白了. FilteredPointList类中使用的抽取算法非常好,可以通过其他方式进行调整以满足您的需求.

总结

以上是内存溢出为你收集整理的c# – Teafiles和茶馆图表库背后的架构?全部内容,希望文章能够帮你解决c# – Teafiles和茶馆图表库背后的架构?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1252737.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存