Hi everyone. I'm developing a pie chart visual. I am currently dealing with it's property settings. other than the already defined datapointSettings , I have added a Legend property to the pane, But i'm not able to change it's value or retrieve it.
Can someone help? I'm a beginner,so this could be some silly mistake.
Here's my code :
visual.ts
module powerbi.extensibility.visual { "use strict"; interface Data { quantity: number; category: string; color:string; selectionId:ISelectionId; } interface PieChartArc { datapoints: Data[]; // setting: pieChartSettings; dataview: DataView[]; } interface pieChartSettings { Legend : { show: boolean; }; } function visualTransform(options:VisualUpdateOptions,host:IVisualHost) : PieChartArc { let dataViews=options.dataViews; let viewModel: PieChartArc= { datapoints:[], //setting : defaultSetting, dataview:dataViews }; if (!dataViews || !dataViews[0] || !dataViews[0].categorical || !dataViews[0].categorical.categories || !dataViews[0].categorical.categories[0].source || !dataViews[0].categorical.values) return viewModel; let categorical=dataViews[0].categorical; let category=categorical.categories[0]; let dataValue=categorical.values[0]; let pieChartData: Data[]=[]; let colorPalette: IColorPalette=host.colorPalette; let objects= dataViews[0].metadata.objects /* let pieChartSetting: pieChartSettings={ Legend:{ show: getValue<boolean>(objects,'Legend','show',defaultSetting.Legend.show) } }*/ for(let i=0;i<Math.max(category.values.length,dataValue.values.length);i++) { pieChartData.push({ quantity:<number>dataValue.values[i], category:<string>category.values[i], color:colorPalette.getColor(<string>category.values[i]).value, selectionId:host.createSelectionIdBuilder() .withCategory(category, i) .createSelectionId() }); console.log(pieChartData[i].color); } return { datapoints: pieChartData, //setting: pieChartSetting, dataview: dataViews }; } export class PieChart implements IVisual { private target: HTMLElement; private settings: VisualSettings; private textNode: Text; private pieChartContainer: d3.Selection<SVGElement>; private arc: any; private host: IVisualHost; private selectionManager: ISelectionManager; private svg: d3.Selection<SVGElement>; private g: any; private pie: any; private color: string; private tooltipServiceWrapper: ITooltipServiceWrapper; private pieSettings: pieChartSettings; static data: DataView[]; static config= { solidOpacity:1, transparentOpacity:0.5, }; constructor(options: VisualConstructorOptions) { console.log('Visual constructor', options); this.target = options.element; this.host= options.host; this.selectionManager= options.host.createSelectionManager(); let svg=this.svg=d3.select(options.element) .append('svg') .classed("pieChart",true) ; this.pieChartContainer=svg.append('g').classed('pieChartContainer',true);//.attr('transform','translate('+100+',' +100+')'); this.tooltipServiceWrapper = createTooltipServiceWrapper(this.host.tooltipService, options.element); } public update(options: VisualUpdateOptions) { let viewModel: PieChartArc = visualTransform(options, this.host); PieChart.data= options.dataViews; let defaultSetting ={ Legend:{ show:true, } }; let width= options.viewport.width; let height= options.viewport.height; let radius= Math.min(width,height)/2; this.svg.attr({ width: width-20, height: height-20, }); this.arc=d3.svg.arc() .innerRadius(0) .outerRadius(radius-20); this.pie = d3.layout.pie<Data>().value((d: Data):number => d.quantity).sort(null); let fill = ((d):string=> d.data.color); let tf = (d: Data) => `translate(${this.arc.centroid(d)})`; let text = d => d.data.category; this.svg.append('g'); this.g=this.svg.selectAll('.arc') .data(this.pie(viewModel.datapoints)) .enter() .append('g') .attr('class', 'arc') .data(this.pie(viewModel.datapoints)) // .attr("fill",fill) ; let path= this.g.append('path') .attr('d', this.arc) .attr('fill',fill) .attr('fill-opacity',1) //.style("stroke","black") .attr("stroke-width","0.8"); this.g.append('text').attr('transform', tf).text(text).attr('fill',"white"); this.tooltipServiceWrapper.addTooltip(path, (tooltipEvent: TooltipEventArgs<number>) => PieChart.getTooltipData(tooltipEvent.data), (tooltipEvent: TooltipEventArgs<number>) => null); let selectionManager = this.selectionManager; path.on("click",function(d) { // path.attr('fill','blue'); selectionManager.select(d.data.selectionId).then((ids: ISelectionId[])=> { path.attr('fill-opacity',ids.length>0? PieChart.config.transparentOpacity: PieChart.config.solidOpacity); d3.select(this).attr('fill-opacity',PieChart.config.solidOpacity); (<Event>d3.event).stopPropagation; }); }); path.exit() .remove(); let objects = options.dataViews[0].metadata.objects; objects[1][0]= getValue<boolean>(objects, 'Legend', 'Legend', false); console.log(objects[1][0]); this.settings=VisualSettings.parse<VisualSettings>(options.dataViews[0]); //for testing whether property value is being changed. if(this.settings.Legend.Legend) { path.attr("fill-opacity",0.2); } } private static parseSettings(dataView: DataView): VisualSettings { return VisualSettings.parse(dataView) as VisualSettings; } /** * 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); } private static getTooltipData(value: any): VisualTooltipDataItem[] { return [{ displayName: PieChart.data[0].metadata.columns[1].displayName, value: value.value.toString(), color: value.data.color, header:value.data.category }]; } } }
capabilities.json
{ "dataRoles": [ { "displayName": "Category", "name": "category", "kind": "Grouping" }, { "displayName": "Measure", "name": "measure", "kind": "Measure" } ], "objects": { "dataPoint": { "displayName": "Data colors", "properties": { "defaultColor": { "displayName": "Default color", "type": { "fill": { "solid": { "color": true } } } }, "showAllDataPoints": { "displayName": "Show all", "type": { "bool": true } }, "fill": { "displayName": "Fill", "type": { "fill": { "solid": { "color": true } } } }, "fillRule": { "displayName": "Color saturation", "type": { "fill": {} } }, "fontSize": { "displayName": "Text Size", "type": { "formatting": { "fontSize": true } } } } }, "Legend":{ "displayName": "Legend", "properties": { "Legend" :{ "displayName": "Legend", "type": { "bool": true } } } } }, "dataViewMappings": [ { "categorical": { "categories": { "for": { "in": "category" }, "dataReductionAlgorithm": { "top": {} } }, "values": { "select": [ { "bind": { "to": "measure" } } ] } }, "conditions":[ { "category":{ "max":1 }, "measure":{ "max":1 } } ] } ] }
settings.ts
module powerbi.extensibility.visual { "use strict"; import DataViewObjectsParser = powerbi.extensibility.utils.dataview.DataViewObjectsParser; export class VisualSettings extends DataViewObjectsParser { public dataPoint: dataPointSettings = new dataPointSettings(); public Legend : LegendSettings=new LegendSettings(); } export class dataPointSettings { // Default color public defaultColor: string = ""; // Show all public showAllDataPoints: boolean; // Fill public fill: string = ""; // Color saturation public fillRule: string = ""; // Text Size public fontSize: number = 12; } export class LegendSettings { public Legend:boolean=false; }