This commit is contained in:
沐见南 2020-02-04 03:33:37 +08:00
commit 7fa42e0df2
22 changed files with 9686 additions and 0 deletions

106
.gitignore vendored Normal file
View File

@ -0,0 +1,106 @@
StandardExmp/
dist/
# tmp
.tmp/
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# next.js build output
.next
# nuxt.js build output
.nuxt
# gatsby files
.cache/
public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port

13
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,13 @@
{
"version": "0.1.0",
"configurations": [
{
"name": "Debugger",
"type": "chrome",
"request": "attach",
"port": 9222,
"sourceMaps": true,
"webRoot": "${cwd}/"
}
]
}

37
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,37 @@
{
"editor.tabSize": 4,
"editor.insertSpaces": true,
"files.eol": "\n",
"files.watcherExclude": {
"**/.git/objects/**": true,
"**/node_modules/**": true,
".tmp": true
},
"files.exclude": {
".tmp": true
},
"search.exclude": {
".tmp": true,
"typings": true
},
"json.schemas": [
{
"fileMatch": [
"/pbiviz.json"
],
"url": "./node_modules/powerbi-visuals-api/schema.pbiviz.json"
},
{
"fileMatch": [
"/capabilities.json"
],
"url": "./node_modules/powerbi-visuals-api/schema.capabilities.json"
},
{
"fileMatch": [
"/dependencies.json"
],
"url": "./node_modules/powerbi-visuals-api/schema.dependencies.json"
}
]
}

BIN
assets/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

192
capabilities.json Normal file
View File

@ -0,0 +1,192 @@
{
"dataRoles": [
{
"displayName": "Dates",
"name": "Dates",
"kind": "Grouping",
"displayNameKey": "Role_Dates_DisplayName",
"description": "Column date",
"descriptionKey": "Role_Dates_Discription"
},
{
"displayNameKey": "Role_StartDate_DisplayName",
"displayName": "DefaultStartDate",
"name": "StartDate",
"kind": "Measure",
"descriptionKey": "Role_StartDate_Discription",
"description": "You can use Messure to assign Default date to the date-picker"
},
{
"displayNameKey": "Role_DefaultEndDate_DisplayName",
"displayName": "DefaultEndDate",
"name": "EndDate",
"kind": "Measure",
"descriptionKey": "Role_DefaultEndDate_Discription",
"description": "You can use Messure to assign Default date to the date-picker"
}
],
"objects": {
"period": {
"displayNameKey": "Obj_Period_DisplayName",
"displayName": "Period",
"descriptionKey": "Obj_Period_Discription",
"description": "Settings for period-picker",
"properties": {
"defaultPeriodType": {
"displayNameKey": "Period_DefaultPeriodType_DisplayName",
"displayName": "Default period",
"descriptionKey":"Period_DefaultPeriodType_Discription",
"description": "Choose how to assign default period to the period-picker",
"type": {
"enumeration": [
{
"value": "0",
"displayNameKey": "LastMonth",
"displayName": "Last month"
},
{
"value": "1",
"displayNameKey": "LastEntireMonth",
"displayName": "Last entire month"
},
{
"value": "2",
"displayNameKey": "LastWeek",
"displayName": "Last week"
},
{
"value": "3",
"displayNameKey": "LastEntireWeek",
"displayName": "Last entire week"
},
{
"value": "4",
"displayNameKey": "Custom",
"displayName": "Custom(use messures)"
}
]
},
"filterState": true
},
"relativeToday": {
"type": {
"bool": true
},
"displayNameKey": "Period_RelativeToday_DisplayName",
"displayName": "Contain today",
"descriptionKey": "Period_RelativeToday_Discription",
"description": "Effictive when and only when Custom(use messures) not selected"
},
"firstDayOfWeek": {
"descriptionKey": "Period_FirstDayOfWeek_DisplayName",
"displayName": "FirstDayOfWeek",
"displayNameKey": "firstDayOfWeek",
"type": {
"enumeration": [
{
"value": "0",
"displayName": "Sunday",
"displayNameKey": "Sunday"
},
{
"value": "1",
"displayName": "Monday",
"displayNameKey": "Monday"
},
{
"value": "2",
"displayName": "Tuesday",
"displayNameKey": "Tuesday"
},
{
"value": "3",
"displayName": "Wednesday",
"displayNameKey": "Wednesday"
},
{
"value": "4",
"displayName": "Thursday",
"displayNameKey": "Thursday"
},
{
"value": "5",
"displayName": "Friday",
"displayNameKey": "Friday"
},
{
"value": "6",
"displayName": "Saturday",
"displayNameKey": "Saturday"
}
]
}
}
}
},
"general": {
"displayName": "General",
"displayNameKey": "formattingGeneral",
"properties": {
"filter": {
"type": {
"filter": true
}
},
"selfFilter": {
"type": {
"filter": {
"selfFilter": true
}
}
}
}
}
},
"suppressDefaultTitle": true,
"dataViewMappings": [
{
"conditions": [
{
"Dates": {
"max": 1,
"min": 1
},
"StartDate": {
"max": 1,
"min": 0
},
"EndDate": {
"max": 1,
"min": 0
}
}
],
"categorical": {
"categories": {
"for": {
"in": "Dates"
},
"dataReductionAlgorithm": {
"top": {
"count": 1
}
}
},
"values": {
"select": [
{
"bind": {
"to": "StartDate"
}
},
{
"bind": {
"to": "EndDate"
}
}
]
}
}
}
]
}

8646
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

54
package.json Normal file
View File

@ -0,0 +1,54 @@
{
"name": "visual",
"scripts": {
"pbiviz": "pbiviz",
"start": "pbiviz start",
"package": "pbiviz package",
"lint": "tslint -c tslint.json -p tsconfig.json"
},
"dependencies": {
"@babel/runtime": "7.6.0",
"@babel/runtime-corejs2": "7.6.0",
"@types/d3": "5.7.2",
"core-js": "3.2.1",
"d3": "5.12.0",
"moment": "^2.24.0",
"powerbi-models": "^1.3.1",
"powerbi-visuals-api": "~2.6.1",
"powerbi-visuals-utils-dataviewutils": "2.2.1",
"powerbi-visuals-utils-interactivityutils": "^5.6.0"
},
"devDependencies": {
"@babel/polyfill": "^7.2.5",
"@types/d3": "5.7.2",
"@types/jasmine": "2.5.37",
"@types/jasmine-jquery": "1.5.28",
"@types/jquery": "2.0.41",
"@types/karma": "3.0.0",
"@types/lodash-es": "4.17.1",
"coveralls": "3.0.2",
"istanbul-instrumenter-loader": "^3.0.1",
"jasmine": "2.5.2",
"jasmine-core": "2.5.2",
"jasmine-jquery": "2.1.1",
"jquery": "^3.4.1",
"karma": "^4.4.1",
"karma-chrome-launcher": "2.2.0",
"karma-coverage": "1.1.2",
"karma-coverage-istanbul-reporter": "^2.0.4",
"karma-jasmine": "2.0.1",
"karma-junit-reporter": "^1.2.0",
"karma-sourcemap-loader": "^0.3.7",
"karma-typescript": "^4.1.1",
"karma-typescript-preprocessor": "0.4.0",
"karma-webpack": "3.0.5",
"puppeteer": "1.17.0",
"style-loader": "0.23.1",
"ts-loader": "6.1.0",
"ts-node": "7.0.1",
"tslint": "^5.18.0",
"tslint-microsoft-contrib": "^6.2.0",
"typescript": "3.6.3",
"webpack": "4.26.0"
}
}

25
pbiviz.json Normal file
View File

@ -0,0 +1,25 @@
{
"visual": {
"name": "DatePeriodSlice",
"displayName": "DatePeriodSlice",
"guid": "DatePeriodSlice9771124744984CE8959D0304EEAB35E8",
"visualClassName": "Visual",
"version": "1.0.0",
"description": "可设置默认值的日期段切片器",
"supportUrl": "https://github.com/mujiannan/PbiViz",
"gitHubUrl": "https://github.com/mujiannan/PbiViz"
},
"apiVersion": "2.6.0",
"author": {
"name": "MuJianNan",
"email": "littlesand@outlook.com"
},
"assets": {
"icon": "assets/icon.png"
},
"externalJS": [],
"style": "style/visual.less",
"capabilities": "capabilities.json",
"dependencies": null,
"stringResources": []
}

View File

@ -0,0 +1,19 @@
"use strict";
import * as moment from 'moment';
export interface IPeriod {
dateStart: Date;
dateEnd: Date;
}
export class Period implements IPeriod {
dateStart: Date;
dateEnd: Date;
public constructor(start: Date = null, end: Date = null) {
this.dateStart = start;
this.dateEnd = end;
}
}
export enum DefaultPeriodType {
LastMonth, LastEntireMonth, LastWeek, LastEntireWeek, Custom
}

View File

@ -0,0 +1,63 @@
"use strict";
import * as d3 from "d3";
import {IPeriod,Period} from "./datePeriod";
import * as moment from "moment";
type Selection<T extends d3.BaseType> = d3.Selection<T, any, any, any>;
export interface IPeriodSelectorManager{
dateSelector_Start:Selection<HTMLInputElement>;
dateSelector_End:Selection<HTMLInputElement>;
period:IPeriod;
defaultPeriod:IPeriod;
}
export class PeriodSelectorManager implements IPeriodSelectorManager{
public constructor(dateSelector_Start:Selection<HTMLInputElement>,dateSelector_End:Selection<HTMLInputElement>){
this._dateSelector_Start=dateSelector_Start;
this._dateSelector_End=dateSelector_End;
}
private _dateSelector_Start:Selection<HTMLInputElement>;
private _dateSelector_End:Selection<HTMLInputElement>;
get dateSelector_Start():Selection<HTMLInputElement>{
return this._dateSelector_Start;
}
get dateSelector_End():Selection<HTMLInputElement>{
return this._dateSelector_End;
}
get period():IPeriod{
console.debug(this._dateSelector_Start.property("value"));
let start:Date=this._dateSelector_Start.property("value")?moment(this._dateSelector_Start.property("value")).startOf("day").toDate():null;
let end:Date=this._dateSelector_End.property("value")?moment(this._dateSelector_End.property("value")).endOf("day").toDate():null;
if(start&&end&&start>end){
console.debug("dateStart>dateEnd, set dateEnd=dateStart");
this._dateSelector_End.property("value",this._dateSelector_Start.property("value"));
end=start;
}
return new Period(start,end);
}
private _defaultPeriod:IPeriod=new Period();
get defaultPeriod(){
return this._defaultPeriod;
}
set defaultPeriod(newDefaultPeriod:IPeriod){
console.debug("PeriodSelectorManager set defaultPeriod start");
console.debug((!this._defaultPeriod.dateStart)&&newDefaultPeriod.dateStart);
console.debug(this._defaultPeriod.dateStart&&newDefaultPeriod.dateStart&&(newDefaultPeriod.dateStart.getTime()-this._defaultPeriod.dateStart.getTime()!=0));
console.debug("test");
if(((!this._defaultPeriod.dateStart)&&newDefaultPeriod.dateStart)||
(this._defaultPeriod.dateStart&&newDefaultPeriod.dateStart&&(newDefaultPeriod.dateStart.getTime()-this._defaultPeriod.dateStart.getTime()!=0))){
let newStartStr=moment(newDefaultPeriod.dateStart).format("YYYY-MM-DD");
console.debug("new start",newStartStr);
this._dateSelector_Start.property("value",newStartStr);
console.debug("Set dateStart value="+newStartStr);
}
if(((!this._defaultPeriod.dateEnd)&&newDefaultPeriod.dateEnd)||
(this._defaultPeriod.dateEnd&&newDefaultPeriod.dateEnd&&(newDefaultPeriod.dateEnd.getTime()-this._defaultPeriod.dateEnd.getTime()!=0))){
let newEndStr=moment(newDefaultPeriod.dateEnd).format("YYYY-MM-DD");
this._dateSelector_End.property("value",newEndStr);
console.debug("Set dateEnd value="+newEndStr);
}
this._defaultPeriod=newDefaultPeriod;
this._dateSelector_Start.dispatch("change");
console.debug("PeriodSelectorManager set defaultPeriod end");
}
}

View File

@ -0,0 +1,7 @@
"use strict";
import * as DatePeriod from "./datePeriod";
export class PeriodSettings {
public defaultPeriodType:DatePeriod.DefaultPeriodType=DatePeriod.DefaultPeriodType.LastEntireMonth;
public relativeToday:boolean=true;
public firstDayOfWeek:number=1;
}

View File

@ -0,0 +1,73 @@
"use strict";
import {DefaultPeriodType,IPeriod,Period} from "./datePeriod";
import * as moment from "moment";
class RelativePeriod {
periodType: DefaultPeriodType;
private _period: IPeriod;
get period(): IPeriod {
return this._period;
}
public constructor(periodType: DefaultPeriodType, period: IPeriod) {
console.debug("RelativePeriod constructor start,preiodType:",periodType);
this.periodType = periodType;
this._period = period;
console.debug(period.dateStart+"~"+period.dateEnd);
}
}
export class RelativeReriodHelper {
private _relativePeriods: RelativePeriod[] = [];
private _baseMoment: moment.Moment;
get baseMoment(){
return moment(this._baseMoment);
}
public getPeriod(periodType: DefaultPeriodType): IPeriod {
console.debug("RelativeReriodHelper getPeriod start");
let result: IPeriod;
console.log("input preiodType",periodType);
for (const key in this._relativePeriods) {
if (this._relativePeriods.hasOwnProperty(key)) {
console.debug("key",key);
let relativePeriod = this._relativePeriods[key];
console.debug(relativePeriod.periodType);
if (relativePeriod.periodType == periodType) {
result = relativePeriod.period;
console.debug("period found",result.dateStart+"~"+result.dateEnd);
}
}
}
return result;
}
public constructor(relativeToday: boolean,firstDayOfWeek:number) {
console.debug("RelativePeriod helper constructor start");
moment.locale("cn",{
week:{
dow:firstDayOfWeek,
doy:7
}
});
this._baseMoment = relativeToday ? moment() : moment().subtract(1, "day");
this._relativePeriods.push(this.getLastWeek(), this.getLastMonth(), this.getLastEntireWeek(), this.getLastEntireMonth());
console.debug("this._baseMoment:" + this.baseMoment.format());
console.debug("RelativePeriodHelper constuctor end");
}
private getLastWeek(): RelativePeriod {
const start: Date = this.baseMoment.subtract(6, "days").startOf("day").toDate();
const end: Date = this.baseMoment.endOf("day").toDate();
return new RelativePeriod(DefaultPeriodType.LastWeek, new Period(start, end));
}
private getLastMonth(): RelativePeriod {
const start: Date = this.baseMoment.subtract(1, "month").add(1, "day").startOf("day").toDate();
const end: Date = this.baseMoment.endOf("day").toDate();
return new RelativePeriod(DefaultPeriodType.LastMonth, new Period(start, end));
}
private getLastEntireMonth(): RelativePeriod {
const start: Date = this.baseMoment.subtract(1, "month").startOf("month").toDate();
const end: Date = this.baseMoment.subtract(1, "month").endOf("month").toDate();
return new RelativePeriod(DefaultPeriodType.LastEntireMonth, new Period(start, end));
}
private getLastEntireWeek(): RelativePeriod {
const start: Date = this.baseMoment.subtract(1, "week").startOf("week").toDate();
const end: Date = this.baseMoment.subtract(1, "week").endOf("week").toDate();
return new RelativePeriod(DefaultPeriodType.LastEntireWeek, new Period(start, end));
}
}

38
src/settings/settings.ts Normal file
View File

@ -0,0 +1,38 @@
/*
* Power BI Visualizations
*
* Copyright (c) Microsoft Corporation
* All rights reserved.
* MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the ""Software""), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
"use strict";
import { dataViewObjectsParser } from "powerbi-visuals-utils-dataviewutils";
import DataViewObjectsParser = dataViewObjectsParser.DataViewObjectsParser;
import {PeriodSettings} from "./datePeriod/periodSetting";
export class VisualSettings extends DataViewObjectsParser {
public period: PeriodSettings = new PeriodSettings();
}

184
src/visual.ts Normal file
View File

@ -0,0 +1,184 @@
/*
* Power BI Visual CLI
*
* Copyright (c) Microsoft Corporation
* All rights reserved.
* MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the ""Software""), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
"use strict";
//powerbi and d3
import "core-js/stable";
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 DataView = powerbi.DataView;
import VisualObjectInstanceEnumerationObject = powerbi.VisualObjectInstanceEnumerationObject;
import ISelectionManager = powerbi.extensibility.ISelectionManager;
import IVisualHost = powerbi.extensibility.visual.IVisualHost;
import ISelectionId = powerbi.extensibility.ISelectionId;
import * as d3 from "d3";
type Selection<T extends d3.BaseType> = d3.Selection<T, any, any, any>;
import { VisualSettings } from "./settings/settings";
import { stratify } from "d3";
import * as models from 'powerbi-models';
import { IAdvancedFilter } from "powerbi-models";
//custom
import { IPeriod, Period, DefaultPeriodType } from "./settings/datePeriod/datePeriod";
import { RelativeReriodHelper } from "./settings/datePeriod/relativePeriodHelper";
import { IPeriodSelectorManager, PeriodSelectorManager } from "./settings/datePeriod/periodSelectorManager";
//third party
import * as moment from "moment";
export class Visual implements IVisual {
//pbi
private host: IVisualHost;
private settings: VisualSettings;
private category: powerbi.DataViewCategoryColumn;
private selectionManager: powerbi.extensibility.ISelectionManager;
//others
private container: Selection<HTMLElement>;
private periodSelectorManager: IPeriodSelectorManager;
constructor(options: VisualConstructorOptions) {
//pbi
//console.log('Visual constructor', options);
console.debug("visual constructor start");
this.host = options.host;
this.selectionManager=this.host.createSelectionManager();
//others
this.container = d3.select(options.element).classed("container", true);
if (document) {
const dateSelector_Start = this.container.append("input")
.attr("type", "date")
.style("margin", "2px 10px 2px 2px");
const dateSelector_End = this.container.append("input")
.attr("type", "date")
.style("margin", "2px 0px 0px 2px");
dateSelector_Start.on("input change", () => { this.filterPeriod(); });
dateSelector_End.on("input change", () => { this.filterPeriod(); });
this.periodSelectorManager = new PeriodSelectorManager(dateSelector_Start, dateSelector_End);
//Select datePeriod when click this button
this.container.on('contextmenu', () => {
const mouseEvent: MouseEvent = d3.event as MouseEvent;
//const eventTarget: EventTarget = mouseEvent.target;
//let dataPoint = d3.select(eventTarget).datum();
this.selectionManager.showContextMenu({}, {
x: mouseEvent.clientX,
y: mouseEvent.clientY
});
mouseEvent.preventDefault();
});
}
}
public update(options: VisualUpdateOptions) {
console.debug("update start");
//pbi
this.settings = Visual.parseSettings(options && options.dataViews && options.dataViews[0]);
let dataView = options.dataViews[0];
console.debug("dataView", dataView);
//set date series
this.category = dataView.categorical.categories[0];
//set new default period
let newDefaultPeriod: IPeriod = new Period();
if (this.settings.period.defaultPeriodType == DefaultPeriodType.Custom) {
console.debug("user select custom defaultPeriod");
dataView.categorical.values.map((messure: powerbi.DataViewValueColumn, index: number) => {
console.debug("1");
console.debug(messure.values[0]);
console.debug("2");
let messureDate: Date = moment(messure.values[0].toString()).startOf("day").toDate();
console.debug("messureDate", messureDate);
if (messure.source.roles["StartDate"]) {
newDefaultPeriod.dateStart = messureDate;
}
if (messure.source.roles["EndDate"]) {
newDefaultPeriod.dateEnd = messureDate;
}
});
} else {
console.debug("user select " + this.settings.period.defaultPeriodType.toString() + "\ defaultPeriod");
console.debug("firstDayOfWeek", this.settings.period.firstDayOfWeek);
let relativePeriodHelper: RelativeReriodHelper = new RelativeReriodHelper(this.settings.period.relativeToday, this.settings.period.firstDayOfWeek);
newDefaultPeriod = relativePeriodHelper.getPeriod(this.settings.period.defaultPeriodType);
}
this.periodSelectorManager.defaultPeriod = newDefaultPeriod;
console.debug("update end");
}
private filterPeriod() {
//determine period from dateSelectors
console.debug("filter start");
let period: IPeriod = this.periodSelectorManager.period;
let target: models.IFilterColumnTarget;
try {
target = {
table: this.category.source.queryName.substr(0, this.category.source.queryName.indexOf('.')), // table
column: this.category.source.displayName // col1
};
}
catch (e) {
console.log(e);
}
//filter
let conditions: models.IAdvancedFilterCondition[] = [];
if (period.dateStart) {
conditions.push(
{
operator: "GreaterThanOrEqual",
value: period.dateStart.toJSON()
}
);
}
if (period.dateEnd) {
conditions.push(
{
operator: "LessThanOrEqual",
value: period.dateEnd.toJSON()
}
);
}
let filter: IAdvancedFilter = {
"$schema": "http://powerbi.com/product/schema#advanced",
"target": target,
"filterType": models.FilterType.Advanced,
"logicalOperator": "And",
"conditions": conditions
};
this.host.applyJsonFilter((period.dateStart || period.dateEnd) ? filter : null, "general", "filter", powerbi.FilterAction.merge);
console.debug("applyFilter end");
}
private static parseSettings(dataView: DataView): VisualSettings {
return <VisualSettings>VisualSettings.parse(dataView);
}
/**
* 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);
}
}

View File

@ -0,0 +1,27 @@
{
"Role_Dates_DisplayName":"日期序列",
"Role_Dates_Discription":"请放置日期列",
"Role_StartDate_DisplayName":"默认开始日期",
"Role_StartDate_Discription":"可以使用度量值指定切片器的默认开始日期",
"Role_DefaultEndDate_DisplayName":"默认结束日期",
"Role_DefaultEndDate_Discription":"可以使用度量值指定切片器的默认结束日期",
"Obj_Period_DisplayName":"日期段",
"Obj_Period_Discription":"日期段选项",
"Period_DefaultPeriodType_DisplayName":"默认日期段",
"Period_DefaultPeriodType_Discription":"选择如何确定切片器日期首尾默认值",
"LastMonth":"最近一个月",
"LastEntireMonth":"最近一个完整月",
"LastWeek":"最近一周",
"LastEntireWeek":"最近一个完整周",
"Custom":"自定义(根据度量值)",
"Period_RelativeToday_DisplayName":"包含今天",
"Period_RelativeToday_Discription":"当默认日期项没有选择自定义时,此选项用于确定相对日期是否包含今日",
"Period_FirstDayOfWeek_DisplayName":"一周的第一天",
"Sunday":"星期天",
"Monday":"星期一",
"Tuesday":"星期二",
"Wednesday":"星期三",
"Thursday":"星期四",
"Friday":"星期五",
"Saturday":"星期六"
}

View File

@ -0,0 +1,32 @@
{
"locale":"zh-CN",
"values":{
"Role_Dates_DisplayName":"日期序列",
"Role_Dates_Discription":"请放置日期列",
"Role_StartDate_DisplayName":"默认开始日期",
"Role_StartDate_Discription":"可以使用度量值指定切片器的默认开始日期",
"Role_DefaultEndDate_DisplayName":"默认结束日期",
"Role_DefaultEndDate_Discription":"可以使用度量值指定切片器的默认结束日期",
"Obj_Period_DisplayName":"日期段",
"Obj_Period_Discription":"日期段选项",
"Period_DefaultPeriodType_DisplayName":"默认日期段",
"Period_DefaultPeriodType_Discription":"选择如何确定切片器日期首尾默认值",
"LastMonth":"最近一个月",
"LastEntireMonth":"最近一个完整月",
"LastWeek":"最近一周",
"LastEntireWeek":"最近一个完整周",
"Custom":"自定义(根据度量值)",
"Period_RelativeToday_DisplayName":"包含今天",
"Period_RelativeToday_Discription":"当默认日期项没有选择自定义时,此选项用于确定相对日期是否包含今日",
"Period_FirstDayOfWeek_DisplayName":"一周的第一天",
"Sunday":"星期天",
"Monday":"星期一",
"Tuesday":"星期二",
"Wednesday":"星期三",
"Thursday":"星期四",
"Friday":"星期五",
"Saturday":"星期六"
}
}

10
style/visual.less Normal file
View File

@ -0,0 +1,10 @@
@import (less) "node_modules/powerbi-visuals-utils-interactivityutils/lib/index.css";
p {
font-size: 20px;
font-weight: bold;
em {
background: yellow;
padding: 5px;
}
}

4
test/datePeriod.js Normal file
View File

@ -0,0 +1,4 @@
import "../src/settings/datePeriod/datePeriod";
import { RelativeReriodHelper } from "../src/settings/datePeriod/datePeriod";
let r=new RelativeReriodHelper();
r.getLastWeek();

19
tsconfig.json Normal file
View File

@ -0,0 +1,19 @@
{
"compilerOptions": {
"allowJs": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es6",
"sourceMap": true,
"outDir": "./.tmp/build/",
"moduleResolution": "node",
"declaration": true,
"lib": [
"es2015",
"dom"
]
},
"files": [
"./src/visual.ts"
]
}

9
tslint.json Normal file
View File

@ -0,0 +1,9 @@
{
"extends": "tslint-microsoft-contrib/recommended",
"rulesDirectory": [
"node_modules/tslint-microsoft-contrib"
],
"rules": {
"no-relative-imports": false
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long