Power BI カスタムビジュアル開発 : TypeUtils でカスタムビジュアルに重要なタイプをより簡単に扱う

# TypeUtils

`TypeUtils` は Power BI カスタムビジュアルでよく扱う型について、多くの機能を提供します。特にデータの集計や軸に対する数値の設定など、Power BI では小数点をよく扱うため、小数点が絡む数値の扱いが行える Double は便利なモジュールです。

# インストール

以下手順で追加。

1\. npm コマンドでインストール。

```shell
npm install powerbi-visuals-utils-typeutils --save
```
2\. tsconfig.json の files に型情報を追加。

```json:tsconfig.json
{
  "compilerOptions": {
  ...
  },
  "files": [
    ...,　
    "node_modules/powerbi-visuals-utils-typeutils/lib/index.d.ts"
  ]
}
```

3\. pbiviz.json の externalJS に追加。

```json:pbiviz.json
{
  ...
  "externalJS": [
    ...,
    "node_modules/powerbi-visuals-utils-typeutils/lib/index.js"
  ],
  ...
}
```

# 機能

- [Double](#double) - 数値側の精度を操作
- [Prototype](#prototype) - オブジェクトの継承をサポート
- [PixelConverter](#pixelconverter) - ピクセルとポイントの相互変換

# Double
`Double` は数値側の精度を操作する機能

`powerbi.extensibility.utils.type.Double` モジュールでは以下の機能を提供

- [pow10](#pow10)
- [log10](#log10)
- [getPrecision](#getprecision)
- [equalWithPrecision](#equalwithprecision)
- [lessWithPrecision](#lesswithprecision)
- [lessOrEqualWithPrecision](#lessorequalwithprecision)
- [greaterWithPrecision](#greaterwithprecision)
- [greaterOrEqualWithPrecision](#greaterorequalwithprecision)
- [floorWithPrecision](#floorwithprecision)
- [ceilWithPrecision](#ceilwithprecision)
- [floorToPrecision](#floortoprecision)
- [ceilToPrecision](#ceiltoprecision)
- [roundToPrecision](#roundtoprecision)
- [ensureInRange](#ensureinrange)
- [round](#round)
- [removeDecimalNoise](#removedecimalnoise)
- [isInteger](#isinteger)
- [toIncrement](#toincrement)

## pow10

10 ベースにを指定した数乗する。

```typescript
function pow10(exp: number): number;
```

### pow10 の例

```typescript
import Double = powerbi.extensibility.utils.type.Double;

Double.pow10(3); // 100
Double.pow10(5); // 10000
Double.pow10(25); // 1e+25
```

## log10

10 をベースに指定した数の対数を取得する。

```typescript
function log10(val: number): number;
```

### log10 の例

```typescript
import Double = powerbi.extensibility.utils.type.Double;

Double.log10(100); // 2
Double.log10(500); // 2
Double.log10(10000); // 4
```

## getPrecision

元の数字に対して、指定した数の精度に対する桁の 10 の累乗を返す。

```typescript
function getPrecision(x: number, decimalDigits?: number): number;
```

### getPrecision の例

```typescript
import Double = powerbi.extensibility.utils.type.Double;

Double.getPrecision(2345, 0); // 1000 (2345.0 -> 4 桁)
Double.getPrecision(2345, 1); // 100 (234.5 -> 3 桁)
Double.getPrecision(2345, 2); // 10 (23.45 -> 2 桁)
```

## equalWithPrecision

指定した精度で、1 つ目の数と 2 つ目の数が同じか確認

```typescript
function equalWithPrecision(x: number, y: number, precision?: number): boolean;
```

### equalWithPrecision の例

```typescript
import Double = powerbi.extensibility.utils.type.Double;

Double.equalWithPrecision(1.11, 1.12, 1); // true (1 = 1)
Double.equalWithPrecision(1.11, 1.12, 0.1); // true (1.1 = 1.1)
Double.equalWithPrecision(1.11, 1.12, 0.01); // false (1.11 = 1.12)
```
## lessWithPrecision

指定した精度で、1 つ目の数が 2 つ目の数より小さいか確認

```typescript
function lessWithPrecision(x: number, y: number, precision?: number): boolean;
```
### lessWithPrecision の例

```typescript
import Double = powerbi.extensibility.utils.type.Double;

Double.lessWithPrecision(1.11, 1.12, 1); // false (1 < 1)
Double.lessWithPrecision(1.11, 1.12, 0.1); // false (1.1 < 1.1)
Double.lessWithPrecision(1.11, 1.12, 0.01); // true (1.11 < 1.12)
```
## lessOrEqualWithPrecision

指定した精度で、1 つ目の数が 2 つ目の数以下か確認

```typescript
function lessOrEqualWithPrecision(x: number, y: number, precision?: number): boolean;
```
### lessOrEqualWithPrecision の例

```typescript
import Double = powerbi.extensibility.utils.type.Double;

Double.lessOrEqualWithPrecision(1.11, 1.12, 1); // true (1 <= 1)
Double.lessOrEqualWithPrecision(1.11, 1.12, 0.1); // true (1.1 <= 1.1)
Double.lessOrEqualWithPrecision(1.11, 1.12, 0.01); // true (1.11 <= 1.12)
```

## greaterWithPrecision

指定した精度で、1 つ目の数が 2 つ目の数がより大きいか確認

```typescript
function greaterWithPrecision(x: number, y: number, precision?: number): boolean;
```
### greaterWithPrecision の例

```typescript
import Double = powerbi.extensibility.utils.type.Double;

Double.greaterWithPrecision(1.12, 1.11, 1); // false (1 > 1)
Double.greaterWithPrecision(1.12, 1.11, 0.1); // false (1.1 > 1.1)
Double.greaterWithPrecision(1.12, 1.11, 0.01); // true (1.12 > 1.11)
```

## greaterOrEqualWithPrecision

指定した精度で、1 つ目の数が 2 つ目の数以上か確認。

```typescript
function greaterOrEqualWithPrecision(x: number, y: number, precision?: number): boolean;
```
### greaterOrEqualWithPrecision の例

```typescript
import Double = powerbi.extensibility.utils.type.Double;

Double.greaterOrEqualWithPrecision(1.12, 1.11, 1); // true (1 >= 1)
Double.greaterOrEqualWithPrecision(1.12, 1.11, 0.1); // true (1.1 >= 1.1)
Double.greaterOrEqualWithPrecision(1.12, 1.11, 0.01); // true (1.12 >= 1.11)
```

## floorWithPrecision

指定した精度での切り捨て

```typescript
function floorWithPrecision(x: number, precision?: number): number;
```

### floorWithPrecision の例

```typescript
import Double = powerbi.extensibility.utils.type.Double;

Double.floorWithPrecision(5.96, 0.001); // 5

// returns: 5
```

## ceilWithPrecision

指定した精度での切り上げ

```typescript
function ceilWithPrecision(x: number, precision?: number): number;
```

### ceilWithPrecision の例

```typescript
import Double = powerbi.extensibility.utils.type.Double;

Double.ceilWithPrecision(5.06, 0.001); // 6
```

## floorToPrecision

指定した精度への切り捨て

```typescript
function floorToPrecision(x: number, precision?: number): number;
```

### floorToPrecision の例

```typescript
import Double = powerbi.extensibility.utils.type.Double;

Double.floorToPrecision(5.96, 0.1); // 5.9
```

## ceilToPrecision

指定した精度への切り上げ

```typescript
function ceilToPrecision(x: number, precision?: number): number;
```

### ceilToPrecision の例

```typescript
import Double = powerbi.extensibility.utils.type.Double;

Double.ceilToPrecision(-506, 10); //-500
```

## roundToPrecision

指定した精度への丸め

```typescript
function roundToPrecision(x: number, precision?: number): number;
```

### roundToPrecision の例

```typescript
import Double = powerbi.extensibility.utils.type.Double;

Double.roundToPrecision(596, 10); // 600
Double.roundToPrecision(594, 10); // 590
```
## ensureInRange

値が指定された範囲にあるか確認。いる場合は元の数が、小さい場合は min, 大きい場合は max が返る。

```typescript
function ensureInRange(x: number, min: number, max: number): number;
```

### ensureInRange の例

```typescript
import Double = powerbi.extensibility.utils.type.Double;

Double.ensureInRange(20, 10, 30); // 20
Double.ensureInRange(5, 10, 30); // 10
Double.ensureInRange(35, 10, 30); // 30
```

## round

値を丸める

```typescript
function round(x: number): number;
```

### round の例

```typescript
import Double = powerbi.extensibility.utils.type.Double;

Double.round(27.45); //27
```

## removeDecimalNoise

数値が小さすぎる小数点のノイズを削除する

```typescript
function removeDecimalNoise(value: number): number;
```

### removeDecimalNoise の例

```typescript
import Double = powerbi.extensibility.utils.type.Double;

Double.removeDecimalNoise(21.493000000000002); // 21.493
```

## isInteger

値が整数か確認する

```typescript
function isInteger(value: number): boolean;
```

### isInteger の例

```typescript
import Double = powerbi.extensibility.utils.type.Double;

Double.isInteger(21.493000000000002); // false
Double.isInteger(21.0); // true
```

## toIncrement

指定された数だけ増やし、丸めた値を返す。

```typescript
function toIncrement(value: number, increment: number): number;
```

### toIncrement の例

```typescript
import Double = powerbi.extensibility.utils.type.Double;

Double.toIncrement(0.6383723, 0.05); //0.65
```

# Prototype
`Prototype` はオブジェクトを継承する機能を提供

`powerbi.extensibility.utils.type.Prototype` モジュールで以下の機能を提供

* [inherit](#inherit)
* [inheritSingle](#inheritsingle)

## inherit

指定したオブジェクトを継承した、新しいオブジェクトを作成

```typescript
function inherit<T>(obj: T, extension?: (inherited: T) => void): T;
```

### inherit の例

```typescript
import Prototype = powerbi.extensibility.utils.type.Prototype;

let base = { Microsoft: "Power BI" };

Prototype.inherit(base);

/* returns: {
    __proto__: {
        Microsoft: "Power BI"
    }
}*/
```

## inheritSingle

inherit と同じだが、protptype がない場合に限り指定したオブジェクトを継承したオブジェクトを作成。

```typescript
function inheritSingle<T>(obj: T): T;
```

### inheritSingle の例

```typescript
import Prototype = powerbi.extensibility.utils.type.Prototype;

let base = { Microsoft: "Power BI" };

Prototype.inheritSingle(base);

/* returns: {
    __proto__: {
        Microsoft: "Power BI"
    }
}*/
```
# PixelConverter
`PixelConverter` はピクセルとポイントを相互変換する機能や文字列にする機能を提供

`powerbi.extensibility.utils.type.PixelConverter` モジュールは以下の機能を提供

* [toString](#tostring)
* [fromPoint](#frompoint)
* [fromPointToPixel](#frompointtopixel)
* [toPoint](#topoint)

## toString

ピクセルを文字列に変換

```typescript
function toString(px: number): string;
```

### toString の例

```typescript
import PixelConverter = powerbi.extensibility.utils.type.PixelConverter;

PixelConverter.toString(25); //25px
```

## fromPoint

ポイントをピクセルに変換し、文字列の形式で返す。

```typescript
function fromPoint(pt: number): string;
```

### fromPoint の例

```typescript
import PixelConverter = powerbi.extensibility.utils.type.PixelConverter;

PixelConverter.fromPoint(8); // 33.33333333333333px
```

## fromPointToPixel

ポイントからピクセルに変換

```typescript
function fromPointToPixel(pt: number): number;
```

### fromPointToPixel の例

```typescript
import PixelConverter = powerbi.extensibility.utils.type.PixelConverter;

PixelConverter.fromPointToPixel(8); // 10.666666666666666
```

## toPoint

ピクセルからポイントに変換

```typescript
function toPoint(px: number): number;
```

### toPoint の例

```typescript
import PixelConverter = powerbi.extensibility.utils.type.PixelConverter;

PixelConverter.toPoint(8); // 6
```

# まとめ

TypeUtil では Double の操作やピクセル変換など、ビジュアルを描写するのに必要な機能が提供されています。ここで紹介したものは一部の関数となるため、必要な関数がここにない場合は、Intellisense などを活用して探してみてください。

[目次へ戻る](https://qiita.com/kenakamu/items/f57ab7f73d6ea10bc9d9)