import L from 'leaflet'; import * as d3 from 'd3'; import { addDropShadowFilter } from '../../../../helpers/d3.helper'; interface PieMarkerOptions extends L.DivIconOptions { // Additional Pie options needed radius: number; // iconSize: L.Point; shadow: { xOffset: number; yOffset: number; standardDeviation: number; } } export class ArcData { value: number; color?: string; label?: string; constructor(value: number, label?: string, color?: string) { this.color = color; this.label = label; this.value = value; } public valueOf = (): number => { return this.value; } } export class PieMarker extends L.DivIcon { public width: number; public height: number; constructor(options: PieMarkerOptions, data: ArcData[]) { // super(); // this.width = (options.radius + xOffset + standardDeviation) * 2; // this.height = (options.radius + yOffset + standardDeviation) * 2; const dominantColor = data.sort((a,b) => b.value - a.value)[0].color; const container = document.createElement('div'); const fontSize = 12; const { xOffset, yOffset, standardDeviation } = options.shadow; const svg = d3.select(container).append('svg') .attr('width', (options.radius + xOffset + standardDeviation * 2 + 1) * 2) .attr('height', (options.radius + yOffset + standardDeviation * 2 + 1) * 2); options.iconSize = new L.Point((options.radius + xOffset + standardDeviation * 2 + 1) * 2, (options.radius + yOffset + standardDeviation * 2 + 1) * 2); addDropShadowFilter(svg, xOffset, yOffset, standardDeviation); const g = svg.append('g') .attr('transform', `translate(${options.iconSize.x / 2}, ${options.iconSize.y / 2})`) const textGroup = svg.append('g') .attr('transform', `translate(${options.iconSize.x / 2}, ${options.iconSize.y / 2 - fontSize / 2})`) const pie = d3.pie(); const arcData = pie(data); const arcGenerator = d3.arc() .innerRadius(0) .outerRadius(options.radius); // const arcGenerator2 = d3.arc() // .innerRadius(0) // .outerRadius(options.radius); // Draw Full circle for shadow anchor g.append('path').attr('d', arcGenerator({ startAngle: 0, endAngle: 2 * Math.PI } as d3.DefaultArcObject) ) .attr('fill', 'white'); g.append('path').attr('d', arcGenerator({ startAngle: 0, endAngle: 2 * Math.PI } as d3.DefaultArcObject) ).attr('filter', 'url(#dropshadow)'); // Draw Pie Arcs const arcs = g.selectAll("arc") .data(arcData) .enter() .append('g') .attr('class', 'arc') arcs.append("path") .attr('d', arcGenerator as any) //.attr('stroke', 'black') .attr("fill", function(d, i) { return d.data.color; }); arcs.append("text") .attr("transform", function(d: any) { return "translate(" + arcGenerator.centroid(d) + ")"; }) .attr('text-anchor', 'middle') .attr('text-baseline', 'middle') .text(function(d) { return d.value ? d.value : ''; }) .style('fill', 'white'); // let offset = 0; // data.forEach((item, i) => { // textGroup.append('text') // .text(item.value) // .attr('text-anchor', 'middle') // .attr('y', offset) // .style('fill', item.color); // offset += fontSize; // }) super({ html: container, iconSize: new L.Point(options.radius * 2, options.radius * 2), className: 'pie-marker', ...options }); } }