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": [
{
"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",
"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": {
"version": "3.2.1",
"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"
},
"devDependencies": {
"@types/node": "^13.13.4",
"ts-loader": "6.1.0",
"tslint": "^5.18.0",
"tslint-microsoft-contrib": "^6.2.0",

View File

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

View File

@ -62,6 +62,7 @@ export class DropDownSelector extends Selector {
this.container = container;
this.dropDown = this.container.append("select").classed("dropDown-selector", true).classed("selector", true);//.attr("multiple",false);
let filterManager: IFilterManager = this.filterManager;
//on change, filter
this.dropDown.on("input change", function () {
console.debug('DropDownSelector:', "input change");
console.debug('this', this);

View File

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

View File

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