Register now to learn Fabric in free live sessions led by the best Microsoft experts. From Apr 16 to May 9, in English and Spanish.
Hi guys, I'm developing a Pie chart and trying to create a legend for it.But the code snippet doesn't seem to do anything. please Help.
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; }; } interface LegendValues { category:string; color:string; selection:ISelectionId; } function visualTransform(options:VisualUpdateOptions,host:IVisualHost) : PieChartArc { let dataViews= options.dataViews; let defaultSetting : pieChartSettings = { Legend:{ show:false, } }; 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: <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 legend: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(); this.legend=d3.select(options.element); 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 legendModel : LegendValues[] = legendTransform(options,this.host); let viewModel: PieChartArc = visualTransform(options, this.host); let settings=this.pieSettings=viewModel.setting; let category=options.dataViews[0].categorical.categories[0]; let dataValue=options.dataViews[0].categorical.values[0]; let legend=this.legend; let legendEnumerate:LegendValues[]; // shows legend if(settings.Legend.show) { //this.svg.append("text").text("Hello"); for(let i=0;i<category.values.length;++i) { legendEnumerate.push({ category:<string>category.values[i], color:<string>dataValue.values[i], selection:this.host.createSelectionIdBuilder() .withCategory(category, i) .createSelectionId() }); } let leg= this.legend.append('svg'); for(let i=0;i<Math.max(category.values.length,dataValue.values.length);++i) { // this.legend.html(legendEnumerate[i].category).attr("transform","translate(" + i*20 +",0)") // leg.a leg.append('circle') .attr('cx',20) .attr('cy',20) .attr('r',8) .attr('fill',legendEnumerate[i].color) .attr("transform","translate(" + i*20 +",0)") ; leg.append('text') .text(legendEnumerate[i].category) .attr("transform","translate(" + i*30 +",0)") ; } } PieChart.data=options.dataViews; 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(); } 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); let objectName=options.objectName; let objectEnumeration:VisualObjectInstance[]=[]; switch(objectName) { case 'Legend': objectEnumeration.push({ objectName: objectName, properties:{ show:this.pieSettings.Legend.show, }, selector: null }); }; return objectEnumeration; } 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 }]; } } }
Here's my capabilities.json, currently only Legend is included in enumerateObjectInstances()
{ "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": { "show" :{ "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 } } ] } ] }
Hello @Anonymous
I'm sorry for the delay.
Have you already found out the root of issue?
Ignat Vilesov,
Software Engineer
Microsoft Power BI Custom Visuals
Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City
Check out the April 2024 Power BI update to learn about new features.