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:
parent
084a65c507
commit
d1ad27312b
@ -1,4 +1,5 @@
|
||||
{
|
||||
"supportsSynchronizingFilterState": true,
|
||||
"dataRoles": [
|
||||
{
|
||||
"displayName": "Field",
|
||||
|
6
package-lock.json
generated
6
package-lock.json
generated
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user