I think that I have found a magic way to implement sync slicers for a slicer-visual with a field and some messures

This commit is contained in:
沐见南 2020-05-03 23:50:25 +08:00
parent 084a65c507
commit d1ad27312b
7 changed files with 47 additions and 16 deletions

View File

@ -1,4 +1,5 @@
{ {
"supportsSynchronizingFilterState": true,
"dataRoles": [ "dataRoles": [
{ {
"displayName": "Field", "displayName": "Field",

6
package-lock.json generated
View File

@ -286,6 +286,12 @@
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.7.tgz", "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.7.tgz",
"integrity": "sha512-wE2v81i4C4Ol09RtsWFAqg3BUitWbHSpSlIo+bNdsCJijO9sjme+zm+73ZMCa/qMC8UEERxzGbvmr1cffo2SiQ==" "integrity": "sha512-wE2v81i4C4Ol09RtsWFAqg3BUitWbHSpSlIo+bNdsCJijO9sjme+zm+73ZMCa/qMC8UEERxzGbvmr1cffo2SiQ=="
}, },
"@types/node": {
"version": "13.13.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.4.tgz",
"integrity": "sha512-x26ur3dSXgv5AwKS0lNfbjpCakGIduWU1DU91Zz58ONRWrIKGunmZBNv4P7N+e27sJkiGDsw/3fT4AtsqQBrBA==",
"dev": true
},
"ansi-styles": { "ansi-styles": {
"version": "3.2.1", "version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",

View File

@ -17,6 +17,7 @@
"powerbi-visuals-utils-dataviewutils": "2.2.1" "powerbi-visuals-utils-dataviewutils": "2.2.1"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^13.13.4",
"ts-loader": "6.1.0", "ts-loader": "6.1.0",
"tslint": "^5.18.0", "tslint": "^5.18.0",
"tslint-microsoft-contrib": "^6.2.0", "tslint-microsoft-contrib": "^6.2.0",

View File

@ -21,6 +21,7 @@ export class SelectorManager implements ISelectorManager{
this.selectorContainer=selectorContainer; this.selectorContainer=selectorContainer;
this.filterManager=filterManager; this.filterManager=filterManager;
} }
updateFormat(visualSettings:settings.VisualSettings,width:number,height:number): void { updateFormat(visualSettings:settings.VisualSettings,width:number,height:number): void {
console.debug('selectorManager updateFormat start'); console.debug('selectorManager updateFormat start');
console.debug('visualSettings:',visualSettings); console.debug('visualSettings:',visualSettings);

View File

@ -62,6 +62,7 @@ export class DropDownSelector extends Selector {
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",false);
let filterManager: IFilterManager = this.filterManager; let filterManager: IFilterManager = this.filterManager;
//on change, filter
this.dropDown.on("input change", function () { this.dropDown.on("input change", function () {
console.debug('DropDownSelector:', "input change"); console.debug('DropDownSelector:', "input change");
console.debug('this', this); console.debug('this', this);

View File

@ -36,6 +36,7 @@ import VisualObjectInstance = powerbi.VisualObjectInstance;
import DataView = powerbi.DataView; import DataView = powerbi.DataView;
import VisualObjectInstanceEnumerationObject = powerbi.VisualObjectInstanceEnumerationObject; import VisualObjectInstanceEnumerationObject = powerbi.VisualObjectInstanceEnumerationObject;
import IVisualEventService = powerbi.extensibility.IVisualEventService; import IVisualEventService = powerbi.extensibility.IVisualEventService;
import SelectionManager=powerbi.extensibility.ISelectionManager;
import * as visualInterfaces from "./visualInterfaces"; import * as visualInterfaces from "./visualInterfaces";
import IVisualHost = powerbi.extensibility.visual.IVisualHost; import IVisualHost = powerbi.extensibility.visual.IVisualHost;
import { VisualSettings } from "../settings/visualSettings"; import { VisualSettings } from "../settings/visualSettings";
@ -43,7 +44,9 @@ import {FilterManager,ManagerFactory,SelectorManager,LayoutManager} from "../man
import * as d3 from "d3"; import * as d3 from "d3";
import { getObject } from "powerbi-visuals-utils-dataviewutils/lib/dataViewObjects"; import { getObject } from "powerbi-visuals-utils-dataviewutils/lib/dataViewObjects";
import { getMeasureIndexOfRole } from "powerbi-visuals-utils-dataviewutils/lib/dataRoleHelper"; import { getMeasureIndexOfRole } from "powerbi-visuals-utils-dataviewutils/lib/dataRoleHelper";
import { selector } from "d3"; import { selector, json } from "d3";
import { debuglog } from "util";
export class Visual implements IVisual { export class Visual implements IVisual {
/* /*
SelectorManager: a custom manager, used to manage dropDownSelector, listSelector, calendarSelector, and so on SelectorManager: a custom manager, used to manage dropDownSelector, listSelector, calendarSelector, and so on
@ -51,28 +54,35 @@ export class Visual implements IVisual {
*/ */
private events: IVisualEventService; private events: IVisualEventService;
private settings: VisualSettings; private settings: VisualSettings;
private selectionManager:SelectionManager;
private layoutManager: visualInterfaces.ILayoutManager; private layoutManager: visualInterfaces.ILayoutManager;
private selectorManager: visualInterfaces.ISelectorManager; private selectorManager: visualInterfaces.ISelectorManager;
private filterManager:visualInterfaces.IFilterManager; private filterManager:visualInterfaces.IFilterManager;
private readonly id:number;
private isFirstUpdate:boolean=true;
//private selectionManager:powerbi.extensibility.ISelectionManager; //private selectionManager:powerbi.extensibility.ISelectionManager;
constructor(options: VisualConstructorOptions) { constructor(options: VisualConstructorOptions) {
console.debug('Visual constructor', options); console.debug('Visual constructor start');
this.events = options.host.eventService; this.events = options.host.eventService;
if (document) { if (document) {
//this.selectionManager =options.host.createSelectionManager(); //this.selectionManager =options.host.createSelectionManager();
let container=d3.select(options.element).append("div").classed("container",true); let container=d3.select(options.element).append("div").classed("container",true);
//overload context menu //overload context menu
// d3.select(options.element).on('contextmenu', () => { let coverContextMenu=false;
// const mouseEvent: MouseEvent = <MouseEvent>d3.event; if(coverContextMenu){
// //const eventTarget: EventTarget = mouseEvent.target; d3.select(options.element).on('contextmenu', () => {
// //let dataPoint = d3.select(eventTarget).datum(); const mouseEvent: MouseEvent = <MouseEvent>d3.event;
// this.selectionManager.showContextMenu({}, { //const eventTarget: EventTarget = mouseEvent.target;
// x: mouseEvent.clientX, //let dataPoint = d3.select(eventTarget).datum();
// y: mouseEvent.clientY this.selectionManager.showContextMenu({}, {
// }); x: mouseEvent.clientX,
// //mouseEvent.preventDefault(); y: mouseEvent.clientY
// }); });
//mouseEvent.preventDefault();
});
}
//First, create the filterManager //First, create the filterManager
this.filterManager=ManagerFactory.CreateFilterManager(FilterManager,options.host); this.filterManager=ManagerFactory.CreateFilterManager(FilterManager,options.host);
@ -82,12 +92,15 @@ export class Visual implements IVisual {
//SelectorManager manage selectors //SelectorManager manage selectors
let selectorContainer=container.append("div").classed("selector-container",true); let selectorContainer=container.append("div").classed("selector-container",true);
this.selectorManager=ManagerFactory.CreateSelectorManager(SelectorManager,selectorContainer,this.filterManager); this.selectorManager=ManagerFactory.CreateSelectorManager(SelectorManager,selectorContainer,this.filterManager);
//set id
this.id=Math.random();
} }
console.debug('end constructor'); console.debug('end constructor');
} }
public update(options: VisualUpdateOptions) { public update(options: VisualUpdateOptions) {
console.debug('visual update start'); console.debug('visual update start, id=',this.id);
this.events.renderingStarted(options); this.events.renderingStarted(options);
this.settings = Visual.parseSettings(options && options.dataViews && options.dataViews[0]); this.settings = Visual.parseSettings(options && options.dataViews && options.dataViews[0]);
let dataView=options.dataViews[0]; let dataView=options.dataViews[0];
@ -117,14 +130,20 @@ export class Visual implements IVisual {
console.debug("start filterManager updateView"); console.debug("start filterManager updateView");
this.filterManager.update(field); this.filterManager.update(field);
console.debug("start selectorManager updateView"); console.debug("previous filter",JSON.stringify(options.jsonFilters));
if(this.isFirstUpdate&&options.jsonFilters){
//Sync slicers
console.debug('Sync slicers start');
}
console.debug("start selectorManager update");
console.debug("isFirstUpdate:",this.isFirstUpdate);
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('visual update end'); console.debug('visual update end');
this.isFirstUpdate=false;
this.events.renderingFinished(options); this.events.renderingFinished(options);
} }
private static parseSettings(dataView: DataView): VisualSettings { private static parseSettings(dataView: DataView): VisualSettings {
return <VisualSettings>VisualSettings.parse(dataView); return <VisualSettings>VisualSettings.parse(dataView);
} }

View File

@ -21,12 +21,14 @@ export interface ILayoutManager{
} }
export interface ILayoutManagerConstructor{ export interface ILayoutManagerConstructor{
new(container:Selection<HTMLElement>,filterManager:IFilterManager):ILayoutManager; new(container:Selection<HTMLElement>,filterManager:IFilterManager):ILayoutManager;
}; }
//ISelectorManager //ISelectorManager
export interface ISelectorManager{ export interface ISelectorManager{
selectorContainer:Selection<HTMLElement>; selectorContainer:Selection<HTMLElement>;
filterManager:IFilterManager; filterManager:IFilterManager;
dispose():void; dispose():void;
updateData(field:powerbi.DataViewCategoryColumn,defaultSelect:powerbi.DataViewValueColumn,defaultStart:powerbi.DataViewValueColumn,defaultEnd:powerbi.DataViewValueColumn):void; updateData(field:powerbi.DataViewCategoryColumn,defaultSelect:powerbi.DataViewValueColumn,defaultStart:powerbi.DataViewValueColumn,defaultEnd:powerbi.DataViewValueColumn):void;
updateFormat(visualSettings:VisualSettings,width:number,height:number):void; updateFormat(visualSettings:VisualSettings,width:number,height:number):void;