Add ReadMe.md; Compare jsonFilters to judge restore or common

This commit is contained in:
沐见南 2020-05-05 15:37:34 +08:00
parent 3d759644d1
commit ad38c05613
7 changed files with 78 additions and 21 deletions

22
ReadMe.md Normal file
View File

@ -0,0 +1,22 @@
# A utility slicer for Power Bi
Assign default selection to this slicer by messures, just use DAX!
## Functionalities
* Implemented
1. Dropdown-slicer for text field
1. Use DAX to assign **single** default selected items to the dropdown-slicer
1. Support async slicers
* Planned
1. List-slicer for text field
1. Use DAX to assign **one** default selected items to the list-slicer
1. Use DAX to assign **multiple** default selected items to the dropdown-slicer and list-slicer
1. Range-slicer for number field
1. Use DAX to assign default selected range to the range-slicer
1. Single-date-slicer for datetime field
1. Use DAX to assign default selected date to the single-date-slicer
1. Period-slicer for datetime field
1. Use DAX to assign default selected period to the period-slicer
## Known issures
1. Slicer components for number field and datetime field are in developing, just slicer for text field is usable now
1. The outline setting has no effectivity on dropdown items
1. I can't change background-color of dropdown items
1. This slicer wouldn't support bookmarks

5
package-lock.json generated
View File

@ -905,6 +905,11 @@
"resolved": "https://registry.npmjs.org/powerbi-visuals-utils-dataviewutils/-/powerbi-visuals-utils-dataviewutils-2.2.1.tgz", "resolved": "https://registry.npmjs.org/powerbi-visuals-utils-dataviewutils/-/powerbi-visuals-utils-dataviewutils-2.2.1.tgz",
"integrity": "sha512-Ai+TM1gj6DpAsNbn0IhOwUCAPfcaH4Z7y6Ow2OwAfbxNpELwQSF0S8D+vlJN2AoqV/ruQhnEngUC88mMFNyvJQ==" "integrity": "sha512-Ai+TM1gj6DpAsNbn0IhOwUCAPfcaH4Z7y6Ow2OwAfbxNpELwQSF0S8D+vlJN2AoqV/ruQhnEngUC88mMFNyvJQ=="
}, },
"powerbi-visuals-utils-typeutils": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/powerbi-visuals-utils-typeutils/-/powerbi-visuals-utils-typeutils-2.2.1.tgz",
"integrity": "sha512-xm5xNBVudCiU9ZZggsLlpHr+a4bnHtgw6Cy1UtNM/zILtOE2HUamjw+yZovLe6YNov4N2EaCmPO8XPhcXkuz+A=="
},
"process-nextick-args": { "process-nextick-args": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",

View File

@ -14,7 +14,8 @@
"d3": "5.12.0", "d3": "5.12.0",
"powerbi-models": "^1.3.3", "powerbi-models": "^1.3.3",
"powerbi-visuals-api": "~2.6.1", "powerbi-visuals-api": "~2.6.1",
"powerbi-visuals-utils-dataviewutils": "2.2.1" "powerbi-visuals-utils-dataviewutils": "2.2.1",
"powerbi-visuals-utils-typeutils": "^2.2.1"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^13.13.4", "@types/node": "^13.13.4",

View File

@ -11,12 +11,17 @@ import { select, json } from "d3";
export class FilterManager implements IFilterManager{ export class FilterManager implements IFilterManager{
private target: models.IFilterColumnTarget={table:'',column:''}; private target: models.IFilterColumnTarget={table:'',column:''};
private host:IVisualHost; private host:IVisualHost;
private jsonFilter:powerbi.IFilter; private _jsonFilter:powerbi.IFilter;
public get jsonFilter() : powerbi.IFilter {
return this._jsonFilter;
}
constructor(host:IVisualHost){ constructor(host:IVisualHost){
this.host=host; this.host=host;
} }
setFilter(jsonFilter: powerbi.IFilter,applyNow:boolean): void { setFilter(jsonFilter: powerbi.IFilter,applyNow:boolean): void {
this.jsonFilter=jsonFilter; this._jsonFilter=jsonFilter;
if(applyNow){ if(applyNow){
this.applyJsonFilter(); this.applyJsonFilter();
} }
@ -24,7 +29,7 @@ export class FilterManager implements IFilterManager{
public applyJsonFilter():void{ public applyJsonFilter():void{
console.debug('filter manager applyJsonFilter start'); console.debug('filter manager applyJsonFilter start');
this.host.applyJsonFilter(this.jsonFilter,'general','filter',powerbi.FilterAction.merge); this.host.applyJsonFilter(this._jsonFilter,'general','filter',powerbi.FilterAction.merge);
console.debug('filter manager applyJsonFilter end'); console.debug('filter manager applyJsonFilter end');
} }
@ -61,7 +66,7 @@ export class FilterManager implements IFilterManager{
"values": selection "values": selection
} }
console.debug("jsonFilter:",jsonFilter); console.debug("jsonFilter:",jsonFilter);
this.jsonFilter=jsonFilter; this._jsonFilter=jsonFilter;
if(applyNow){ if(applyNow){
this.applyJsonFilter(); this.applyJsonFilter();
} }

View File

@ -4,6 +4,7 @@ import powerbi from "powerbi-visuals-api";
import * as d3 from "d3"; import * as d3 from "d3";
import { selection } from "d3"; import { selection } from "d3";
type Selection<T extends d3.BaseType> = d3.Selection<T, any, any, any>; type Selection<T extends d3.BaseType> = d3.Selection<T, any, any, any>;
import {pixelConverter} from "powerbi-visuals-utils-typeutils";
export class DropDownSelector extends Selector { export class DropDownSelector extends Selector {
public select(items: string[]): void { public select(items: string[]): void {
@ -25,7 +26,7 @@ export class DropDownSelector extends Selector {
this.dropDown.style('background-color', itemsSetting.backgroundColor) this.dropDown.style('background-color', itemsSetting.backgroundColor)
.attr('postion','absolute') .attr('postion','absolute')
.style('color', itemsSetting.fontColor) .style('color', itemsSetting.fontColor)
.style('font-size', itemsSetting.textSize + 'px') .style('font-size',pixelConverter.fromPointToPixel(itemsSetting.textSize) + 'px')
.style('width', (width - 10) + 'px') .style('width', (width - 10) + 'px')
.style('border-style', settings.Enums.getOutlineStyle(itemsSetting.outline)) .style('border-style', settings.Enums.getOutlineStyle(itemsSetting.outline))
.style('border-width', '2px') .style('border-width', '2px')
@ -37,8 +38,7 @@ export class DropDownSelector extends Selector {
.style('width', (width - 10) + 'px') .style('width', (width - 10) + 'px')
.style('border-style', settings.Enums.getOutlineStyle(itemsSetting.outline)) .style('border-style', settings.Enums.getOutlineStyle(itemsSetting.outline))
.style('border-width', '2px') .style('border-width', '2px')
.style('border-color', 'black') .style('border-color', 'black');
.style('maxHeight','200px');
} }
console.debug('dropDownSelector updateFormat end'); console.debug('dropDownSelector updateFormat end');
} }
@ -73,7 +73,7 @@ export class DropDownSelector extends Selector {
protected createView(container: Selection<HTMLDivElement>) { protected createView(container: Selection<HTMLDivElement>) {
console.debug('dropDownViewManager', 'createView start'); console.debug('dropDownViewManager', 'createView start');
this.container = container; this.container = container;
this.dropDown = this.container.append("select").classed("dropDown-selector", true).classed("selector", true);//.attr("multiple",false); this.dropDown = this.container.append("select").classed("dropDown-selector", true).classed("selector", true);//.attr('multiple',true);
let dropDownSelector=this; let dropDownSelector=this;
//on change, filter //on change, filter
this.dropDown.on("input change", function () { this.dropDown.on("input change", function () {
@ -95,6 +95,7 @@ export class DropDownSelector extends Selector {
} }
console.debug("this", this.selectedOptions); console.debug("this", this.selectedOptions);
}); });
console.debug('dropDownViewManager', 'createView end'); console.debug('dropDownViewManager', 'createView end');
} }
@ -116,6 +117,7 @@ export class DropDownSelector extends Selector {
newDefaultSelect = defaultSelect.values[0].toString(); newDefaultSelect = defaultSelect.values[0].toString();
console.debug('newDefaultSelect:', newDefaultSelect); console.debug('newDefaultSelect:', newDefaultSelect);
} }
//let values=field.values
let options: d3.Selection<HTMLOptionElement, powerbi.PrimitiveValue, HTMLSelectElement, any> = <d3.Selection<HTMLOptionElement, powerbi.PrimitiveValue, HTMLSelectElement, any>>this.dropDown.selectAll("option").data(field.values, function (d) { return d.toString(); });//map data let options: d3.Selection<HTMLOptionElement, powerbi.PrimitiveValue, HTMLSelectElement, any> = <d3.Selection<HTMLOptionElement, powerbi.PrimitiveValue, HTMLSelectElement, any>>this.dropDown.selectAll("option").data(field.values, function (d) { return d.toString(); });//map data
options.exit().remove();//delete options.exit().remove();//delete
@ -125,6 +127,7 @@ export class DropDownSelector extends Selector {
.text(function (d) { return d.toString(); }) .text(function (d) { return d.toString(); })
.attr('label', function (d) { return d.toString(); }) .attr('label', function (d) { return d.toString(); })
.classed('dropDown-option', true) .classed('dropDown-option', true)
.attr('title',function (d) { return d.toString(); })
.merge(options) .merge(options)
.attr("selected", function (d) { .attr("selected", function (d) {
console.debug('d.toString():', d.toString()); console.debug('d.toString():', d.toString());
@ -134,7 +137,11 @@ export class DropDownSelector extends Selector {
console.debug('Set defaultSelection end'); console.debug('Set defaultSelection end');
} else { } else {
console.debug('defaultSelection not reset, start update options'); console.debug('defaultSelection not reset, start update options');
options=options.enter().append("option").text(function (d) { return d.toString(); }).attr('label', function (d) { return d.toString(); }).classed('dropDown-option', true).merge(options);//add options=options.enter().append("option")
.text(function (d) { return d.toString(); })
.attr('label', function (d) { return d.toString(); })
.attr('title',function (d) { return d.toString(); })
.attr('label', function (d) { return d.toString(); }).classed('dropDown-option', true).merge(options);//add
console.debug('defaultSelection not reset, end update options'); console.debug('defaultSelection not reset, end update options');
} }

View File

@ -84,7 +84,6 @@ export class Visual implements IVisual {
}); });
} }
//First, create the filterManager //First, create the filterManager
this.filterManager=ManagerFactory.CreateFilterManager(FilterManager,options.host); this.filterManager=ManagerFactory.CreateFilterManager(FilterManager,options.host);
//Then, layoutManager and selectorManager, both use the filterManager //Then, layoutManager and selectorManager, both use the filterManager
@ -142,18 +141,35 @@ export class Visual implements IVisual {
this.selectorManager.updateData(field,defaultSelect,defaultStart,defaultEnd); this.selectorManager.updateData(field,defaultSelect,defaultStart,defaultEnd);
this.selectorManager.updateFormat(this.settings,width,height); this.selectorManager.updateFormat(this.settings,width,height);
console.debug("previous filter",JSON.stringify(options.jsonFilters)); console.debug("previous filter",JSON.stringify(options.jsonFilters));
if(this.isFirstUpdate&&options.jsonFilters&&options.jsonFilters[0]){ /*
Compare two jsonFilters(filterManager.jsonFilter and options.jsonFilters[0]).
Use method JSON.stringify.
1. filterManager.jsonFilter is null, options.jsonFilter[0] is null
Don't restore
2. filterManager.jsonFilter is Null, options.jsonFilter[0] is not null
Restore
3. filterManager.jsonFilter is not null, options.jsonFilter[0] is null
Don't restore
4. filterManager.jsonFilter != options.jsonFilter[0]
Restore
5. filterManager.jsonFilter == options.jsonFilter[0]
Don't restore
*/
if(options.jsonFilters&&options.jsonFilters[0]&&this.isFirstUpdate){
console.debug('options.jsonFilters[0] is not null');
if((!this.filterManager.jsonFilter)||
(JSON.stringify(this.filterManager.jsonFilter)!=JSON.stringify(options.jsonFilters[0]))){
//Sync slicers //Sync slicers
console.debug('Sync slicers init end'); console.debug('Sync slicers init or restore a bookmark start');
this.filterManager.setFilter(options.jsonFilters[0],false); this.filterManager.setFilter(options.jsonFilters[0],false);
this.selectorManager.select(options.jsonFilters[0]['values']) this.selectorManager.select(options.jsonFilters[0]['values'])
console.debug('Sync slicers init end'); console.debug('Sync slicers init or restore a bookmark end');
}//end if
}else{ }else{
console.debug('Neednt init a sync slicer'); console.debug('Neednt init a sync slicer or restore a bookmark');
} }
console.debug("isFirstUpdate:",this.isFirstUpdate);
this.isFirstUpdate=false;
console.debug('visual update end'); console.debug('visual update end');
this.isFirstUpdate=false;
this.filterManager.applyJsonFilter(); this.filterManager.applyJsonFilter();
this.events.renderingFinished(options); this.events.renderingFinished(options);
} }

View File

@ -43,6 +43,7 @@ export interface ISelectorManagerConstructor{
//IFilterManager //IFilterManager
export interface IFilterManager{ export interface IFilterManager{
jsonFilter:powerbi.IFilter;
update(field:powerbi.DataViewCategoryColumn):void; update(field:powerbi.DataViewCategoryColumn):void;
setFilter_String(selection:string[],applyNow:boolean):void; setFilter_String(selection:string[],applyNow:boolean):void;
setFilter(jsonFilter:powerbi.IFilter,applyNow:boolean):void; setFilter(jsonFilter:powerbi.IFilter,applyNow:boolean):void;