Forum Discussion
Creating a Pie chart visual with Static Data.
- 8 years ago
Please take a look at this fixed version:
module powerbi.extensibility.visual { "use strict"; interface Data { quantity: number; category: string; } 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 svg: d3.Selection<SVGElement>; private g: any; private pie: any; private color: string; constructor(options: VisualConstructorOptions) { debugger; console.log('Visual constructor', options); this.target = options.element; this.host = options.host; let svg = this.svg = d3.select(options.element) .append('svg') .classed("pieChart", true); this.pieChartContainer = svg .append('g') .classed('pieChartContainer', true); } public update(options: VisualUpdateOptions) { console.log(options); this.settings = PieChart.parseSettings(options && options.dataViews && options.dataViews[0]); let testData: Data[] = [ { quantity: 25, category: 'a' }, { quantity: 50, category: 'b' }, { quantity: 100, category: 'c' }, { quantity: 200, category: 'd' }, { quantity: 300, category: 'e' }]; let width = options.viewport.width; let height = options.viewport.height; let radius = Math.min(width, height) / 2; this.svg.attr({ width: width, height: height, }); let colourValues = d3.scale.category20c(); this.arc = d3.svg.arc() .innerRadius(0) .outerRadius(radius - 20); this.pie = d3.layout.pie<Data>().value((d: Data): number => d.quantity); let fill = (d => colourValues(d.category)); let tf = d => `translate(${this.arc.centroid(d)})`; let text = d => d.data.category; this.pieChartContainer.attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')'); this.g = this.pieChartContainer.selectAll('.arc') .data(this.pie(testData)) .enter() .append('g') .attr('class', 'arc') .data(this.pie(testData)); this.g.append('path') .attr('d', this.arc) .attr('fill', fill) .style("stroke", "black") .style("stroke-width", "0.8") .on("mouseover", d => { d3.select(d) .attr('fill', 'blue') .style('opacity', '0.6') .attr('d', this.arc) .style("stroke", "black") .style("stroke-width", "3"); this.color = d.getAttribute('fill'); }) .on("mouseout", d => { d3.select(d) .attr('fill', colourValues(this.color)) .style("opacity", "1") .attr('d', this.arc) .style("stroke-width", "0.8"); }).append("svg:title"); //.html(d=>'<p>Quantity :'+d=>d. + '</p>'); this.g.append('text').attr('transform', tf).text(text); } 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); } } }Ignat Vilesov,
Software Engineer
Microsoft Power BI Custom Visuals
I'm using d3 3.5.17 and yes, i have included it into externalJS property.
Your code actually works for me:
However, Pie chart is misplaced. I suppose that you should apply CSS transform-translate to fix position issue.
Ignat Vilesov,
Software Engineer
Microsoft Power BI Custom Visuals
- Anonymous8 years agoNot applicable
Could you please share your .json files?
Did you make any change to my code?
Is there a need to fill the data fields when using static data?Thank You
Vishnu Suresh
- Anonymous8 years agoNot applicable
I got it. Thank you for your patience.
By the way,which element should be given the transform-translate style?
I added it as a attribute for svg ,but no use.- v-viig8 years agoCommunity Champion
Please take a look at this fixed version:
module powerbi.extensibility.visual { "use strict"; interface Data { quantity: number; category: string; } 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 svg: d3.Selection<SVGElement>; private g: any; private pie: any; private color: string; constructor(options: VisualConstructorOptions) { debugger; console.log('Visual constructor', options); this.target = options.element; this.host = options.host; let svg = this.svg = d3.select(options.element) .append('svg') .classed("pieChart", true); this.pieChartContainer = svg .append('g') .classed('pieChartContainer', true); } public update(options: VisualUpdateOptions) { console.log(options); this.settings = PieChart.parseSettings(options && options.dataViews && options.dataViews[0]); let testData: Data[] = [ { quantity: 25, category: 'a' }, { quantity: 50, category: 'b' }, { quantity: 100, category: 'c' }, { quantity: 200, category: 'd' }, { quantity: 300, category: 'e' }]; let width = options.viewport.width; let height = options.viewport.height; let radius = Math.min(width, height) / 2; this.svg.attr({ width: width, height: height, }); let colourValues = d3.scale.category20c(); this.arc = d3.svg.arc() .innerRadius(0) .outerRadius(radius - 20); this.pie = d3.layout.pie<Data>().value((d: Data): number => d.quantity); let fill = (d => colourValues(d.category)); let tf = d => `translate(${this.arc.centroid(d)})`; let text = d => d.data.category; this.pieChartContainer.attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')'); this.g = this.pieChartContainer.selectAll('.arc') .data(this.pie(testData)) .enter() .append('g') .attr('class', 'arc') .data(this.pie(testData)); this.g.append('path') .attr('d', this.arc) .attr('fill', fill) .style("stroke", "black") .style("stroke-width", "0.8") .on("mouseover", d => { d3.select(d) .attr('fill', 'blue') .style('opacity', '0.6') .attr('d', this.arc) .style("stroke", "black") .style("stroke-width", "3"); this.color = d.getAttribute('fill'); }) .on("mouseout", d => { d3.select(d) .attr('fill', colourValues(this.color)) .style("opacity", "1") .attr('d', this.arc) .style("stroke-width", "0.8"); }).append("svg:title"); //.html(d=>'<p>Quantity :'+d=>d. + '</p>'); this.g.append('text').attr('transform', tf).text(text); } 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); } } }Ignat Vilesov,
Software Engineer
Microsoft Power BI Custom Visuals
- Anonymous8 years agoNot applicable
Thanks v-viig.
And consider this as a Humble request from my side, Please consider improving the current documentation for creating custom visuals. Beginners like me struggle a lot following the current documentation.