2013-06-14 41 views
5

Tôi bắt gặp một thư viện mã nguồn mở có tên là Teafiles.net, nơi xử lý lưu trữ và truy xuất chuỗi thời gian. Sản phẩm độc quyền, phòng trà, có thể xếp hạng chuỗi thời gian như vậy. Tôi tự hỏi liệu sản phẩm của quán trà cũng có sẵn như là mã nguồn, cho dù nguồn mở hay giấy phép trả tiền. Tôi quan tâm đến công nghệ đằng sau việc có thể chỉ tải các datapoint được hiển thị trên chế độ xem biểu đồ hiện tại và cách triển khai giải pháp tương tự.Kiến trúc đằng sau Teafiles và thư viện biểu đồ quán trà?

Tôi đang tìm cách triển khai điều gì đó tương tự và tự hỏi liệu có ai đã bắt gặp công nghệ tương tự hay biết liệu giấy phép phòng trà có trả tiền cũng có sẵn với mã nguồn hay không.

Trả lời

3

Tôi hiện đang phát triển một giải pháp xu hướng dựa trên thư viện ZedGraph và tôi đang sử dụng TeaFiles để lưu trữ một lượng lớn dữ liệu đến từ cơ sở dữ liệu.

Tôi không biết chính xác loại công nghệ nào đứng sau giải pháp TeaHouse. Nhưng tôi cũng đã sử dụng một cách tiếp cận để hiển thị một tập hợp các điểm nằm giữa hai ngày từ một lượng lớn dữ liệu đến từ TeaFile.

Thư viện ZedGraph có đối tượng FilteredPointList thực hiện tự động decimation điểm dữ liệu. Nó bao gồm một phương thức SetBounds cho phép bạn chọn phạm vi ngày bạn muốn hiển thị và số lượng điểm tối đa bạn muốn hiển thị. Thông thường, nó tương ứng với chiều rộng thực tế của chế độ xem của bạn.

FilteredPointList(original source code) sử dụng hai mảng đôi chứa dữ liệu XY. Dễ dàng điều chỉnh lớp này thành TeaFilePointList bằng cách thay thế mảng bằng đối tượng TeaFile, xem T là cấu trúc chứa DateTime và thuộc tính double.

Việc triển khai không tối ưu, nhưng tôi đã bắt đầu theo cách này. Tôi có thể cập nhật mã này sau để bao gồm tính năng MemoryMappedFile của TeaFile. Nó sẽ nhanh hơn nhiều theo cách này.

public class TeaFilePointList : IPointList 
{ 
    TeaFile<point> tf; 

    private int _maxPts = -1; 
    private int _minBoundIndex = -1; 
    private int _maxBoundIndex = -1; 

    struct point 
    { 
     public TeaTime.Time x; 
     public double y; 
    } 

    public TeaFilePointList(DateTime[] x, double[] y) 
    { 
     tf = TeaFile<point>.Create(Path.GetRandomFileName() + ".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(); 
     File.Delete(tf.Name); 
    } 
} 

Phần khó nhất là triển khai Tìm kiếm nhị phân cho TeaFile để tìm kiếm nhanh hồ sơ bằng DateTime. Tôi nhìn thi Array.BinarySearch bằng cách sử dụng một decompiler, và tôi đã viết phần mở rộng dưới đây:

public static int BinarySearch<T, U>(this TeaFile<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; 
} 

Nếu ZedGraph không phù hợp với nhu cầu của bạn, ít nhất bạn có ý tưởng. Thuật toán decimation được sử dụng trong lớp FilteredPointList khá tốt và có thể được điều chỉnh cho phù hợp với nhu cầu của bạn theo một cách khác.

+3

Cảm ơn bạn Laurent, tôi đã kết thúc với giải pháp tương tự. Không có sẵn mã nguồn như là một phần của sản phẩm TeaHouse là một không-đi cho tôi. Tôi đã kết thúc bằng cách sử dụng cấu trúc tệp nhị phân của riêng mình và điều chỉnh nó để đưa ra một giải pháp biểu đồ chuyên nghiệp (SciChart). Theo cách đó, tôi kiểm soát hầu hết mã nguồn. –