2016-11-03 14 views
1

私は非常に汎用性の高いチャート作成用の非常に汎用的な再利用可能なユーザーコントロールを作成するプロジェクトを行いたいと思っていました。私はチャートを濡らすことを望んでいましたが、地球上の誰もがWPF ToolkitまたはSparrow Chartsを使って無料のサードパーティ製のチャートを作成しています。誰かがチャート作成を行うために完全に隔離されたベースの方法を拘束したり構築したりする経験がありますか?私はキャンバスでポリラインをバインドして渡すようなものから始めるために何か一般的なことをすることを考えていました。他の誰かがこの道を歩いていて、イベントの募集と潜在的な依存特性の拘束力を設定するためのヒントを持っていれば、私は不思議でした。私はMVVMアーキテクチャのアプローチに従うことを考えていましたが、ViewModelへのバインディングの大部分を行っていましたが、最終的にプロパティを公開して更新したいと考えていました。サードパーティのライブラリを使用せずに2Dチャートを作成するには、WPFが優先されますか?

コンセプトでこれと同様に

(ユーザーコントロールが別のビューまたはMainFormを中に埋め込む):

<StackPanel> 
    <Label x:Name="lblCustomDataGridHeader" Content="{Binding TestText}" HorizontalAlignment="Center" FontSize="24"/> 
    <Canvas Height="260" Width="300"> 
     <Polyline Points="{Binding Points}" Stroke="LightBlue" StrokeThickness="4" /> 
    </Canvas> 
    </StackPanel> 

のViewModelのプロパティ:

public ViewModel() 
{ 
    TestText = "Line Chart"; 
    //Obviously some converter or something else here to accept one or many lines 
    Points = "0,260 10,250 20,245 40,200 50,250 80, 200, 140,100"; 
} 

public string TestText { 
    get { return _testText; } 
    set 
    { 
     _testText = value; 
     OnPropertyChanged(NameOf(TestText)); 
    } 
} 

private string _points; 
public string Points { 
    get { return _points; } 
    set 
    { 
     _points = value; 
     OnPropertyChanged(NameOf(Points)); 
    } 
} 

EDIT LATER

私もやって試してみましたクラスにバインドするテンプレート付きコントロール

<Style TargetType="{x:Type local:LineGraph}"> 
    <Setter Property="Template"> 
    <Setter.Value> 
     <ControlTemplate TargetType="{x:Type local:LineGraph}"> 
     <Grid> 
      <Grid.RowDefinitions> 
      <RowDefinition Height="Auto"/> 
      <RowDefinition Height="*"/> 
      </Grid.RowDefinitions> 
      <TextBlock Grid.Row="0" Text="Hello" FontSize="20"/> 
      <Border Grid.Row="1" BorderThickness="1" BorderBrush="Black" CornerRadius="15" Margin="10"> 
      <Canvas Margin="10" x:Name="PART_Canvas"> 
       <Canvas.LayoutTransform> 
       <ScaleTransform ScaleX="1" ScaleY="-1" /> 
       </Canvas.LayoutTransform> 
      </Canvas> 
      </Border> 
     </Grid> 
     </ControlTemplate> 
    </Setter.Value> 
    </Setter> 
</Style> 

クラス(これのいくつかは、私は他の誰かの実装を使用していたとしてクリーンアップする必要があり、それがVB.NETにあったと換算):ViewModelにで

public class LineGraph : Control, INotifyPropertyChanged 
{ 

    //CONSTRUCTOR 
    static LineGraph() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(LineGraph), new FrameworkPropertyMetadata(typeof(LineGraph))); 
    } 

    public event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged; 

    public void OnPropertyChanged(string info) 
    { 
     if (PropertyChanged != null) { 
      PropertyChanged(this, new PropertyChangedEventArgs(info)); 
     } 
    } 


    public static readonly DependencyProperty _Trends = DependencyProperty.RegisterReadOnly("Trends", typeof(Collection<ChartDataSegment>), typeof(LineGraph), new PropertyMetadata(new Collection<ChartDataSegment>())).DependencyProperty; 
    public Collection<ChartDataSegment> Trends { 
     get { return (Collection<ChartDataSegment>)GetValue(_Trends); } 
    } 

    public override void OnApplyTemplate() 
    { 
     base.OnApplyTemplate(); 
     dynamic canvas = GetTemplateChild("PART_Canvas") as Canvas; 
     if (canvas != null && Trends != null) { 
      foreach (void trend_loopVariable in Trends) { 
       trend = trend_loopVariable; 
       DrawTrend(canvas, trend); 
      } 
     } 
    } 

    private void DrawTrend(Canvas drawingCanvas, ChartDataSegment Trend) 
    { 
     dynamic t = Trend as ChartDataSegment; 
     if (t != null && t.Points != null) { 
      for (int i = 1; i <= t.Points.Count - 1; i++) { 
       dynamic toDraw = new Line { 
        X1 = t.Points(i - 1).X, 
        Y1 = t.Points(i - 1).Y, 
        X2 = t.Points(i).X, 
        Y2 = t.Points(i).Y, 
        StrokeThickness = 2, 
        Stroke = t.LineColor 
       }; 
       drawingCanvas.Children.Add(toDraw); 
      } 
     } 
    } 

} 

public class ChartDataSegment : DependencyObject 
{ 


    public static readonly DependencyProperty _LineColor = DependencyProperty.Register("LineColor", typeof(Brush), typeof(ChartDataSegment), new PropertyMetadata(null)); 
    public Brush LineColor { 
     get { return (Brush)GetValue(_LineColor); } 
     set { SetValue(_LineColor, value); } 
    } 

    public static readonly DependencyProperty _LineThickness = DependencyProperty.Register("LineThickness", typeof(Thickness), typeof(ChartDataSegment), new PropertyMetadata(null)); 
    public Thickness PointThickness { 
     get { return (Thickness)GetValue(_LineThickness); } 
     set { SetValue(_LineThickness, value); } 
    } 

    public static readonly DependencyProperty _Points = DependencyProperty.Register("Points", typeof(ObservableCollection<Point>), typeof(ChartDataSegment), new UIPropertyMetadata(null)); 
    public ObservableCollection<Point> Points { 
     get { return (ObservableCollection<Point>)GetValue(_Points); } 
     set { SetValue(_Points, value); } 
    } 
} 

と実装:

var lineTrend1 = new ChartDataSegment { 
    LineColor = Brushes.Blue, 
    Points = new ObservableCollection<Point>({ 
     new Point { 
      X = 1, 
      Y = 1 
     }, 
     new Point { 
      X = 50, 
      Y = 20 
     }, 
     new Point { 
      X = 100, 
      Y = 100 
     }, 
     new Point { 
      X = 150, 
      Y = 130 
     } 
    }) 
}; 

var ctrl = new LineGraph(); 
ctrl.Trends.Add(lineTrend1); 

私の最大の懸念は、これが達成できるわけではなく、必要に応じてオブジェクトをインラインで更新することです。 EG:破棄して呼び出す必要のある静的なチャートをホストするのではなく、折れ線グラフを更新するための非同期呼び出し。

Stack Overflowが問題の詳細を知りたがっている直観的な問題は、「コレクション(ライン)のコレクション(ポイント)を簡単に挿入でき、依存プロパティ付きのキャンバスを使って自己更新できますか?

+2

これは本当に話題にではありません。はい/いいえ質問になることは本当に難しいです。 UIの作業を一度もやっていないのなら、**難しい**です。だから、もしあなたが少なくとも数ヶ月*それに専念したいのでなければ、サードパーティ製のライブラリを入手してください。離婚は高価なのと同じ理由で彼らは高価です。 – Will

+0

これは: "私の直接の質問は、スタックオーバーフローが問題の詳細なので、"コレクション(ポイント)のコレクション(ライン)を簡単に挿入でき、セルフアップデートするために依存プロパティを持つキャンバスを使用できますか?どの部分が具体的ではないのですか? – djangojazz

+0

それは卑劣ではなく、ただの基準を持っています。私はそれを下から読んだが、「はい」または「いいえ」と答えた場合、あなたには何が良いのだろうか?そして、私が正しいことをどうやって知っていますか?地獄、私は自分の経験から、あなたが聞いたことをするのは簡単だと言うことができますが、それは制御設計の表面を傷つけるだけです。しかし、もう一度、多分私は吸うだけで、あなたはそれが非常に簡単に見つけるでしょう。これがあなたの質問がトピックではない理由です。その部分をボーリングすることは、そうでないことはありません。 – Will

答えて

3

私は必要なグラフを作成しました。あなたのように、私はサードパーティのライブラリを使用しませんでした。私はそれを探していたと私は、このプロジェクトのプロジェクトが見つかりました:

enter image description here

ソースがダウンロードできます、そしてそれは、サード使用していません:彼らは次のようなグラフを作る http://www.codeproject.com/Articles/446888/Custom-Spider-or-Radar-Chart-Control

を彼らがしているすべてのことを簡単に見直すことができます。グラフを作成するには

は行うことが必要なだけである:あなたはすでにそれが結合特性だ見ることができるように

<WpfCharts:SpiderChart Title="Spider chart" 
        Lines="{Binding Lines}" 
        Axis="{Binding Axes}" 
        Minimum="0" 
        Maximum="1" 
        Ticks="5" 
        ShowLegend="True" 
        LegendLocation="BottomRight" 
        LegendBackgroundColor="Aquamarine"/> 

。 MVVMプロジェクトで既に使用しています。

あなたが探している方法であなたを導くことを願っています。

+0

これは私が探していたものです。ありがとう!彼らは、私が2番目の事例で考えていたのと同じことをしました。スタイルを設定してから、依存関係をトリガーします。そして、それは図書館に含まれており、それはさらに優れています。 – djangojazz

+0

私はそれを助けてうれしいです。 –

0

はいあなたは、コードのその部分を拡大したいときは、「チャート」の一種、実際の作業が開始されたシンプルなものをグラフ化するコントロールを作成することができ、その後、あなたはいくつかの点で、あなたの要件をそれを覚えておくことができますあなたが始まったデザインはもう良くなりません。個人的には、これが良い練習になると思います。しかし、受け取るデータは変更され、誰もPointのコレクションを渡すことは望ましくないことを覚えておく必要があります。私は個人的に整数または浮動小数点数のコレクションを渡したいと思います。かなり私の想像をくすぐる。この時点で、あなたは頭を掻きして、そのすべてのロジックをもう一度実装する別の方法を考え始めるでしょう。それは私の友人です。私はあなたにこの仕事を取ってもらうことをおろそうとしているわけではありませんが、あなたの出発点は近い将来変わるはずです。
BTW聞いてみましょう彼は彼が何を話しているのか知っています。

+0

「コーディングは難しく、サードパーティを使用してください」以外の回答は得られませんでした。チャートを作成してバインドすることができれば(私のチャートはうまく機能しています)、APIや他の手段から簡単に自己更新できるかどうかを確認するには、さらにいくつかの手順が必要です。私はそれが面白い問題だと知っていますが、それが私が尋ねた理由です。私はちょっと頭を悩ましています。「あまりにも漠然としています!!!あなたは建築の選択肢やテクニック、さらに2 + 2 =について質問していますか?」私はそれをすべて行う方法を知っていたなら私はここにいません。私は自分自身を更新するためにちょうど興味があった始めた。 – djangojazz

+0

私はそれもどちらかとは分かりませんが、これはあまりにも漠然とした熱狂が、「このようにして、これを考えていました、あなたはどう思いますか?拒否されています。私は他のユーザーからそれを去ったり、言ったりしています。 – djangojazz

+0

私はそれのためのガイドラインが面白いと思うので、これは: 'プログラマーがよく使うソフトウェアツール。 は、ソフトウェア開発に特有の実用的で問題のない問題です。私の質問:あなたは簡単にコレクション(ポイント)のコレクション(ライン)を挿入し、依存するプロパティを持つキャンバスを使って自己更新できますか?」この疑問は明らかに明確ではありません:http://stackoverflow.com/質問/ 332365/sql-injection-the-the-bobby-tables-xkcd-comic-work/332367#332367 – djangojazz

-1

私はMVFパターンのWPFでチャートを作成するためにWPF Toolkitを使用し、提案しました。ビューで

:ViewModelにで

<chartingToolkit:Chart> 
    <chartingToolkit:Chart.Axes> 
     <chartingToolkit:LinearAxis Orientation="Y" SeriesHost="{x:Null}" Minimum="0"/> 
    </chartingToolkit:Chart.Axes> 
    <chartingToolkit:ColumnSeries DependentValueBinding="{Binding Value, Mode=OneWay}" IndependentValueBinding="{Binding Key, Mode=OneWay}" ItemsSource="{Binding ChartData}"/> 
</chartingToolkit:Chart> 

public ObservableCollection<KeyValuePair<string,int> ChartData; 

private void DrawChart() 
{ 
    //do not forget initialize ChartData in constructor 
    ChartData.Add(new KeyValuePair<string,int>("type1",10)); 
    ChartData.Add(new KeyValuePair<string,int>("type2",20)); 
    ChartData.Add(new KeyValuePair<string,int>("type3",30)); 
} 
+0

基本的な質問: 'WPFには第三者のライブラリがなくても2Dチャートを作成するための方法がありますか?' 2番目と3番目の文章:「私は自分の足をチャートに濡らすことを望んでいましたが、地球上の誰もがWPF ToolkitやSparrow Chartsを使って無料のサードパーティ製のチャートを作成しています。誰かがチャート作成を行うために完全に隔離されたベースの方法を拘束するか構築する経験を持っていますか? – djangojazz

+0

私はあなたが3番目のライブラリツールを使わないことに夢中になっていると思っています。「誰かがバインディングの経験を持っていますか? – user7131252

+0

私は読書が私の強迫観念ではないとは思わない。私はあなたにそれを完全に読まなかったという質問をしました。私のせいじゃない。 – djangojazz

関連する問題