Re-wrote to work with latest Power BI visuals SDK; added latest Vega/… (#8)

* Re-wrote to work with latest Power BI visuals SDK; added latest Vega/Vega-Lite packages and fixed typings for Vega spec. Removed the logger, as this hasn't worked in the SDK for a while and the team have yet to document a suitable replacement.

* Removed old .api and logger from source as no longer needed.

* Updating .gitignore

We shouldn't be keeping the generated webpack stats in our source code
This commit is contained in:
Daniel Marsh-Patrick 2020-06-05 11:33:00 +12:00 коммит произвёл GitHub
Родитель f5cd4c6c9d
Коммит 80249e4f94
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
13 изменённых файлов: 7720 добавлений и 9662 удалений

1406
.api/v1.10.0/PowerBI-visuals.d.ts поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,38 +0,0 @@
{
"PBI_API_VERSION": "v1.10.0",
"type": "object",
"properties": {
"cranPackages": {
"type": "array",
"description": "An array of the Cran packages required for the custom R visual script to operate",
"items": {
"$ref": "#/definitions/cranPackage"
}
}
},
"definitions": {
"cranPackage": {
"type": "object",
"description": "cranPackage - Defines the name and displayName of a required Cran package",
"properties": {
"name": {
"type": "string",
"description": "The name for this Cran package"
},
"displayName": {
"type": "string",
"description": "The name for this Cran package that is shown to the user"
},
"url": {
"type": "string",
"description": "A url for package documentation in Cran website"
}
},
"required": [
"name",
"url"
],
"additionalProperties": false
}
}
}

Просмотреть файл

@ -1,103 +0,0 @@
{
"PBI_API_VERSION": "v1.10.0",
"type": "object",
"properties": {
"apiVersion": {
"type": "string",
"description": "Version of the IVisual API"
},
"author": {
"type": "object",
"description": "Information about the author of the visual",
"properties": {
"name": {
"type": "string",
"description": "Name of the visual author. This is displayed to users."
},
"email": {
"type": "string",
"description": "E-mail of the visual author. This is displayed to users for support."
}
}
},
"assets": {
"type": "object",
"description": "Assets used by the visual",
"properties": {
"icon": {
"type": "string",
"description": "A 20x20 png icon used to represent the visual"
}
}
},
"externalJS": {
"type": "array",
"description": "An array of relative paths to 3rd party javascript libraries to load",
"items": {
"type": "string"
}
},
"stringResources": {
"type": "array",
"description": "An array of relative paths to string resources to load",
"items": {
"type": "string"
},
"uniqueItems": true
},
"style" : {
"type": "string",
"description": "Relative path to the stylesheet (less) for the visual"
},
"capabilities": {
"type": "string",
"description": "Relative path to the visual capabilities json file"
},
"visual": {
"type": "object",
"description": "Details about this visual",
"properties": {
"description": {
"type": "string",
"description": "What does this visual do?"
},
"name": {
"type": "string",
"description": "Internal visual name"
},
"displayName": {
"type": "string",
"description": "A friendly name"
},
"externals": {
"type": "array",
"description": "External files (such as JavaScript) that you would like to include"
},
"guid": {
"type": "string",
"description": "Unique identifier for the visual"
},
"visualClassName": {
"type": "string",
"description": "Class of your IVisual"
},
"icon": {
"type": "string",
"description": "Icon path"
},
"version": {
"type": "string",
"description": "Visual version"
},
"gitHubUrl": {
"type": "string",
"description": "Url to the github repository for this visual"
},
"supportUrl": {
"type": "string",
"description": "Url to the support page for this visual"
}
}
}
}
}

Просмотреть файл

@ -1,67 +0,0 @@
{
"PBI_API_VERSION": "v1.10.0",
"type": "object",
"properties": {
"locale": {
"$ref": "#/definitions/localeOptions"
},
"values": {
"type": "object",
"description": "translations for the display name keys in the capabilities",
"additionalProperties": { "type": "string" }
}
},
"required": [ "locale" ],
"definitions": {
"localeOptions": {
"description": "Specifies the locale key from a list of supported locales",
"type": "string",
"enum": [
"ar-SA",
"bg-BG",
"ca-ES",
"cs-CZ",
"da-DK",
"de-DE",
"el-GR",
"en-US",
"es-ES",
"et-EE",
"eu-ES",
"fi-FI",
"fr-FR",
"gl-ES",
"he-IL",
"hi-IN",
"hr-HR",
"hu-HU",
"id-ID",
"it-IT",
"ja-JP",
"kk-KZ",
"ko-KR",
"lt-LT",
"lv-LV",
"ms-MY",
"nb-NO",
"nl-NL",
"pl-PL",
"pt-BR",
"pt-PT",
"ro-RO",
"ru-RU",
"sk-SK",
"sl-SI",
"sr-Cyrl-RS",
"sr-Latn-RS",
"sv-SE",
"th-TH",
"tr-TR",
"uk-UA",
"vi-VN",
"zh-CN",
"zh-TW"
]
}
}
}

2
.gitignore поставляемый
Просмотреть файл

@ -2,3 +2,5 @@ node_modules
.tmp
.vscode
dist
webpack.statistics*.html

14337
package-lock.json сгенерированный

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -6,14 +6,22 @@
"url": "https://github.com/Microsoft/vegalite-for-powerbi.git"
},
"dependencies": {
"powerbi-visuals-utils-dataviewutils": "1.4.1",
"vega": "^3.0.8",
"vega-lite": "^2.0.4"
"@babel/runtime": "7.6.0",
"@babel/runtime-corejs2": "7.6.0",
"core-js": "3.2.1",
"powerbi-visuals-api": "^2.6.2",
"powerbi-visuals-utils-dataviewutils": "2.2.1",
"regenerator-runtime": "^0.13.3",
"vega": "^5.9.1",
"vega-lite": "^4.4.0"
},
"devDependencies": {
"powerbi-visuals-tools": "^1.10.0",
"tslint": "^5.9.1",
"typescript": "^2.6.2"
"@types/vega": "^3.2.0",
"powerbi-visuals-tools": "^3.1.5",
"ts-loader": "6.1.0",
"tslint": "^5.18.0",
"tslint-microsoft-contrib": "^6.2.0",
"typescript": "3.6.3"
},
"scripts": {
"start": "pbiviz start",

Просмотреть файл

@ -9,7 +9,7 @@
"supportUrl": "https://github.com/Microsoft/vegalite-for-powerbi/issues",
"gitHubUrl": "https://github.com/Microsoft/vegalite-for-powerbi"
},
"apiVersion": "1.10.0",
"apiVersion": "2.6.0",
"author": {
"name": "Dominik Moritz",
"email": "t-romor@microsoft.com"
@ -17,13 +17,9 @@
"assets": {
"icon": "assets/icon.png"
},
"externalJS": [
"node_modules/powerbi-visuals-utils-dataviewutils/lib/index.js",
"node_modules/vega-lite/build/vega-lite.js",
"node_modules/vega/build/vega.js"
],
"externalJS": [],
"style": "style/visual.less",
"capabilities": "capabilities.json",
"dependencies": "dependencies.json",
"dependencies": null,
"stringResources": []
}

Просмотреть файл

@ -1,16 +0,0 @@
module powerbi.extensibility.visual {
export function logExceptions() {
return function(target: any, propertyKey: string, descriptor) {
return {
value: function() {
try {
return descriptor.value.apply(this, arguments);
} catch (e) {
console.error(e);
throw e;
}
}
};
};
}
}

Просмотреть файл

@ -1,11 +1,10 @@
module powerbi.extensibility.visual {
import DataViewObjectsParser = powerbi.extensibility.utils.dataview.DataViewObjectsParser;
import { dataViewObjectsParser } from 'powerbi-visuals-utils-dataviewutils';
import DataViewObjectsParser = dataViewObjectsParser.DataViewObjectsParser;
export class VisualSettings extends DataViewObjectsParser {
public rendering = new RenderSettings();
}
export class RenderSettings {
public svg = false;
}
export class VisualSettings extends DataViewObjectsParser {
public rendering = new RenderSettings();
}
export class RenderSettings {
public svg = false;
}

Просмотреть файл

@ -1,117 +1,128 @@
module powerbi.extensibility.visual {
interface BarChartDataPoint {
value: PrimitiveValue;
category: string;
"use strict";
import "core-js/stable";
import "regenerator-runtime/runtime";
import "./../style/visual.less";
import powerbi from "powerbi-visuals-api";
import VisualConstructorOptions = powerbi.extensibility.visual.VisualConstructorOptions;
import VisualUpdateOptions = powerbi.extensibility.visual.VisualUpdateOptions
import IVisual = powerbi.extensibility.visual.IVisual;
import EnumerateVisualObjectInstancesOptions = powerbi.EnumerateVisualObjectInstancesOptions;
import VisualObjectInstance = powerbi.VisualObjectInstance;
import VisualObjectInstanceEnumerationObject = powerbi.VisualObjectInstanceEnumerationObject;
import VisualUpdateType = powerbi.VisualUpdateType;
import PrimitiveValue = powerbi.PrimitiveValue;
import DataView = powerbi.DataView;
import * as vega from 'vega';
import * as vl from 'vega-lite';
import { VisualSettings } from "./settings";
interface BarChartDataPoint {
value: PrimitiveValue;
category: string;
}
function visualTransform(options: VisualUpdateOptions) {
let dataViews = options.dataViews;
let dataPoints: BarChartDataPoint[] = [];
if (!dataViews
|| !dataViews[0]
|| !dataViews[0].categorical
|| !dataViews[0].categorical.categories
|| !dataViews[0].categorical.categories[0].source
|| !dataViews[0].categorical.values)
return null;
let categorical = dataViews[0].categorical;
let category = categorical.categories[0];
let dataValue = categorical.values[0];
let objects = dataViews[0].metadata.objects;
let categoryTitle = category.source.displayName;
let valueTitle = dataValue.source.displayName;
for (let i = 0, len = Math.max(category.values.length, dataValue.values.length); i < len; i++) {
dataPoints.push({
category: category.values[i] + "",
value: dataValue.values[i]
});
}
function visualTransform(options: VisualUpdateOptions) {
let dataViews = options.dataViews;
return {dataPoints, categoryTitle, valueTitle};
}
let dataPoints: BarChartDataPoint[] = [];
export class BarChart implements IVisual {
private target: HTMLElement;
private settings: VisualSettings;
if (!dataViews
|| !dataViews[0]
|| !dataViews[0].categorical
|| !dataViews[0].categorical.categories
|| !dataViews[0].categorical.categories[0].source
|| !dataViews[0].categorical.values)
return null;
private view: any;
let categorical = dataViews[0].categorical;
let category = categorical.categories[0];
let dataValue = categorical.values[0];
constructor(options: VisualConstructorOptions) {
console.log("Visual constructor", options);
let objects = dataViews[0].metadata.objects;
let categoryTitle = category.source.displayName;
let valueTitle = dataValue.source.displayName;
for (let i = 0, len = Math.max(category.values.length, dataValue.values.length); i < len; i++) {
dataPoints.push({
category: category.values[i] + '',
value: dataValue.values[i]
});
}
return {dataPoints, categoryTitle, valueTitle};
this.target = options.element;
}
export class BarChart implements IVisual {
private target: HTMLElement;
private settings: VisualSettings;
public update(options: VisualUpdateOptions) {
this.settings = BarChart.parseSettings(options && options.dataViews && options.dataViews[0]);
console.log("Visual update", options);
private view: any;
constructor(options: VisualConstructorOptions) {
console.log('Visual constructor', options);
this.target = options.element;
if (this.view && (options.type & VisualUpdateType.Resize || options.type & VisualUpdateType.ResizeEnd)) {
this.view.width(options.viewport.width).height(options.viewport.height).run();
return;
}
@logExceptions()
public update(options: VisualUpdateOptions) {
this.settings = BarChart.parseSettings(options && options.dataViews && options.dataViews[0]);
console.log('Visual update', options);
const r = visualTransform(options);
if (this.view && (options.type & VisualUpdateType.Resize || options.type & VisualUpdateType.ResizeEnd)) {
this.view.width(options.viewport.width).height(options.viewport.height).run();
return;
if (!r) {
this.target.innerHTML = "Need category and measure";
this.view = null;
return;
}
const {dataPoints, categoryTitle, valueTitle} = r;
const spec: vl.TopLevelSpec = {
$schema: "https://vega.github.io/schema/vega-lite/v4.json",
width: options.viewport.width,
height: options.viewport.height,
padding: 0,
autosize: {
type: "fit",
contains: "content"
},
data: {
values: dataPoints
},
mark: "bar",
encoding: {
x: {field: "category", type: "ordinal", axis: {title: categoryTitle}},
y: {field: "value", type: "quantitative", axis: {title: valueTitle}}
}
};
const r = visualTransform(options);
const vgSpec = vl.compile(spec).spec;
if (!r) {
this.target.innerHTML = "Need category and measure";
this.view = null;
return;
}
const runtime = vega.parse(vgSpec);
const {dataPoints, categoryTitle, valueTitle} = r;
this.view = new vega.View(runtime)
.logLevel(vega.Warn)
.initialize(this.target)
.renderer(this.settings.rendering.svg ? "svg" : "canvas")
.run();
}
// this should be type TopLevelExtendedSpec
const spec = {
$schema: "https://vega.github.io/schema/vega-lite/v2.json",
width: options.viewport.width,
height: options.viewport.height,
padding: 0,
autosize: {
type: "fit",
contains: "content"
},
data: {
values: dataPoints
},
mark: "bar",
encoding: {
x: {field: "category", type: "ordinal", axis: {title: categoryTitle}},
y: {field: "value", type: "quantitative", axis: {title: valueTitle}}
}
};
private static parseSettings(dataView: DataView): VisualSettings {
return VisualSettings.parse(dataView) as VisualSettings;
}
const vl = (window as any).vl;
const vega = (window as any).vega;
const vgSpec = vl.compile(spec).spec;
const runtime = vega.parse(vgSpec);
this.view = new vega.View(runtime)
.logLevel(vega.Warn)
.initialize(this.target)
.renderer(this.settings.rendering.svg ? "svg" : "canvas")
.run();
}
private static parseSettings(dataView: DataView): VisualSettings {
return VisualSettings.parse(dataView) as VisualSettings;
}
/**
* This function gets called for each of the objects defined in the capabilities files and allows you to select which of the
* objects and properties you want to expose to the users in the property pane.
*/
public enumerateObjectInstances(options: EnumerateVisualObjectInstancesOptions): VisualObjectInstance[] | VisualObjectInstanceEnumerationObject {
return VisualSettings.enumerateObjectInstances(this.settings || VisualSettings.getDefault(), options);
}
/**
* This function gets called for each of the objects defined in the capabilities files and allows you to select which of the
* objects and properties you want to expose to the users in the property pane.
*/
public enumerateObjectInstances(options: EnumerateVisualObjectInstancesOptions): VisualObjectInstance[] | VisualObjectInstanceEnumerationObject {
return VisualSettings.enumerateObjectInstances(this.settings || VisualSettings.getDefault(), options);
}
}

Просмотреть файл

@ -1,17 +1,19 @@
{
"compilerOptions": {
"allowJs": true,
"allowJs": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "ES5",
"target": "es6",
"sourceMap": true,
"out": "./.tmp/build/visual.js"
"outDir": "./.tmp/build/",
"moduleResolution": "node",
"declaration": true,
"lib": [
"es2015",
"dom"
]
},
"files": [
".api/v1.10.0/PowerBI-visuals.d.ts",
"node_modules/powerbi-visuals-utils-dataviewutils/lib/index.d.ts",
"src/settings.ts",
"src/logger.ts",
"src/visual.ts"
"./src/visual.ts"
]
}