Power BI Desktop 1月アップデートの内容
Power BI DesktopのUpdateがされたので、試してみました。
どうやら、今年から月末アップデートではなく、
月初めくらいのアップデートになったみたいです。
レポート
レポート部分でのアップデートは4つです。
- 列見出しのワードラップ
- ブランク時の条件付き書式
- 最も古い日付や最近の日付での集計
- モバイルレポートのGA
列見出しのワードラップ
テーブルコントロールの列見出しにワードラップ機能が追加されました。
機能を有効にしておくと、勝手に折り返してくれます。
機能を無効 | 機能を有効 |
---|---|
ワードラップ機能を有効にするには、書式タブ -> 列見出し -> 右端での折り返し です。
ブランク時の条件付き書式
テーブルコントロールや、マトリックスコントロールの行列内で
空白の値がある場合に、条件付き書式が設定できるようになりました。
設定なし | 設定あり |
---|---|
機能を使うには、フィールド -> 設定するフィールド(列)の▽ -> 条件付き書式 です。
条件付き書式のダイアログの右側で、空白の値に対する書式を設定できます。
最も古い日付や最近の日付での集計
日付型の最近や最遅で集計が選択できるようになりました。RFM分析がしやすくなったかな?
(テキスト型も選択できるようになってますが、どんな時にうれしい機能なのかさっぱり?)
こんな感じです。
機能を使うには、フィールド -> 設定するフィールド(列)の▽ です。
データコネクタ
1個増えて、1個は機能追加ですね。
- Visual Studio Team Service
- SQL Server フェールオーバー サポート
Visual Studio Team Service
これ、実際に使う人がいるから増えたんでしょうが、
VSTS上で、クエリから作成する可視化機能で十分な気がしなくもないです。
タスクやバックログの確認を、Power BI側でするシーンが分からないです。
選択すると、まだ開発中ですと。
続行すると、アカウントやプロジェクトの情報を求められます。
SQL Server フェールオーバー サポート
あれ? 今まで無かったってことは、
フェールオーバーするとデータ更新できなくなったんでしょうか。
接続のダイアログを確認すると、一番下にチェックボックスが増えています。
クエリ編集
SQL Databaseに対して、DirectQueryモードでレポート作っていると
クエリ編集しないんですよね。
機能追加は1個です。
- Nested Listの展開
Nested Listの展開
これのコメント欄で質問している方がいたので助かりました。
powerbi.microsoft.com
ODataに対して使う時はあるけど、なかなか出会わないなぁ。
1つのフィールドで、こんな形式になっているデータです。
{ {1,{0,1}}, {2,{0,1,2}}, {3,{0,1,2,3} }
上の形式のデータを、クエリ編集の列見出しから、簡単に展開できるようになりました。
展開を選びます。
そうすると、リストの最初のデータが展開されます。
さらに、特定の文字で、リスト内の値を抽出できます。
カンマで抽出します。
こんな感じですね。
新年明け初回のアップデートは、量があまり無かったですね。
Power BI Desktop 11月アップデートの内容
Power BI DesktopのUpdateがされたので、試してみました。
powerbi.microsoft.com
レポート
レポート部分での機能追加は、6つあります。
順に追ってみていきます。
ドロップダウンスライサ
スライサにカテゴリ値をマッピングした時のUIは、チェックボックスだけでしたが、
ドロップダウンが追加されました。これでレポートがすっきりします。
スライサの右上で、ドロップダウンを選ぶと、UIが変わります。
こんな感じで使えます。(左がチェックボックスのスライサ/右がドロップダウンのスライサ)
階層軸
ドリルダウンするときに、上の階層のラベルを表示する機能が追加されました。
今までは、下の階層にドリルダウンすると、上の階層が何だっけ?な状態でした。
(左から右にドリルダウンしています。お菓子カテゴリに含まれる商品です。)
設定をONにすると、上の階層のラベルを表示できるようになりました。
設定する箇所は、書式 ⇒ 軸 ⇒ ラベルの結合です。
ここをオフにします。(初期値はオンのままです。)
日付を軸に設定した時は、何月の何日だっけ?って迷子にならなくなりました。
マトリックスの条件付き書式
マットリックス内の値に基づいた、条件付き書式が設定できるようになりました。
Excelからの置き換えを意識すると、だいたい登場する表です。
値にマッピングしている項目を選んで、条件付き書式を選びます。
この画面で設定します。
デフォルトですと、最小値から最大値にかけて色が変わっていくように設定しますが、
特定の値から特定の値にかけても設定ができます。
画面内の左右逆方向という不思議な日本語のチェックボックスですが、
英語のUIですと、Divergingとなっていました。
チェックをつけることで、中央値が置かれるので、
中央値から、「最小値に向けて」と「最大値に向けて」を分けて設定します。
設定すると、こんな見映えになります。
条件付き書式を削除するときは、設定するときと同じように、
値にマッピングしている項目を選んで、条件付き書式の削除を選びます。
表と行列の列の書式
表の列ごとに、フォントの色と背景色が指定できるようになりました。
また、それぞれの列で、ヘッダー行や合計行に適用するか否かを指定できます。
こんな表です。(さっきはマトリックスを使っていましたが、これは表を使っています。)
設定は書式 ⇒ 列の書式設定 です。ここで列ごとに設定をしていきます。
こんな感じで、列ごとにフォントの色と背景色が指定できて、
さらに、ヘッダ行と合計行に適用するかどうかも指定できます。
軸ラベルとタイトルの色の設定
ほとんどのグラフで、軸ラベルの文字色とタイトルの文字色が別々に指定できる
ようになりました。
(色の設定よりかは、文字を大きくしたいんだけど、、、)
こんな感じです。
設定は、書式 ⇒ 軸です。
分析系
アップデートは、3つです。
- クラスタリング(プレビュー)
- 予測
- グループの作成UI
クラスタリング
散布図で自動的にクラスタを見つけてくれます。
プレビュー機能ですので、オプションで設定をしておきます。
(クラスタリングのところです。)
クラスタリング機能を有効にしたら、散布図の右上の…のところです。
ここでクラスターの自動検索が行えます。
選ぶと、クラスターという味気ないダイアログが開きます。
クラスターの数が指定できますが、ここは自動で進みます。
そうすると、このようにクラスタリングされます。
フィールドリストには、クラスタリングされたフィールドが追加されています。
このフィールドの…から、クラスタリングの編集が行えます。
また、クラスターという味気ないダイアログが開きます。
ここで、クラスターの数を変更して、再度クラスタリングが行えます。
クラスターの数を3個に変更してみました。
3軸以上でクラスタリングを行いたい場合は、表を基に行うことができます。
こんな表ですね。
同じように右上の…から、クラスターの自動検索を選びます。
同じようにクラスターのフィールドが追加されます。
新しく追加されたクラスターのフィールドは、さらに分析を進める上で役立ちます。
Power BI Blogでは箱ひげ図のCustom Visualを使っています。
こんな感じですね。クラスタリングされたカテゴリごとの馬力の箱ひげ図です。
R: Motor Trend Car Road Testsデータセットを使っています。
データコネクタ
アップデートは、4つです。
- SparkへのDirect Query(プレビュー)
- ODataフィードのパフォーマンス向上
- バイナリ結合の強化
- Azure Analysis Services
SparkへのDirect Query
Sparkに対して、Direct Queryモードが追加されました。
ただ、プレビュー機能なので、Power BI Serviceからは使用できません。
ODataフィードのパフォーマンス向上
どうやら、ODataの扱いを変えたため、Power BI側に取得するデータ量が少なくなり、
トランザクションが効率的になりました。と。
う~ん、ODataフィードを使っているレポートがあるんだけど、効果を体感できるくらいなのかな。
Power BI Desktop更新してしまったら、以前がどんなだったかも分からない。
バイナリ結合の強化
このリリース前は、各ファイルを1つのテーブルに結合する時に、
ヘッダ行があるテキストファイルかCSVファイルしか対象としてなかったのかな。
ExcelファイルとテキストファイルとCSVファイルの結合を試してみましたが、
エラーになってできませんでした。。。
テキストファイルとCSVファイルの結合はできたんですが、、、
う~む。
クエリ編集
アップデートは、3つです。
- function Authoring
- %データタイプ
- クエリの依存関係ダイアログ
function Authoring
バイナリ結合時に自動的に作られるクエリやクエリから作成される関数ですが、
それらの間で依存関係が作成されるので、クエリを実行すると、関数も更新されるっぽい。
。。。Excelファイルを含めたバイナリ結合上手くいかなかったからなぁ。
このあたりは、あとで調べなおさないとダメだな。
%データタイプ
パーセンテージがデータタイプに増えました。それだけ。
クエリの依存関係ダイアログ
依存関係のダイアログが、最大化と戻すに対応しました。
クエリまわりってどれくらい使われているんですかね?
DirectQueryモードでレポート作るほうが多いと、あまり使わないという。。。
最後に
Power BI Serviceに発行しました。
発行して、タグ作るときに気付いたのですが、
いつのまにかpbixファイルがダウンロードできるようになってました。
とりあえず、ローカルのpbixファイル捨てても大丈夫かな。
Power BI API データプッシュを試してみた
Power BIを扱う機会が増えてきているので、APIを試してみました。
Power BI ダッシュボードにデータをプッシュする | Microsoft Power BI
上記のガイド通りに進めていけば何も問題ないですが、
あまりにも香ばしい箇所があり、きっと誰も使ってないよ!
と思われる部分があったので、ガイドとは変えてみました。
特にこのへんです。サンプルでもそれなりに書いてほしいな
このへんを、Newtonsoft.Jsonを使ったり、HttpClientを使うように変えています。
ガイドと同様に、下記の手順ですすめます。
アプリをAzureADに登録する
手順 1: アプリを Azure AD に登録する | Microsoft Power BI
AzureADによる認証機能を使うために行います。PowerBIに限ったことではないですね。
ガイドでは、Power BI専用のAzureAD登録サイトから行うように誘導されますが、
AzureADに直接登録しても同じです。慣れているならこっちの方が早い。
リダイレクトURLは、ガイドでも指定されている、
この値をhttps://login.live.com/oauth20_desktop.srf入力します。
クライアントIDと、リダイレクトURLは認証する際に使うため、
メモ帳などに貼りつけておきます。
アクセス許可は、これだけ付けておけば良いです。
AzureADへの登録が終わりましたら、アプリケーションを作っていきます。
認証アクセストークンを取得する
手順 2: 認証アクセス トークンを取得する | Microsoft Power BI
ここでの注意は、Microsoft.IdentityModel.Clients.ActiveDirectoryのバージョンです。
ガイドと同じバージョンでないと、認証に使うメソッドがありません。
ガイド通りパッケージマネージャコンソールに、下記コマンドを入力します。
Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory -Version 2.21.301221612
Microsoft.IdentityModel.Clients.ActiveDirectoryパッケージをインストールしたら、
認証用のクラスを作成していきます。
役割はアクセストークンを取得するだけです。
using System; using System.Configuration; using Microsoft.IdentityModel.Clients.ActiveDirectory; namespace PBIApiDataPushExample { public class AccessToken { /// <summary> /// OAuth2 authority Uri /// </summary> private const string AuthorityUrl = "https://login.windows.net/common/oauth2/authorize"; /// <summary> /// Resource Uri for Power BI API /// </summary> private const string ResourceUrl = "https://analysis.windows.net/powerbi/api"; /// <summary> /// AzureADから発行されたクライアントID /// </summary> private static readonly string ClientID = ConfigurationManager.AppSettings["ClientID"]; /// <summary> /// AzureADに指定したRedirectUrl /// </summary> private const string RedirectUrl = "https://login.live.com/oauth20_desktop.srf"; /// <summary> /// アクセストークンを取得します /// </summary> public static string GetToken() { var authContext = new AuthenticationContext(AuthorityUrl); return authContext.AcquireToken(ResourceUrl, ClientID, new Uri(RedirectUrl)).AccessToken; } } }
ガイドがメソッドで作成しているのに対して、ここでは、クラスにしているだけです。
AcquireToken()が、Microsoft.IdentityModel.Clients.ActiveDirectoryの
最新のバージョンだと無くなっています。
試しに実行してみます。
コンソールアプリケーションで作っていますので、
Mainメソッドから作成したGetoToken()を呼びます。
namespace PBIApiDataPushExample { class Program { /// <summary> /// PBIApiDataPushExampleアプリのエンドポイント /// </summary> /// <param name="args">コマンドライン引数</param> static void Main(string[] args) { string token = AccessToken.GetToken(); } } }
認証用のダイアログが表示されますので、
アプリを登録したAzureADで利用している組織アカウントを選びます。
認証が成功すると、アクセストークンが取得できます。
次はデータセットを作ります。
データセットを作成する
手順 3: Power BI ダッシュボードにデータセットを作成する | Microsoft Power BI
このへんから、リテラルでJSON書いてたり、リクエストをストリームに書き出したりと
香ばしくなってきますので、微妙に対応していきます。
まず、JSONを扱うので、
Nugetパッケージの管理からNewtonsoft.Jsonをインストールします。
Newtonsoft.Jsonに含まれる
JsonConvert.SerializeObject()を使って、オブジェクトからJSON文字列を作成するために、
良い感じにクラス分けする必要があります。
Power BIのデータセットは、下記図のような構成です
同じ構成にするために、下記クラスに分けました。
- データセットクラス
- テーブルクラス
- 列クラス
- 列のデータ列挙型(列挙型から文字列に変換する拡張クラス付き)
VSのコードマップで見ると、こんな感じです。
3クラス+1列挙型+列挙型の拡張クラスにしています。
まずデータセットクラス
using System.Collections.Generic; using Newtonsoft.Json; namespace PBIApiDataPushExample { /// <summary> /// PowerBIデータセットを表します /// </summary> public class PBIDataset { /// <summary> /// データセット名 /// </summary> [JsonProperty("name")] public string Name { get; set; } /// <summary> /// テーブルリスト /// </summary> [JsonProperty("tables")] public List<PBITable> Tables { get; set; } /// <summary> /// PowerBIDatasetオブジェクトを生成します /// </summary> /// <param name="name">データセット名</param> /// <returns>PowerBIDatasetオブジェクト</returns> public static PBIDataset Create(string name) { return new PBIDataset() { Name = name, Tables = new List<PBITable>() }; } } }
テーブルクラス
using System.Collections.Generic; using Newtonsoft.Json; namespace PBIApiDataPushExample { /// <summary> /// PowerBIのテーブルを表します /// </summary> public class PBITable { /// <summary> /// テーブル名 /// </summary> [JsonProperty("name")] public string Name { get; set; } /// <summary> /// 列リスト /// </summary> [JsonProperty("columns")] public List<PBIColumn> Columns { get; set; } /// <summary> /// PowerBITableオブジェクトを生成します /// </summary> /// <param name="name">テーブル名</param> /// <returns>PowerBITableオブジェクト</returns> public static PBITable Create(string name) { return new PBITable() { Name = name, Columns = new List<PBIColumn>() }; } } }
列クラス
using Newtonsoft.Json; namespace PBIApiDataPushExample { /// <summary> /// PowerBIの列を表します /// </summary> public class PBIColumn { /// <summary> /// 名称 /// </summary> [JsonProperty(PropertyName = "name", Order = 1)] public string Name { get; set; } /// <summary> /// 型 /// </summary> /// <remarks> /// JSONにする時は、無視します。 /// </remarks> [JsonIgnore] public PBIColumnDataTypes PBIDataType { private get; set; } /// <summary> /// 型文字列 /// </summary> /// <remarks> /// 設定は、PBIDataTypeプロパティを使います /// JSONにする時は、このプロパティを使います /// </remarks> [JsonProperty(PropertyName = "dataType", Order = 2)] public string PBIDataTypeString { get { return this.PBIDataType.ToDataTypeString(); } } /// <summary> /// PowerBIColumnオブジェクトを生成します /// </summary> /// <param name="name">名称</param> /// <param name="dataType">データ型</param> /// <returns>PBIApiDataPushExample</returns> public static PBIColumn Create(string name, PBIColumnDataTypes dataType) { return new PBIColumn() { Name = name, PBIDataType = dataType }; } } }
列のデータ列挙型と、列挙型の拡張クラス
using System; using System.Collections.Generic; namespace PBIApiDataPushExample { /// <summary> /// APIでサポートされるデータ型を列挙しています。 /// </summary> /// <remarks> /// https://powerbi.microsoft.com/ja-jp/documentation/powerbi-developer-walkthrough-push-data/ /// </remarks> public enum PBIColumnDataTypes { PBI_Int64, PBI_Double, PBI_Bool, PBI_Datetime, PBI_String, } /// <summary> /// PBIColumnDataTypes列挙型の拡張機能を提供します /// </summary> public static class PBIColumnDataTypesExtensions { /// <summary> /// 列挙型と型文字列の対応 /// </summary> private readonly static Dictionary<PBIColumnDataTypes, string> _PBIColumnDataTypeString = new Dictionary<PBIColumnDataTypes, string>() { { PBIColumnDataTypes.PBI_Int64, "Int64" }, { PBIColumnDataTypes.PBI_Double, "Double" }, { PBIColumnDataTypes.PBI_String, "string" }, { PBIColumnDataTypes.PBI_Bool, "bool" }, { PBIColumnDataTypes.PBI_Datetime, "DateTime" }, }; /// <summary> /// 列挙値と型文字列に変換します /// </summary> /// <param name="candidate">対象</param> /// <returns>型文字列</returns> public static string ToDataTypeString(this PBIColumnDataTypes candidate) { if (!_PBIColumnDataTypeString.ContainsKey(candidate)) { throw new ArgumentException("型リストに未登録の型を指定しています。"); } return _PBIColumnDataTypeString[candidate]; } } }
試しに、データセットオブジェクトを作って、JSON文字列にしてみます。
using System; using Newtonsoft.Json; namespace PBIApiDataPushExample { class Program { /// <summary> /// PBIApiDataPushExampleアプリのエンドポイント /// </summary> /// <param name="args">コマンドライン引数</param> static void Main(string[] args) { string token = AccessToken.GetToken(); // テーブルオブジェクトを作って、 var pbi_table = PBITable.Create("テーブル"); // テーブルオブジェクトに列オブジェクトを追加していきます pbi_table.Columns.Add(PBIColumn.Create("名前", PBIColumnDataTypes.PBI_String)); pbi_table.Columns.Add(PBIColumn.Create("日時", PBIColumnDataTypes.PBI_Datetime)); // データセットオブジェクトを作って、 var pbi_dataset = PBIDataset.Create("データセット"); // テーブルオブジェクトを追加しています pbi_dataset.Tables.Add(pbi_table); // データセットオブジェクトをJSON文字列に変換します string jsonString = JsonConvert.SerializeObject(pbi_dataset); Console.WriteLine(jsonString); } } }
データセットオブジェクトからJSON文字列に変換できたので、
Power BIのAPIに送信してみます。
ガイドでは、リクエストストリームに書き込んでましたが、HttpClientを使います。
パッケージマネージャコンソールを開いて、下記サイトのコマンドを入力してください。
www.nuget.org
データセットクラスに、ApiへJson文字列をPostするメソッドを追加します。
/// <summary> /// Apiへ送信します /// </summary> /// <param name="token">トークン</param> /// <returns>レスポンス</returns> public HttpResponseMessage SendApi(string token) { using (var httpClient = new HttpClient()) { var request = new HttpRequestMessage(HttpMethod.Post, PBIDatasetApiUrl); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); request.Content = new StringContent(JsonConvert.SerializeObject(this), Encoding.UTF8, "application/json"); return httpClient.SendAsync(request).Result; } }
試してみます。先ほどMainメソッドで作成したpbi_datasetオブジェクトの
SendApiメソッドを呼びます
using System; //using Newtonsoft.Json; namespace PBIApiDataPushExample { class Program { /// <summary> /// PBIApiDataPushExampleアプリのエンドポイント /// </summary> /// <param name="args">コマンドライン引数</param> static void Main(string[] args) { string token = AccessToken.GetToken(); // テーブルオブジェクトを作って、 var pbi_table = PBITable.Create("テーブル"); // テーブルオブジェクトに列オブジェクトを追加していきます pbi_table.Columns.Add(PBIColumn.Create("名前", PBIColumnDataTypes.PBI_String)); pbi_table.Columns.Add(PBIColumn.Create("日時", PBIColumnDataTypes.PBI_Datetime)); // データセットオブジェクトを作って、 var pbi_dataset = PBIDataset.Create("データセット"); // テーブルオブジェクトを追加しています pbi_dataset.Tables.Add(pbi_table); // 作ったメソッドを呼びます var response = pbi_dataset.SendApi(token); Console.WriteLine(response.StatusCode); //// データセットオブジェクトをJSON文字列に変換します //string jsonString = JsonConvert.SerializeObject(pbi_dataset); //Console.WriteLine(jsonString); } } }
まずは、アプリケーションを実行します。成功したようです。
Power BI Serviceを確認します。指定した通りに、作成されていました。
データセット | テーブル、カラム |
---|---|
行を追加するデータセットを取得する
手順 4: Power BI テーブルに行を追加するためにデータセットを取得する | Microsoft Power BI
ここもガイドには香ばしさがあふれています。
特に、ここですね。Odata形式でvalue句に入ってくるのは理解できますが、
絶対1番目にないでしょ!
//Get the first id datasetId = results["value"][0]["id"];
というわけで、レスポンスを見ると、IDとNameがあるみたいです。
IDとNameがあるのは分かりましたが、POST時とGET時で
エンティティが違うのって、どうなんでしょうね。
しょうがないので、GET時用のクラスを作成しました。
public class PBIDatasetsGetMethodOnly { [JsonProperty("value")] public PBIDatasetGetMethodOnly[] Values { get; set; } } public class PBIDatasetGetMethodOnly { [JsonProperty("name")] public string Name { get; set; } [JsonProperty("id")] public string ID { get; set; } }
データセットクラスには、IDプロパティを追加します。
[JsonIgnore] public string ID { get; private set; }
ID取得用のメソッドを追加します。
/// <summary> /// IDを読み込みます /// </summary> /// <param name="token">トークン</param> public void LoadId(string token) { using (var httpClient = new HttpClient()) { var request = new HttpRequestMessage(HttpMethod.Get, PBIDatasetApiUrl); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("appication/json")); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); var response = httpClient.SendAsync(request).Result; var results = JsonConvert.DeserializeObject<PBIDatasetsGetMethodOnly>(response.Content.ReadAsStringAsync().Result); this.ID = (from d in results.Values where d.Name == this.Name select d).FirstOrDefault().ID; } }
試してみますが、何個もデータセット作成されるのは嫌なので、
データセットを作成するメソッド部分はコメントにしておきます。
/// <summary> /// PBIApiDataPushExampleアプリのエンドポイント /// </summary> /// <param name="args">コマンドライン引数</param> static void Main(string[] args) { string token = AccessToken.GetToken(); // テーブルオブジェクトを作って、 var pbi_table = PBITable.Create("テーブル"); // テーブルオブジェクトに列オブジェクトを追加していきます pbi_table.Columns.Add(PBIColumn.Create("名前", PBIColumnDataTypes.PBI_String)); pbi_table.Columns.Add(PBIColumn.Create("日時", PBIColumnDataTypes.PBI_Datetime)); // データセットオブジェクトを作って、 var pbi_dataset = PBIDataset.Create("データセット"); // テーブルオブジェクトを追加しています pbi_dataset.Tables.Add(pbi_table); // 作ったメソッドを呼びます //var response = pbi_dataset.SendApi(token); //Console.WriteLine(response.StatusCode); // IDを取得します pbi_dataset.LoadId(token); Console.WriteLine(pbi_dataset.ID); //// データセットオブジェクトをJSON文字列に変換します //string jsonString = JsonConvert.SerializeObject(pbi_dataset); //Console.WriteLine(jsonString); } }
無事データセットのIDが取れました。
テーブルに行を追加する
手順 5: Power BI テーブルに行を追加する | Microsoft Power BI
ようやくデータを追加するとこまで来ました。
ガイドでは、ここも香ばしいので、
HttpClientを使ったり、オブジェクトからJSON文字列を作るように変えます。
新しいクラスを2個追加します。
作成したデータセットに沿った行クラスと、行を束ねるクラスです。
今までに作成したクラスには、なんの関連もありません。
クラスの内容がこちら。
using System; using System.Collections.Generic; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using Newtonsoft.Json; namespace PBIApiDataPushExample { /// <summary> /// 作成したデータセットの行群 /// </summary> public class ExampleDatasetRows { /// <summary> /// 行群 /// </summary> [JsonProperty("rows")] public List<ExampleDatasetRow> Rows { get; set; } /// <summary> /// データセットID /// </summary> [JsonIgnore] public string DataSetID { get; private set; } /// <summary> /// テーブル名 /// </summary> [JsonIgnore] public string TableName { get; private set; } /// <summary> /// 作ったデータセットの行群オブジェクトを生成します /// </summary> /// <param name="datasetId">データセットID</param> /// <param name="tableName">テーブル名</param> /// <returns>作ったデータセットの行群オブジェクト</returns> public static ExampleDatasetRows Create(string datasetId, string tableName) { return new ExampleDatasetRows() { DataSetID = datasetId, TableName = tableName, Rows = new List<ExampleDatasetRow>() }; } /// <summary> /// データを追加します /// </summary> /// <param name="token">トークン</param> /// <returns>Apiコール結果</returns> public HttpResponseMessage AddData(string token) { string powerBIApiAddRowsUrl = String.Format("https://api.powerbi.com/v1.0/myorg/datasets/{0}/tables/{1}/rows", this.DataSetID, this.TableName); using (var httpClient = new HttpClient()) { var request = new HttpRequestMessage(HttpMethod.Post, powerBIApiAddRowsUrl); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); request.Content = new StringContent(JsonConvert.SerializeObject(this), Encoding.UTF8, "application/json"); return httpClient.SendAsync(request).Result; } } } /// <summary> /// 作成したデータセットの行 /// </summary> public class ExampleDatasetRow { [JsonProperty("名前")] public string Name { get; set; } [JsonProperty("日時")] public DateTime AddDate { get; set; } } }
Mainメソッドに処理を追加して、試してみます。
/// <summary> /// PBIApiDataPushExampleアプリのエンドポイント /// </summary> /// <param name="args">コマンドライン引数</param> static void Main(string[] args) { string token = AccessToken.GetToken(); // テーブルオブジェクトを作って、 var pbi_table = PBITable.Create("テーブル"); // テーブルオブジェクトに列オブジェクトを追加していきます pbi_table.Columns.Add(PBIColumn.Create("名前", PBIColumnDataTypes.PBI_String)); pbi_table.Columns.Add(PBIColumn.Create("日時", PBIColumnDataTypes.PBI_Datetime)); // データセットオブジェクトを作って、 var pbi_dataset = PBIDataset.Create("データセット"); // テーブルオブジェクトを追加しています pbi_dataset.Tables.Add(pbi_table); //// データセットオブジェクトをJSON文字列に変換します //string jsonString = JsonConvert.SerializeObject(pbi_dataset); //Console.WriteLine(jsonString); //// 作ったメソッドを呼びます //var response = pbi_dataset.SendApi(token); //Console.WriteLine(response.StatusCode); // IDを取得します pbi_dataset.LoadId(token); //Console.WriteLine(pbi_dataset.ID); // 追加するデータを用意します var dataRow = ExampleDatasetRows.Create(pbi_dataset.ID, pbi_table.Name); for(int i = 0; i < 30; i++) { if(i % 5 ==0 ) { dataRow.Rows.Add(new ExampleDatasetRow() { Name = "サンプル1", AddDate = DateTime.Now }); } else { dataRow.Rows.Add(new ExampleDatasetRow() { Name = "サンプル2", AddDate = DateTime.Now.AddDays(-i) }); } } // データを追加します var response = dataRow.AddData(token); Console.WriteLine(response); }
成功しました。
Power BI Service側でデータがあるか確認します。
ちゃんとデータが登録されていました。
作れることは分かったので、API経由で作ったデータセットと
Power BI Desktopでレポートと共にアップしたデータセットと
比較してみないとですね。
作ったクラスはこちらで全部です。
(ちょっと上にある図と同じです。Main部分は除いています。)
データセットクラスだけは最終形を載せていないので載せておきます。
それ以外のクラスは、最後に出てるとこから取ればOKです。
using System.Collections.Generic; using Newtonsoft.Json; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Linq; namespace PBIApiDataPushExample { /// <summary> /// PowerBIデータセットを表します /// </summary> public class PBIDataset { /// <summary> /// データセットApiUrl /// </summary> private const string PBIDatasetApiUrl = "https://api.powerbi.com/v1.0/myorg/datasets"; /// <summary> /// データセット名 /// </summary> [JsonProperty("name")] public string Name { get; set; } /// <summary> /// テーブルリスト /// </summary> [JsonProperty("tables")] public List<PBITable> Tables { get; set; } [JsonIgnore] public string ID { get; private set; } /// <summary> /// PowerBIDatasetオブジェクトを生成します /// </summary> /// <param name="name">データセット名</param> /// <returns>PowerBIDatasetオブジェクト</returns> public static PBIDataset Create(string name) { return new PBIDataset() { Name = name, Tables = new List<PBITable>() }; } /// <summary> /// Apiへ送信します /// </summary> /// <param name="token">トークン</param> /// <returns>レスポンス</returns> public HttpResponseMessage SendApi(string token) { using (var httpClient = new HttpClient()) { var request = new HttpRequestMessage(HttpMethod.Post, PBIDatasetApiUrl); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); request.Content = new StringContent(JsonConvert.SerializeObject(this), Encoding.UTF8, "application/json"); return httpClient.SendAsync(request).Result; } } /// <summary> /// IDを読み込みます /// </summary> /// <param name="token">トークン</param> public void LoadId(string token) { using (var httpClient = new HttpClient()) { var request = new HttpRequestMessage(HttpMethod.Get, PBIDatasetApiUrl); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("appication/json")); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); var response = httpClient.SendAsync(request).Result; var results = JsonConvert.DeserializeObject<PBIDatasetsGetMethodOnly>(response.Content.ReadAsStringAsync().Result); this.ID = (from d in results.Values where d.Name == this.Name select d).FirstOrDefault().ID; } } } public class PBIDatasetsGetMethodOnly { [JsonProperty("value")] public PBIDatasetGetMethodOnly[] Values { get; set; } } public class PBIDatasetGetMethodOnly { [JsonProperty("name")] public string Name { get; set; } [JsonProperty("id")] public string ID { get; set; } } }
Power BI Desktop 10月アップデートの内容-3
この記事の続きです。
mukkujohn.hatenablog.com
接続先
3つ増えました。
1つ目は、Dynamics 365 for Financials。
今まで、業務アプリのスクラッチ開発が主だったので、
Dynamics CRMとか触れたことないんだよなー。しかもfor Financialsって。。。
とりあえず、接続してみます。オンラインサービス部分にあります。
プレビュー段階だから、ほにゃららと。
OData URLを入れろと。
この先は、接続先もないし、データ構造も分からないなので、
ここまでで。
2つ目は、OLEDB。
これ需要あるのかな?
あらかた、Microsoftのサービスへは接続先が既に整っているし。。。
その他部分にありますね。
接続文字列には、UidやPwdを入れるなと。
この後にダイアログが出るから、そこで入れてね。と。
3つ目は、MixPanel。
知らなかったのですが、Webサイトの解析ツールのようです。
mixpanel.com
オンラインサービス部分にあります。
プレビュー段階なので、ほにゃらら。
APIキーとパスワードですね。
関数呼び出しのテーブルパラメータのサポート
新しいクエリ作成時に、テーブル関数が使えるようになったみたいです。
新しいクエリ作成するための入り口は2か所あります。
1つは、データの取得 → 空のクエリ
もう1つは、
クエリエディターのクエリ部分で右クリック → 新しいクエリ → 空のクエリ
空のクエリを作成時に、数式バー(?)に関数を入力しますが、
大文字小文字を間違えないように!
Table.Transposeと正しく入力しましょう。
Table.Transpose()は、テーブルを転置します。
対象のテーブルを選択します。ここでは、カラム名は省略しておきます。理由は後述。
そして呼び出し!
新しくテーブルが作成されます。
そしてこのクエリですが、カスタム関数の呼び出しでも使う事ができます。
とまぁ、こんな機能なのですが、
先ほどカラム名を省略した部分に大きな落とし穴がありました。
新しいテーブルの数式バーを見ると、nullになっている部分があります。
ここですが、列名をリスト形式で指定することができます。
カラム名を指定するところに戻ります。
リスト形式で指定すれば良いので、こんな形で指定しますよね?
呼び出すとこうなります。えぇぇぇ
おい!
リストを囲むな!ダブルクォーテをエスケープするな!と
ならば、
えい!
もう何も言うまい。。。
セッションID
ヘルプ出すときに、この情報を付与しろってことですかね。
ファイル → ヘルプ → バージョン情報です。
この画面のSessionIDのとこです。
ようやく10/31に出たアップデートの追いかけが終わりました。
しばらくは、Rと戯れたいですね。
Power BI Desktop 10月アップデートの内容-2
この記事の続きです。
mukkujohn.hatenablog.com
データポイントの除外
グラフ上のデータを選択して、除外することができるようになりました。
下のグラフは、R: Motor Trend Car Road Testsデータセットを使っています。
馬力と1ガロンあたり何マイル走れるかの散布図です。
このグラフ上のデータポイントを選んで、右クリックです。
含めないを選択すると、グラフから除外されます。
除外したデータはフィルターで確認できます。
Rのカスタムビジュアル
ディシジョンツリーと折れ線のForecast範囲がついているカスタムを使ってみました。
驚きなのが、スライサーや他のグラフと連動するところ。
まずはディシジョンツリー。よくあるTitanicのデータです。
R: Survival of passengers on the Titanicと違うとこが年齢に数値が入っているくらい。
スライサーでmaleを選択します。
Gender=male部分だけになった!
もうね。。。なんだろうね。驚きしかないです。
次にForecast範囲付きの折れ線。
国連加盟国(全加盟国ではないけど)の出生率かな。(UN birth rate)
マップのバブルを選択します。
日本のバブルを選んでみました。
これまた、マップのバブルと連動して動きます。
最後にPower BI Serviceに発行してみました。
カスタムビジュアルは、Power BI Service上では動作していますが、
パブリックアクセスにすると、動作しないみたいですね。残念。
Power BI Service上でのカスタムビジュアル
(画像ですが、、、)
パブリックアクセス版
→にページ移動して、9ページ目と10ページ目にカスタムビジュアルを配置していますが、、、
カスタムビジュアルのサンプルをダウンロードして
クエリの編集を見てみたところ、、、。
t-jacobm…
次回は、データ接続先とクエリ編集部分ですかね。
Power BI Desktop 10月アップデートの内容-1
10月31日に発表されてましたので、試してみました。
powerbi.microsoft.com
(デモとかで使う準備があったので、更新するの控えてました。)
日付型のスライサー
日付型に設定したフィールドを、スライサーにマッピングする事で使えます。
スライサー | データ型 |
---|---|
期間や、~以降、~以前で指定する事ができます。
- 11/1~11/5
- 11/2~
- ~11/4
11/2~11/4の期間を指定してます。
11/2以降を指定してます。
グリッド線(プレビュー)
ページにグリッド線を表示させる事ができます。
グラフを配置する際の手助けですね。
こちらは、編集しているpbixファイル内の全てのページに有効になります。
設定はこちらから。
プレビュー機能ですので、オプションで有効にする必要があります。
有効にするためには、「ファイル」→「オプションと設定」→「オプション」と進み、
「プレビュー機能」→「グリッド線とグリッドにスナップ」をチェックします。
データラベル
データラベルの表示位置が変更できるようになりました。
積上棒グラフです。方向は指定できず、位置の指定になります。
積上棒グラフ | データラベルのプロパティ |
---|---|
集合棒グラフです。方向と位置の両方が指定できます。
集合棒グラフ | データラベルのプロパティ(方向) | データラベルのプロパティ(位置) |
---|---|---|
マップグラフ
マップグラフの書式で、バブルサイズを変更できます。
バブルが小さくて微妙な時に使えますね。
0% | 50% | 100% |
---|---|---|
ズームインのオンオフが切り替えられるようになりました。
オフを指定すると、離れた地域を選択しても、ズームインしません。
沖縄県のみを選択中 | 沖縄県と北海道を選択中 |
---|---|
グループ
グループが、グラフ上から作成することができるようになりました。
すごい便利な機能です。
この都道府県ごとの面積(㎢)のグラフをベースに作成していきます。
データ | マッピング |
---|---|
グループを作成するためには、グラフ上で右クリックして、グループを選択します。
グループを選択すると、自動でグルーピングされます。
北海道とそれ以外でグループが作成されています。
フィールドリストや、グラフの凡例にも
作成されたグループが設定されています。
データ | マッピング |
---|---|
自動で作成されたグループを編集するには、
フィールドを選択するか、凡例にマッピングされているグループを選択し、
グループの編集を選択します。
グループの編集画面が開きます。
地域ごとに分けてみました。
日本の地域 - Wikipedia
作ったグループが良くなかったですね。もっと自由に作ればよかった・・・
ただ、作ったグループフィールドは、使いまわしができます。
スライサーや、軸にマッピングしてみました。
ビン
ビン詰めですね。ggplot2を使って、ヒストグラムを作成した時と同じ
R: Motor Trend Car Road Testsデータを使っていきます。
mukkujohn.hatenablog.com
上段のグラフは、mpgごとのデータの個数です。
下段のグラフは、データポイントを10個ごとにビン詰したデータの個数です。
ビン詰めのフィールドの作成方法はグループの作成方法と同じです。
フィールドリストから、ビン詰めするフィールドを選択して、グループを選択します。
ビンのサイズと、ビン詰めされたフィールドの名前を入力します。
Top N フィルター
フィルターに新しい種類が増えました。
「~の上位10だけ」とか「~の下位5だけ」の見せ方しますよね。
こちらの3つのグラフは、TopNフィルターを指定しています。
左 | 中 | 右 |
---|---|---|
指定なし |
次回は、データポイントの除外やRのカスタムビジュアルを
扱います。
Power BIの軸や凡例の並び順を調べてみた-2
Power BI Desktop
過去記事*1にて、コメントを頂き、
並び順が指定できそうです。。
この記事は、並び順を指定して、実際に確認できるまでの記録です。
ちなみに、コメントで誘導されたBlogはこちらです。コメントくれた方もこちらの方?
blogs.msdn.microsoft.com
誘導されたBlogにて記載されていることを試してから、
過去記事のデータで試してみたいと思います。
カレンダーテーブル
必要ですよね。以前、開発していた業務システムでも当然作っていました。
こんなんだったかな。
年 | 年月 | 月 | 日 | 年月日 | 曜日番号 | 曜日 | 営業日フラグ |
---|---|---|---|---|---|---|---|
2016 | 201610 | 10 | 30 | 20161030 | 1 | 日 | 1 |
2016 | 201610 | 10 | 31 | 20161031 | 2 | 月 | 0 |
2016 | 201611 | 11 | 1 | 20161101 | 3 | 火 | 0 |
2016 | 201611 | 11 | 2 | 20161102 | 4 | 水 | 0 |
2016 | 201611 | 11 | 3 | 20161103 | 5 | 木 | 0 |
2016 | 201611 | 11 | 4 | 20161104 | 6 | 金 | 0 |
2016 | 201611 | 11 | 5 | 20161105 | 7 | 土 | 1 |
あとは、祝日テーブルも作っていました。会社の記念日とかありますしね。
手メンテでした。
年 | 年月 | 月 | 日 | 年月日 | 事由 |
---|---|---|---|---|---|
2016 | 201611 | 11 | 3 | 20161103 | 文化の日 |
2016 | 201611 | 11 | 14 | 20161114 | 埼玉県民の日 |
何はともあれ、誘導されたBlogの記事を試していきます。
まずは、モデリングタブで、新しいテーブルをポチっとします。
数式ペインにこれを記載して、Enter!
カレンダー = CALENDAR("2015/1/1", TODAY())
おぉ、日付が列挙されました。
列をバシバシ追加していきます。しょうもないことなのですが、
DAX式の=の後ろが、全角スペースだとエラーになります。
#コピペせず、キー打ってたら、うっかり全角のまま #列追加した時点で、= が表示されていて、「月」を全角で打って、横に移動してみたいな 月 = FORMAT([Date],"M月")
全角スペースから半角スペースに直せばよいです。
ついに待ちにまった並び替えの指定をやってみます。
「月」列を選んだ状態で、「列で並び替え」を押して、「月番号」を選びます。
・・・うん、まぁそうですよね。
・・・これだけだと分からないので、何かしらデータを追加します。
追加したデータはこちらです。
左側の表は、商品マスタチックに、右側の表は、売上明細チックにしてます。
データを追加して、リレーションシップを定義します
x軸に商品名、y軸に数量、凡例に並び替えをした月をマッピングします。
おぉ
「月」列はテキスト型なのに、1月→9月→10月の順です。
追加したデータの商品マスタチックの商品名を、商品IDで並び替えたいと思います。
並び替え前:カタカナのゴから並んでいます。
並び替え中
並び替え後:りんごが先にきています。
凡例でも軸でも並び替えができました。
過去記事のデータで試してみる
過去記事では、こちらのデータを使いました。
名前 | 科目 | 点数 |
---|---|---|
但 | 数学 | 80 |
但 | 国語 | 60 |
但 | 社会 | 50 |
但 | 英語 | 90 |
但 | 理科 | 70 |
佐 | 数学 | 70 |
佐 | 国語 | 80 |
佐 | 社会 | 60 |
佐 | 英語 | 90 |
佐 | 理科 | 40 |
佑 | 数学 | 10 |
佑 | 国語 | 30 |
佑 | 社会 | 40 |
佑 | 英語 | 20 |
佑 | 理科 | 100 |
とりあえず取り込みます。
科目番号列を追加します。
科目列を、科目番号列で並び替えてみます。
!?!!?
この列によって既に直感的にまたは間接的に並び替えられている列を
基準としてこの列を並び替えることができません。
日本語を整理すると、こうなりますかね。
この列:科目列
この列によって既に直感的にまたは間接的に並び替えられている列:科目番号列
データソースにある列から、DAX式を使って追加した列で並び替えはできないんでしょうか?
というわけで、科目番号列もデータソース側に用意して、取り込みます。
並び替えできました。エイ→コク→スウ→リ→シャです。
軸に科目を、値に点数を、凡例に名前をマッピングします。
ちゃんと、エイ→コク→スウ→リ→シャで並んでいます。
名称列から番号列を作って、作った番号列で名称列を並び替えるがNGっぽいので
番号列から名称列を作る順番で試してみます。
科目番号列をGroupByした新しいテーブルを作成します。
科目番号列から、科目列を作ります。
科目列を、科目番号列で並び替えします。
リレーションシップを定義します。
軸に科目を、値に点数を、凡例に名前をマッピングします。
ちゃんと、エイ→コク→スウ→リ→シャで並んでいます。
よかった!
並び替えが指定できるようになりました!!
頂いたコメントで、MSのBlogに誘導されたので…
↓Tech Summit参加します。しかもブースじゃない方で!!
microsoft-events.jp
de:codeもForesightもブース出展側だったから、楽しめなかったんだよなぁ。
デモがぁデモがぁ
今回は、気楽に楽しめそうです。