20210506のC#に関する記事は7件です。

[C#] oxyplotでグラフを書く2

もくじ https://qiita.com/tera1707/items/4fda73d86eded283ec4f やりたいこと oxyplotでグラフを出した。 そこに、グラフと軸が交わるところに、そこの値がいくらなのか?を表示してやりたくなった。 その実現のためにいろいろ調べたところ、、注釈表示機能(Annotation)が使えそうな気がする。 Annotationの使い方を練習したい。 やったこと 試した限りでは、上のようなことをするときはRectangleAnnotationで、軸とグラフが交わるところにAnnotationを出して、その中身をその点の値にすればよさそう。 →なのでRectangleAnnotationを使うことになりそうだが、いろんなAnnotationを試してみたのでその時のメモを部品取り用に下記に残す。 部品取りコード 注釈表示(線) LineAnnotationを使う。 using OxyPlot; using OxyPlot.Annotations; using OxyPlot.Axes; using System.Collections.ObjectModel; using System.Windows; namespace WpfApp1 { public partial class MainWindow : Window { // OxyPlotのためのモデルとコントローラー public PlotModel Model { get; } = new PlotModel(); public PlotController Controller { get; } = new PlotController(); // 軸の設定 public OxyPlot.Axes.LinearAxis AxisX { get; } = new OxyPlot.Axes.LinearAxis(); public OxyPlot.Axes.LinearAxis AxisY { get; } = new OxyPlot.Axes.LinearAxis(); // データを保存するコレクション public ObservableCollection<DataPoint> Datas { get; private set; } = new ObservableCollection<DataPoint>(); public MainWindow() { InitializeComponent(); InitGraph(); } // グラフの設定 public void InitGraph() { // X軸の設定 AxisX.Position = OxyPlot.Axes.AxisPosition.Bottom; // 軸の位置(topにしたら、目盛りが上にくる) // Y軸の設定 AxisY.Position = OxyPlot.Axes.AxisPosition.Left; // Y軸の位置(Rightにしたら、目盛りが右にくる) // 設定した軸をモデルにセット Model.Title = "グラフのタイトル"; Model.Axes.Add(AxisX); Model.Axes.Add(AxisY); // 線グラフ var LineSeries = new OxyPlot.Series.LineSeries(); LineSeries.Title = "Line"; LineSeries.Color = OxyColor.FromArgb(0xff, 0xff, 0, 0); // 上の線の色 LineSeries.StrokeThickness = 2; // 線の太さ // データを関連付け加 LineSeries.ItemsSource = Datas; // 点を追加 Datas.Add(new DataPoint(1.0, 0.0)); Datas.Add(new DataPoint(5.0, 15.0)); Datas.Add(new DataPoint(9.0, 5.0)); // グラフをモデルに追加 Model.Series.Add(LineSeries); // Annotationを追加 Model.Annotations.Add(new LineAnnotation { StrokeThickness = 5, Slope = 1, Intercept = 1, Text = "Slope=1", TextOrientation = AnnotationTextOrientation.Horizontal }); Model.Annotations.Add(new LineAnnotation { StrokeThickness = 5, Slope = 3, Intercept = 2, MaximumX = 2, Color = OxyColors.Red, Text = "Slope=2", TextOrientation = AnnotationTextOrientation.Vertical }); Model.Annotations.Add(new LineAnnotation { StrokeThickness = 5, Type = LineAnnotationType.Vertical, X = 4, MaximumY = 10, Color = OxyColors.Green, Text = "x=4", TextPadding = 8, TextOrientation = AnnotationTextOrientation.Horizontal }); Model.Annotations.Add(new LineAnnotation { StrokeThickness = 5, Type = LineAnnotationType.Vertical, X = 5, MaximumY = 10, Color = OxyColors.Green, Text = "x=5", TextPadding = 8, TextOrientation = AnnotationTextOrientation.Horizontal }); Model.Annotations.Add(new LineAnnotation { StrokeThickness = 5, Type = LineAnnotationType.Horizontal, Y = 2, MaximumX = 3, Color = OxyColors.Gold, Text = "Horizontal", TextOrientation = AnnotationTextOrientation.Horizontal }); // セットした内容を反映させる Model.InvalidatePlot(true); } } } 注釈(楕円) EllipseAnnotationを使う。 using OxyPlot; using OxyPlot.Annotations; using OxyPlot.Axes; using System.Collections.ObjectModel; using System.Windows; namespace WpfApp1 { public partial class MainWindow : Window { // OxyPlotのためのモデルとコントローラー public PlotModel Model { get; } = new PlotModel(); public PlotController Controller { get; } = new PlotController(); // 軸の設定 public OxyPlot.Axes.LinearAxis AxisX { get; } = new OxyPlot.Axes.LinearAxis(); public OxyPlot.Axes.LinearAxis AxisY { get; } = new OxyPlot.Axes.LinearAxis(); // データを保存するコレクション public ObservableCollection<DataPoint> Datas { get; private set; } = new ObservableCollection<DataPoint>(); public MainWindow() { InitializeComponent(); InitGraph(); } // グラフの設定 public void InitGraph() { // X軸の設定 AxisX.Position = OxyPlot.Axes.AxisPosition.Bottom; // 軸の位置(topにしたら、目盛りが上にくる) // Y軸の設定 AxisY.Position = OxyPlot.Axes.AxisPosition.Left; // Y軸の位置(Rightにしたら、目盛りが右にくる) // 設定した軸をモデルにセット Model.Title = "グラフのタイトル"; Model.Axes.Add(AxisX); Model.Axes.Add(AxisY); // 線グラフ var LineSeries = new OxyPlot.Series.LineSeries(); LineSeries.Title = "Line"; LineSeries.Color = OxyColor.FromArgb(0xff, 0xff, 0, 0); // 上の線の色 LineSeries.StrokeThickness = 2; // 線の太さ // データを関連付け加 LineSeries.ItemsSource = Datas; // 点を追加 Datas.Add(new DataPoint(1.0, 0.0)); Datas.Add(new DataPoint(5.0, 15.0)); Datas.Add(new DataPoint(9.0, 5.0)); // グラフをモデルに追加 Model.Series.Add(LineSeries); // EllipseAnnotation Model.Annotations.Add(new EllipseAnnotation { X = 3, // 中心点X Y = 2, // 中心点Y Text = "あいうえお", TextRotation = 30, // 文字の傾き Width = 4, // 横幅 Height = 3, // 縦幅 Fill = OxyColors.Green, Stroke = OxyColors.Black, StrokeThickness = 2 }); // セットした内容を反映させる Model.InvalidatePlot(true); } } } 注釈(四角) RectangleAnnotationを使う。 using OxyPlot; using OxyPlot.Annotations; using OxyPlot.Axes; using System.Collections.ObjectModel; using System.Windows; namespace WpfApp1 { public partial class MainWindow : Window { // OxyPlotのためのモデルとコントローラー public PlotModel Model { get; } = new PlotModel(); public PlotController Controller { get; } = new PlotController(); // 軸の設定 public OxyPlot.Axes.LinearAxis AxisX { get; } = new OxyPlot.Axes.LinearAxis(); public OxyPlot.Axes.LinearAxis AxisY { get; } = new OxyPlot.Axes.LinearAxis(); // データを保存するコレクション public ObservableCollection<DataPoint> Datas { get; private set; } = new ObservableCollection<DataPoint>(); public MainWindow() { InitializeComponent(); InitGraph(); } // グラフの設定 public void InitGraph() { // X軸の設定 AxisX.Position = OxyPlot.Axes.AxisPosition.Bottom; // 軸の位置(topにしたら、目盛りが上にくる) // Y軸の設定 AxisY.Position = OxyPlot.Axes.AxisPosition.Left; // Y軸の位置(Rightにしたら、目盛りが右にくる) // 設定した軸をモデルにセット Model.Title = "グラフのタイトル"; Model.Axes.Add(AxisX); Model.Axes.Add(AxisY); // 線グラフ var LineSeries = new OxyPlot.Series.LineSeries(); LineSeries.Title = "Line"; LineSeries.Color = OxyColor.FromArgb(0xff, 0xff, 0, 0); // 上の線の色 LineSeries.StrokeThickness = 2; // 線の太さ // データを関連付け加 LineSeries.ItemsSource = Datas; // 点を追加 Datas.Add(new DataPoint(1.0, 0.0)); Datas.Add(new DataPoint(5.0, 15.0)); Datas.Add(new DataPoint(9.0, 5.0)); // グラフをモデルに追加 Model.Series.Add(LineSeries); // RectangleAnnotation Model.Annotations.Add(new RectangleAnnotation { MinimumX = 3, MaximumX = 6, MinimumY = 2, MaximumY = 5, TextRotation = 10, Text = "あいうえお", Fill = OxyColors.Blue, Stroke = OxyColors.Black, StrokeThickness = 2 }); // セットした内容を反映させる Model.InvalidatePlot(true); } } } 注釈(ポリゴン) PolygonAnnotationを使う。 using OxyPlot; using OxyPlot.Annotations; using OxyPlot.Axes; using System.Collections.ObjectModel; using System.Windows; namespace WpfApp1 { public partial class MainWindow : Window { // OxyPlotのためのモデルとコントローラー public PlotModel Model { get; } = new PlotModel(); public PlotController Controller { get; } = new PlotController(); // 軸の設定 public OxyPlot.Axes.LinearAxis AxisX { get; } = new OxyPlot.Axes.LinearAxis(); public OxyPlot.Axes.LinearAxis AxisY { get; } = new OxyPlot.Axes.LinearAxis(); // データを保存するコレクション public ObservableCollection<DataPoint> Datas { get; private set; } = new ObservableCollection<DataPoint>(); public MainWindow() { InitializeComponent(); InitGraph(); } // グラフの設定 public void InitGraph() { // X軸の設定 AxisX.Position = OxyPlot.Axes.AxisPosition.Bottom; // 軸の位置(topにしたら、目盛りが上にくる) // Y軸の設定 AxisY.Position = OxyPlot.Axes.AxisPosition.Left; // Y軸の位置(Rightにしたら、目盛りが右にくる) // 設定した軸をモデルにセット Model.Title = "グラフのタイトル"; Model.Axes.Add(AxisX); Model.Axes.Add(AxisY); // 線グラフ var LineSeries = new OxyPlot.Series.LineSeries(); LineSeries.Title = "Line"; LineSeries.Color = OxyColor.FromArgb(0xff, 0xff, 0, 0); // 上の線の色 LineSeries.StrokeThickness = 2; // 線の太さ // データを関連付け加 LineSeries.ItemsSource = Datas; // 点を追加 Datas.Add(new DataPoint(1.0, 0.0)); Datas.Add(new DataPoint(5.0, 15.0)); Datas.Add(new DataPoint(9.0, 5.0)); // グラフをモデルに追加 Model.Series.Add(LineSeries); // PolygonAnnotation var aaa = new PolygonAnnotation(); aaa.Points.Add(new DataPoint(1, 1)); aaa.Points.Add(new DataPoint(1, 5)); aaa.Points.Add(new DataPoint(5, 5)); aaa.Points.Add(new DataPoint(5, 1)); aaa.Points.Add(new DataPoint(3, 3)); aaa.Text = "polygon"; Model.Annotations.Add(aaa); // セットした内容を反映させる Model.InvalidatePlot(true); } } }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[C#] oxyplotでグラフを書く1

もくじ https://qiita.com/tera1707/items/4fda73d86eded283ec4f やりたいこと WPFで、グラフを表示するアプリをやることになり「oxyplot」というライブラリを使うこととなった。 使い方を練習したい。 ※横軸を時間、縦軸に数値、のようなグラフを扱ったので、そういうグラフのみまずは挙げておく。 (円グラフとかは今回やってないので一旦対象外。) 今回の前提 下記を使用する。 .NET 5 OxyPlot.Wpfの2.0.0 部品取りコード 横軸、縦軸の設定 基本の軸の設定。 <Window x:Class="WpfApp1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp1" xmlns:oxy="http://oxyplot.org/wpf" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800" Name="root"> <Grid> <oxy:PlotView Model="{Binding Model, ElementName=root}" Controller="{Binding Controller, ElementName=root}" /> </Grid> </Window> using OxyPlot; using OxyPlot.Axes; using System.Windows; namespace WpfApp1 { public partial class MainWindow : Window { // OxyPlotのためのモデルとコントローラー public PlotModel Model { get; } = new PlotModel(); public PlotController Controller { get; } = new PlotController(); // 軸の設定 public OxyPlot.Axes.LinearAxis AxisX { get; } = new OxyPlot.Axes.LinearAxis(); public OxyPlot.Axes.LinearAxis AxisY { get; } = new OxyPlot.Axes.LinearAxis(); public MainWindow() { InitializeComponent(); InitGraph(); } // グラフの設定 public void InitGraph() { // X軸の設定 AxisX.Position = OxyPlot.Axes.AxisPosition.Bottom; // 軸の位置(topにしたら、目盛りが上にくる) AxisX.MajorStep = 0.5; // 大きなTickの間隔 AxisX.MajorTickSize = 10; // 大きなTickの長さ AxisX.TickStyle = TickStyle.Crossing; // Tickのスタイル(ナシにもできる) AxisX.MinorStep = 0.1; // 小さなTickの間隔 AxisX.Maximum = 10.0; // 右端のX軸の値 // Y軸の設定 AxisY.Position = OxyPlot.Axes.AxisPosition.Left; // Y軸の位置(Rightにしたら、目盛りが右にくる) AxisY.Minimum = 0.0; // 左端のX軸の値 // 設定した軸をモデルにセット Model.Title = "グラフのタイトル"; Model.Axes.Add(AxisX); Model.Axes.Add(AxisY); // セットした内容を反映させる Model.InvalidatePlot(true); } } } 線グラフ LineSeriesを使う。 using OxyPlot; using OxyPlot.Axes; using System.Windows; namespace WpfApp1 { public partial class MainWindow : Window { // OxyPlotのためのモデルとコントローラー public PlotModel Model { get; } = new PlotModel(); public PlotController Controller { get; } = new PlotController(); // 軸の設定 public OxyPlot.Axes.LinearAxis AxisX { get; } = new OxyPlot.Axes.LinearAxis(); public OxyPlot.Axes.LinearAxis AxisY { get; } = new OxyPlot.Axes.LinearAxis(); public MainWindow() { InitializeComponent(); InitGraph(); } // グラフの設定 public void InitGraph() { // X軸の設定 AxisX.Position = OxyPlot.Axes.AxisPosition.Bottom; // 軸の位置(topにしたら、目盛りが上にくる) // Y軸の設定 AxisY.Position = OxyPlot.Axes.AxisPosition.Left; // Y軸の位置(Rightにしたら、目盛りが右にくる) // 設定した軸をモデルにセット Model.Title = "グラフのタイトル"; Model.Axes.Add(AxisX); Model.Axes.Add(AxisY); // 線グラフ var LineSeries = new OxyPlot.Series.LineSeries(); LineSeries.Title = "Line"; LineSeries.InterpolationAlgorithm = InterpolationAlgorithms.UniformCatmullRomSpline;//グラフの角を丸める LineSeries.Color = OxyColor.FromArgb(0xff, 0xff, 0, 0); // 上の線の色 LineSeries.StrokeThickness = 2; // 線の太さ // 点を追加 LineSeries.Points.Add(new DataPoint(1.0, 10.0)); LineSeries.Points.Add(new DataPoint(5.0, 90.0)); LineSeries.Points.Add(new DataPoint(9.0, 40.0)); // 線グラフをモデルに追加 Model.Series.Add(LineSeries); // セットした内容を反映させる Model.InvalidatePlot(true); } } } 二本線グラフ AreaSeriesを使う。 上の線と下の線の間に色を付けたりできる。 using OxyPlot; using OxyPlot.Axes; using System.Windows; namespace WpfApp1 { public partial class MainWindow : Window { // OxyPlotのためのモデルとコントローラー public PlotModel Model { get; } = new PlotModel(); public PlotController Controller { get; } = new PlotController(); // 軸の設定 public OxyPlot.Axes.LinearAxis AxisX { get; } = new OxyPlot.Axes.LinearAxis(); public OxyPlot.Axes.LinearAxis AxisY { get; } = new OxyPlot.Axes.LinearAxis(); public MainWindow() { InitializeComponent(); InitGraph(); } // グラフの設定 public void InitGraph() { // X軸の設定 AxisX.Position = OxyPlot.Axes.AxisPosition.Bottom; // 軸の位置(topにしたら、目盛りが上にくる) // Y軸の設定 AxisY.Position = OxyPlot.Axes.AxisPosition.Left; // Y軸の位置(Rightにしたら、目盛りが右にくる) // 設定した軸をモデルにセット Model.Title = "グラフのタイトル"; Model.Axes.Add(AxisX); Model.Axes.Add(AxisY); // 二本線グラフ var LineSeries = new OxyPlot.Series.AreaSeries();// Point(上)とPoint2(下)の2つの値をsetしたら、その間に色をつけれる LineSeries.Title = "Line"; LineSeries.InterpolationAlgorithm = InterpolationAlgorithms.UniformCatmullRomSpline;//グラフの角を丸める LineSeries.Color = OxyColor.FromArgb(0xff, 0xff, 0, 0); // 上の線の色 LineSeries.Color2 = OxyColor.FromArgb(0xff, 0x0, 0xff, 0); // 下の線の色 LineSeries.Fill = OxyColor.FromArgb(0x66, 0x0, 0, 0xff); // 塗る色 LineSeries.StrokeThickness = 2; // 線の太さ // 点(上の線)を追加 LineSeries.Points.Add(new DataPoint(1.0, 10.0)); LineSeries.Points.Add(new DataPoint(5.0, 90.0)); LineSeries.Points.Add(new DataPoint(9.0, 40.0)); // 点(下の線)を追加 LineSeries.Points2.Add(new DataPoint(1.0, 5.0)); LineSeries.Points2.Add(new DataPoint(6.0, 80.0)); LineSeries.Points2.Add(new DataPoint(9.0, 20.0)); // 線グラフをモデルに追加 Model.Series.Add(LineSeries); // セットした内容を反映させる Model.InvalidatePlot(true); } } } 棒グラフ LinearBarSeriesを使う。 棒の太さはコードから調整できる。 using OxyPlot; using OxyPlot.Axes; using System.Windows; namespace WpfApp1 { public partial class MainWindow : Window { // OxyPlotのためのモデルとコントローラー public PlotModel Model { get; } = new PlotModel(); public PlotController Controller { get; } = new PlotController(); // 軸の設定 public OxyPlot.Axes.LinearAxis AxisX { get; } = new OxyPlot.Axes.LinearAxis(); public OxyPlot.Axes.LinearAxis AxisY { get; } = new OxyPlot.Axes.LinearAxis(); public MainWindow() { InitializeComponent(); InitGraph(); } // グラフの設定 public void InitGraph() { // X軸の設定 AxisX.Position = OxyPlot.Axes.AxisPosition.Bottom; // 軸の位置(topにしたら、目盛りが上にくる) AxisX.Maximum = 10.0; AxisX.Minimum = 0.0; // Y軸の設定 AxisY.Position = OxyPlot.Axes.AxisPosition.Left; // Y軸の位置(Rightにしたら、目盛りが右にくる) // 設定した軸をモデルにセット Model.Title = "グラフのタイトル"; Model.Axes.Add(AxisX); Model.Axes.Add(AxisY); // 棒グラフ var BarSeries = new OxyPlot.Series.LinearBarSeries(); BarSeries.Title = "LinearBar"; BarSeries.BarWidth = 30; // 点を追加 BarSeries.Points.Add(new DataPoint(1.0, 10.0)); BarSeries.Points.Add(new DataPoint(5.0, 90.0)); BarSeries.Points.Add(new DataPoint(9.0, 40.0)); // グラフをモデルに追加 Model.Series.Add(BarSeries); // セットした内容を反映させる Model.InvalidatePlot(true); } } } 棒グラフの太さメモ グラフを表示している領域の幅はModel.PlotArea.Widthでとることができる。 (上の図だと、X軸の0と表示されているところ~10と表示されているところ、までの長さ) 等間隔に棒グラフを表示させるような場合は、そのWidthと棒の本数で、太さ(barSeries.BarWidth)の値を計算できるかもしれない。 データをObservableCollectionで管理する ObservableCollectionを作って、それをSeriesのItemsSourceに指定する。 using OxyPlot; using OxyPlot.Axes; using System.Collections.ObjectModel; using System.Windows; namespace WpfApp1 { public partial class MainWindow : Window { // OxyPlotのためのモデルとコントローラー public PlotModel Model { get; } = new PlotModel(); public PlotController Controller { get; } = new PlotController(); // 軸の設定 public OxyPlot.Axes.LinearAxis AxisX { get; } = new OxyPlot.Axes.LinearAxis(); public OxyPlot.Axes.LinearAxis AxisY { get; } = new OxyPlot.Axes.LinearAxis(); // データを保存するコレクション public ObservableCollection<DataPoint> Datas { get; private set; } = new ObservableCollection<DataPoint>(); public MainWindow() { InitializeComponent(); InitGraph(); } // グラフの設定 public void InitGraph() { // X軸の設定 AxisX.Position = OxyPlot.Axes.AxisPosition.Bottom; // 軸の位置(topにしたら、目盛りが上にくる) // Y軸の設定 AxisY.Position = OxyPlot.Axes.AxisPosition.Left; // Y軸の位置(Rightにしたら、目盛りが右にくる) // 設定した軸をモデルにセット Model.Title = "グラフのタイトル"; Model.Axes.Add(AxisX); Model.Axes.Add(AxisY); // 線グラフ var LineSeries = new OxyPlot.Series.LineSeries(); LineSeries.Title = "Line"; LineSeries.Color = OxyColor.FromArgb(0xff, 0xff, 0, 0); // 上の線の色 LineSeries.StrokeThickness = 2; // 線の太さ // データを関連付け加 LineSeries.ItemsSource = Datas; // 点を追加 Datas.Add(new DataPoint(1.0, 10.0)); Datas.Add(new DataPoint(5.0, 90.0)); Datas.Add(new DataPoint(9.0, 40.0)); // グラフをモデルに追加 Model.Series.Add(LineSeries); // セットした内容を反映させる Model.InvalidatePlot(true); } } } 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WPF-DataGridのヘッダーへのバインドはちょっと仕掛けが必要

DataGridは要素の宣言のところにアイテムソースを記述する。 ヘッダーをバインドしたい先がDataGridのアイテムソースの下にいない場合、DataContextからのパスを指定しないといけない。 しかし、なぜか普通にはDataContextまで辿れない。この議論は下記サイトにあるが、結論としてDataContextを参照する為のプロキシを用意してリソースディクショナリに入れておかないといけない。 https://stackoverflow.com/questions/7711275/bind-datagrid-column-visibility-mvvm <Grid.Resources> <FrameworkElement x:Key="proxyElement" /> </Grid.Resources> <ContentControl Visibility="Collapsed" Content="{StaticResource proxyElement}" /> <DataGrid ItemsSource="{Binding DataList}" AutoGenerateColumns="False"> ~ 省略 ~ <DataGrid.Columns> <DataGridTemplateColumn Header="{Binding Path=DataContext.Data.Value, Source={StaticResource proxyElement}}"> ~ 省略 ~ </DataGrid.Columns> </DataGrid>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WPF-XPSドキュメントをマージする方法

xpsファイルをマージして一つにする方法。備忘録として 参考記事:https://stackoverflow.com/questions/10672456/merging-xps-documents-make-last-one-duplicate public void DoMerge(List<string> mergedFiles) { // ソースドキュメントの準備 List<XpsDocument> sourceXps = new List<XpsDocument>(); foreach (var f in mergedFiles) { sourceXps.Add(new XpsDocument(f, FileAccess.Read)); } // 出力先 var name = destinationPath; if (File.Exists(name)) { File.Delete(name); } XpsDocument destXps = new XpsDocument(name, System.IO.FileAccess.ReadWrite); // ライター XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(destXps); FixedDocumentSequence seq = new FixedDocumentSequence(); // マージ foreach (XpsDocument doc in sourceXps) { FixedDocumentSequence sourceSeq = doc.GetFixedDocumentSequence(); foreach (DocumentReference dr in sourceSeq.References) { DocumentReference newDr = new DocumentReference(); newDr.Source = dr.Source; (newDr as System.Windows.Markup.IUriContext).BaseUri = (dr as System.Windows.Markup.IUriContext).BaseUri; FixedDocument fd = newDr.GetDocument(true); newDr.SetDocument(fd); seq.References.Add(newDr); } } // 終了処理 writer.Write(seq); destXps.Close(); }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

azure functionでJSONとかHTMLとかを文字列から返す

Azure Functionsの例 ex.cs using System; using System.IO; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.Azure.WebJobs; using Microsoft.Azure.WebJobs.Extensions.Http; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using Newtonsoft.Json; namespace LocalFunctionProj { public static class HttpExample { [FunctionName("HttpExample")] public static async Task<IActionResult> Run( [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, ILogger log) { log.LogInformation("C# HTTP trigger function processed a request."); string name = req.Query["name"]; string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); dynamic data = JsonConvert.DeserializeObject(requestBody); name = name ?? data?.name; return name != null ? (ActionResult)new OkObjectResult($"Hello, {name}") : new BadRequestObjectResult("Please pass a name on the query string or in the request body"); } } } こんな感じでOkObjectResultから何か返すのか、と思ってやっていた。 オブジェクトをJsonに勝手にしてくれたりで便利ではあるが、ファイルからJSON読み込んで、String型を放り込むと、 勝手にtext/plainになったりして困った。 ContentResultを使う つまりこういう感じ。 ex.cs namespace LocalFunctionProj { public static class HttpExample { [FunctionName("HttpExample")] public static async Task<IActionResult> RunAsync( [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req, ILogger log) { log.LogInformation("C# HTTP trigger function processed a request."); string text = System.IO.File.ReadAllTextAsync(@"./some_file.txt").Result; return new ContentResult(){Content = text, ContentType = "application/json"}; } } } ContentResultを使うとContentTypeも指定できるので、JSONだろうがHTMLだろうが何でも返せるようになる。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

2Dキャラクターを動かす原理

【①】sprite(画像データ)を使ってゲームオブジェクト(player)を作成。 【②】playerの座標を設定する。 座標とは、 ゲームオブジェクトがシーンの中心(親がいない場合)、または親(親がいる場合)からの距離のことです。 3つの座標は以下の通りです: Horizontal (x):横方向 Vertical (y) :縦方向 Depth (z):奥行き 今回は2Dゲームなのでzは覚えなくてオッケーです。 player の座標を設定するには: Hierarchy で、Main Camera GameObject を選択します。Inspector では、その位置が 0,0 になっているのがわかりますが、これは Unity の Main Camera GameObject のデフォルトの位置です。(今のところ、z 座標は無視してください)。 x と y の値を 0 に変更します。 これで Main Camera GameObject がシーンの中心に位置するようになります。 Hierarchy で、新しい Ruby GameObject を選択します。 Inspector で、x の値を -2、y の値を 0 に設定します。 これで player は Main Camera と縦方向に並びますが、横方向には左側になります。(グラフの軸を考えるのに役立つかもしれません:マイナスの値はゲームオブジェクトを横軸(horizontal axis)で左に、縦軸(vertical axis)で下に移動させます)。 【③】Update 関数の調整 まずは、playerオブジェクトを動かせるようにします。 void Update() { Vector2 position = transform.position; position.x = position.x + 0.1f; transform.position = position; } 変数とは? 変数とは、コンピューターのメモリの中で名前を付ける場所のことです。後で、その名前を使って、そこに保存されている値を取り出すことができます。棚の上に置かれた箱のようなもので、表に名前が書かれていて、中には値が入っていると考えてください。 Vector2 変数って何? 変数名の前の最初の単語、Vector2 は変数の型です。型は、どのようなデータを格納したいかをコンピュータに伝えるので、コンピューターはメモリの適切な容量を得ることができます。Vector2 は、2 つの数値を格納するデータ型です。横(horizontal)位置に x、縦(vertical)位置に y、奥行き(depth)に z を使用する Inspector の Transform 値を覚えておいてください。この 3 つの数字が座標を形成します。このゲームは 2D なので、z 軸の位置を格納する必要がないので、ここでは Vector2 を使って x と y の位置だけを格納します。 Equals(=記号)について Equals 記号は「右側にあるものを左側にあるものに格納する」ことを意味します。したがって、ここでは、Transform の現在の x と y の位置の値を格納するように位置変数に指示しています。 player の位置の取得 Transform も変数(あなたではなく Unity が作成したもの)で、スクリプトが置かれている GameObject の Transform コンポーネントが含まれています。 transform と position の間のドットを「含む」と考えると、ここでは、Transform 内に「含まれる」位置を取得しています。 まとめ 要約すると、Transform コンポーネントに含まれる position を Vector2 型の変数内に格納しています。これでメモリ内に「position」という名前の場所ができ、そこには GameObject の現在位置のコピーが入っています。 【④】GameObjectの移動 2 行目では、1 行目と同じように、何か別のものに「含まれている」ものにアクセスするためにドットを使っています: position.x = position.x + 0.1f; Vector2 は 2 つの数値であるため、x と y を「含みます」。 ここでは、横位置である x の値にアクセスしています。 ゲームオブジェクトを少し右に移動させるには、x の値に 0.1 を加え、結果を x に戻します。 これでメモリ内の位置変数に 0.1 ユニット右にある x 座標が格納されました(正の値はゲームオブジェクトを右に、負の値は左に移動します)。 【⑤】GameObjectの新しい位置を格納する 3 行目では、その新しい Position を Transform の位置の内側に格納しました: transform.position = position; この行の前は、用紙の一面で数学をするように、コピーを修正していただけでした。新しい結果が得られたので、それを Transform コンポーネントに返して、ゲームオブジェクトを 0.1 ユニット右に移動させることを実際に認識させる必要があります! コンピューターはこの関数を新しいフレームごとに実行するので、オブジェクトは新しいフレームごとに最後のフレームに比べて 0.1 ユニット右に移動します。これにより、ゲームオブジェクトが連続的に右に移動しているような錯覚に陥ります。 超初心者復習用です。これが分からないなら多分ゲーム作れない。勉強頑張るぞ(´・_・`)b
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

C# (.NET Core 5.0) Web API CRUD実装

概要 .NET Core 5.0 Web APIサーバを実装して、MySQL接続&CRUD実装をおこなう。 バージョン Version .NET Core 5.0 MySQL 8.0.22 簡易設計・実装 簡易設計 MySQL テスト用DB testデータベースを作成し、以下の2つのテーブルを作成する。 helloテーブル Field Type Null Key id int NO PRI name varchar(128) NO hello_itemテーブル Field Type Null Key id int NO PRI name varchar(128) NO API I/F Resource path HTTP Method Request Body Response Body /hello GET n/a [{"id": 1, "name": ""}] /hello POST {"id": 1, "name": ""} {"id": 1, "name": ""} /hello/{id} PUT {"name": ""} {"id": 1, "name": ""} /hello/{id} DELETE n/a {"message": "ok"} 設定値の定義 パッケージ MySQLの8系を利用するとEntityFrameworkCoreの5系では未対応のため、3系を利用する。 <Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>net5.0</TargetFramework> <RootNamespace>http_api</RootNamespace> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="5.0.0" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.10" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.10" /> <PackageReference Include="MySql.Data.EntityFrameworkCore" Version="8.0.22" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" /> </ItemGroup> </Project> 接続情報 ※ 本ドキュメントはMySQL接続してCRUDをおこうことが目的のため、Secret情報の考慮はしていません。 appsettings.jsonに接続情報を追加する。 "ConnectionStrings": { "DefaultConnection": "Server=127.0.0.1;Database=test;User=root;Password=root;" } Entityの実装 定義したテーブルのEntityクラスを実装する。 Hello.cs public class Hello { public long Id { get; set; } [Required] [StringLength(100, ErrorMessage = "Name is within 100 length")] public string Name { get; set; } } HelloItem.cs public class HelloItem { public long Id { get; set; } [Required] [StringLength(100, ErrorMessage = "Name is within 100 length")] public string Name { get; set; } } DbContextの実装 Microsoft.EntityFrameworkCoreのDbContextを継承して実装する。 OnModelCreating関数のBuilderでどのEntityがどのテーブルにマッピングするか定義できるので利用する。 Microsoft.EntityFrameworkCore ModelBuilder Class public class MysqlContext : DbContext { public MysqlContext(DbContextOptions<MysqlContext> options) : base(options) { Console.WriteLine("Generated MysqlContext"); } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<HelloItem>().ToTable("hello_item"); modelBuilder.Entity<Hello>().ToTable("hello"); } public DbSet<Hello> Hellos { get; set; } public DbSet<HelloItem> HelloItems { get; set; } } サーバのServiceCollectionの実装 実装したMysqlContextの接続数は1つとして、1つのConnectionを使い回すようにする。 Startup.csのDbContextPoolでMysqlContextをAddする。 public void ConfigureServices(IServiceCollection services) { ... Console.WriteLine(Configuration.GetConnectionString("DefaultConnection")); services.AddDbContextPool<MysqlContext>(opt => opt.UseMySQL(Configuration.GetConnectionString("DefaultConnection"))); ... } Controllerの実装 HelloテーブルのCRUDを実装する。 先ほど実装したMysqlContextをSingletonインスタンスで保持するようにDIする。 MysqlContextのコンストラクタに Generated MysqlContext" とログを入れているので、期待値は一度だけ出力されていれば良い。 public class HelloController : ControllerBase { private readonly MysqlContext _mysqlContext; public HelloController(MysqlContext mysqlContext) { _mysqlContext = mysqlContext; Console.WriteLine("Generated HelloController"); } [HttpGet] public List<Hello> Get() { var list = _mysqlContext.Hellos.ToList(); return list; } [HttpPost] public Hello Post(Hello hello) { _mysqlContext.Hellos.Add(hello); _mysqlContext.SaveChanges(); return hello; } [HttpPut("{id}")] public Hello Put(long id, Hello hello) { hello.Id = id; _mysqlContext.Hellos.Update(hello); _mysqlContext.SaveChanges(); return hello; } [HttpDelete("{id}")] public IDictionary<string, string> Delete(long id) { var hello = new Hello(); hello.Id = id; _mysqlContext.Hellos.Remove(hello); _mysqlContext.SaveChanges(); IDictionary<string, string> map = new Dictionary<string, string>(); map.Add("message", "ok"); return map; } } サーバの起動 実装したAPIサーバを起動する。 バイナリにするまでもないので、runで実行する。 $ dotnet run Building... Server=127.0.0.1;Database=test;User=root;Password=root; info: Microsoft.Hosting.Lifetime[0] Now listening on: http://[::]:8080 info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down. info: Microsoft.Hosting.Lifetime[0] Hosting environment: Development 動作確認 POST クライアントのログ。 $ curl -i -X POST \ -H "Content-Type: application/json" \ -d "{\"name\": \"test_data01\"}" \ http://localhost:8080/hello HTTP/1.1 200 OK Date: Thu, 06 May 2021 04:00:39 GMT Content-Type: application/json; charset=utf-8 Server: Kestrel Transfer-Encoding: chunked {"id":24,"name":"test_data01"} サーバのログ。 サーバ起動後の初回リクエストにおいて、MySQLのSingletonインスタンスが生成されることでMySQL接続までの時間がレイテンシに乗っていることがわかった。サーバ起動時にMySQLのConnectionをはることができないかは調査が必要。 Generated MysqlContext Generated HelloController instance GET クライアントのログ。 $ curl -i -X GET http://localhost:8080/hello HTTP/1.1 200 OK Date: Thu, 06 May 2021 04:03:54 GMT Content-Type: application/json; charset=utf-8 Server: Kestrel Transfer-Encoding: chunked [{"id":1,"name":"string"}, {"id":24,"name":"test_data01"}] サーバのログ。 MysqlContextのログは出力されていないので、使いまわすことができている。 Generated HelloController instance PUT クライアントのログ。 $ curl -i -X PUT \ -H "Content-Type: application/json" \ -d "{\"name\": \"test_data01_updated\"}" http://localhost:8080/hello/24 HTTP/1.1 200 OK Date: Thu, 06 May 2021 04:06:09 GMT Content-Type: application/json; charset=utf-8 Server: Kestrel Transfer-Encoding: chunked {"id":24,"name":"test_data01_updated"} サーバのログ。 Generated HelloController instance DELETE クライアントのログ。 $ curl -i -X DELETE http://localhost:8080/hello/24 HTTP/1.1 200 OK Date: Thu, 06 May 2021 04:07:18 GMT Content-Type: application/json; charset=utf-8 Server: Kestrel Transfer-Encoding: chunked {"message":"ok"} サーバのログ。 Generated HelloController instance 所感 サーバ起動時にMySQLに接続しておきたい。 サーバ起動条件の設定を少し調べて、条件満たさない場合のサーバシャットダウン処理等はまた別ドキュメントでまとめていきたい。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む