2012-04-16 39 views
7

Chúng tôi có một tính năng dòng thời gian của phần mềm của chúng tôi. Nó cho thấy các hàng của các đốm màu nhỏ chỉ ra dữ liệu ở các thời điểm khác nhau. Mã là C#, .Net 4 và WPF. Để hiển thị một đốm màu, chúng tôi hiện đang tạo đường viền (cho nó một bàn chải) và thêm nó vào lưới. Lưới này sau đó được thêm vào lưới bố mẹ tạo thành các hàng.Làm thế nào để hiển thị hiệu quả đồ họa trong WPF?

Điều này là tốt khi dòng thời gian hiển thị số lượng nhỏ các đốm màu, nhưng khi dữ liệu rất bận, việc hiển thị chậm, sử dụng mem tăng lên và giao diện người dùng không phản hồi. (Không ngạc nhiên là).

Tôi biết chúng tôi không làm điều này một cách tốt nhất - câu hỏi của tôi là cách tốt nhất để hiển thị đồ họa như thế này trong wpf là gì?

EDIT: Cảm ơn bạn đã trả lời dưới đây - Tôi sẽ điều tra các tùy chọn này. Tuy nhiên, mỗi yêu cầu một số lượng lớn của recoding, và câu hỏi của tôi ở đây là đơn giản hơn; Có một số kiểm soát hoặc hiệu ứng tôi có thể sử dụng để thay thế cho Biên giới có chi phí tài nguyên thấp hơn không?

+0

Bạn không nên tạo các phần tử theo chương trình và thêm chúng vào lưới như thế. Bạn nên tạo một listatemem datatemplate cho các đốm màu của bạn và sau đó liên kết một tập hợp các đốm màu với một listView. – Alain

+0

Sẽ rất khó để cuộn trơn tru theo cách đó, phải không? Tôi sẽ phải thêm tất cả các dữ liệu vào bộ sưu tập (mà sẽ sụp đổ) hoặc tự động repopulate bộ sưu tập, mà có lẽ sẽ không nhìn trơn tru. – Sugrue

Trả lời

4

Để hiển thị dữ liệu như thế này, tôi thực sự thích DynamicDataDisplay. Thành phần này hiện chỉ được duy trì/phát triển cho Silverlight nhưng có một phiên bản mã nguồn mở (trong liên kết) cho WPF thực sự là một thư viện tuyệt vời.

Thư viện sử dụng IObservable bộ sưu tập và hỗ trợ DateTime giá trị trục.

Có loại biểu đồ đánh dấu được tạo sẵn (ví dụ bên dưới).

Bạn có thể sử dụng đánh dấu tùy chỉnh, nó hỗ trợ phóng to và cuộn, nhiều tính năng đẹp khác, v.v. Nó cũng rất nhanh, ngay cả với bộ dữ liệu khá lớn.

Vì bộ dữ liệu là IObservable thành phần biểu đồ phản ứng động với các thay đổi trong tập dữ liệu cơ bản nên biểu đồ của bạn được cập nhật bất kỳ lúc nào tập hợp dữ liệu được cập nhật.

EDIT

Dưới đây là một ví dụ:

sử dụng:

using System.ComponentModel; 
using Microsoft.Research.DynamicDataDisplay; 
using Microsoft.Research.DynamicDataDisplay.Charts; 
using Microsoft.Research.DynamicDataDisplay.DataSources; 
using Microsoft.Research.DynamicDataDisplay.PointMarkers; 

chính:

public Window1() 
    { 
     InitializeComponent(); 
     // 
     const int N = 100; 
     List<double> x = new List<double>(); 
     List<double> y = new List<double>(); 

     DateTimeAxis dtAxis = new DateTimeAxis(); 
     _plotter.HorizontalAxis = dtAxis; 

     Random rand = new Random(); 
     for (int i = 0; i < N; i++) 
     { //generate some random data 
      x.Add(dtAxis.ConvertToDouble(DateTime.Now.AddDays(i))); 
      y.Add(rand.Next(N)); 
     } 

     EnumerableDataSource<double> gX = new EnumerableDataSource<double>(x); 
     EnumerableDataSource<double> gY = new EnumerableDataSource<double>(y); 
     _MarkerGraph.DataSource = new CompositeDataSource(gX,gY); 

     //no scaling - identity mapping 
     gX.XMapping = xx => xx; 
     gY.YMapping = yy => yy; 

     CirclePointMarker mkr = new CirclePointMarker(); 
     mkr.Fill = new SolidColorBrush(Colors.Red); 
     mkr.Pen = new Pen(new SolidColorBrush(Colors.Black),2.0); 
     _MarkerGraph.Marker = mkr; 
    } 

XAML:

<Window x:Class="WpfApplication1.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:d3="clr-namespace:Microsoft.Research.DynamicDataDisplay;assembly=DynamicDataDisplay" 
Title="Window1" Height="481" Width="651"> 
<Grid> 
    <d3:ChartPlotter Name="_plotter"> 
     <d3:MarkerPointsGraph Name="_MarkerGraph"/> 
    </d3:ChartPlotter> 
</Grid> 

Output: Program runs...

Các DateTime trục thang đẹp, điều chỉnh ve cho ngày, tháng, giờ, giây ... bất cứ điều gì là thích hợp. Dễ như ăn bánh!

Nếu bạn sử dụng gói này, tôi cao khuyên bạn nên tải xuống nguồn và thêm nó làm dự án thứ hai cho giải pháp của bạn. Tài liệu này rất kém cho D3 và việc có nguồn trong dự án của bạn là hữu ích để tìm ra cách mọi thứ hoạt động. Nó cũng làm cho nó rất dễ dàng để thêm/mở rộng những thứ nếu bạn cần.Hãy chắc chắn để tham khảo dự án trong giải pháp của bạn nếu bạn làm điều này và không phải là DLL biên dịch.

Cũng lưu ý rằng rất nhiều tài liệu có sẵn và ví dụ trực tuyến được nhắm mục tiêu cho thành phần Silverlight được duy trì và không dành cho thành phần WPF mở. Nhiều thành phần khác nhau giữa hai phiên bản này, do đó bạn phải đào sâu qua thành phần WPF để xem có gì ở đó. Ví dụ trên là dành cho thành phần WP0 v0.3.

+0

Cảm ơn vì điều đó. Thú vị, và tôi có thể sử dụng nó một ngày nào đó. Tôi không muốn phải triệt để triệt để hệ thống hiện tại của chúng tôi mặc dù. Đó là 99% làm việc, tôi chỉ muốn làm cho việc dựng hình thực sự hiệu quả hơn. – Sugrue

+0

@Sugrue Tôi nghĩ rằng để làm cho kết xuất hiệu quả hơn, có thể bạn sẽ cần thay đổi cách tiếp cận của mình. Việc vẽ tất cả các phần tử của bạn vào một canvas duy nhất có thể sẽ cần thiết để có được hiệu suất mong muốn và đó là sự dịch chuyển khỏi phương pháp lưới trong lưới mà bạn đang sử dụng. Miễn là dữ liệu của bạn đã được sắp xếp ra, nó thực sự là rất nhanh chóng để chỉ cần thả một thành phần biểu đồ trong và liên kết nó với nhau. –

+0

@Sugrue: đã thêm một ví dụ để cho biết điều này dễ dàng như thế nào! Thực sự, thành phần này chỉ là một công cụ hiển thị dữ liệu rất hiệu quả, chính xác là vấn đề bạn đang cố giải quyết. Ngoài một vài dòng để chuyển đổi dữ liệu, nó phải là giải pháp chủ yếu thả xuống. –

3

Nếu bạn muốn vẽ nhiều hình ảnh thay đổi liên tục, cách nhanh nhất mà WPF cung cấp là ghi đè OnRender và vẽ vào DrawingContext.

Nếu hình ảnh chủ yếu là tĩnh, nhưng đôi khi có thể thay đổi, cách nhanh nhất là tạo DrawingVisual cho mỗi cái, sau đó có thể được sửa đổi nếu cần.

Chi tiết khác trong this question, bài viết được liên kết và câu trả lời.

+0

Cảm ơn, tôi sẽ điều tra nó. – Sugrue

Các vấn đề liên quan