import React from 'react';
import L from 'leaflet';
import BoundsDriftMarker, { BoundsDriftMarkerProps } from './BoundsDriftMarker';
import PiePlot from '../plots/PiePlot';
import {
MarkerScaleAddon,
MarkerScaleDefault,
PiePlotDatum,
ContainerStylesAddon,
} from '../types/plots';
import { last } from 'lodash';
// ts definition for HistogramMarkerSVGProps: need some adjustment but for now, just use Donut marker one
export interface DonutMarkerProps
extends BoundsDriftMarkerProps,
MarkerScaleAddon {
data: {
value: number;
label: string;
color?: string;
}[];
// isAtomic: add a special thumbtack icon if this is true
isAtomic?: boolean;
onClick?: (event: L.LeafletMouseEvent) => void | undefined;
/** center title/number for marker (defaults to sum of data[].value) */
markerLabel?: string;
/** cumulative mode: values are expected in order and to **already** be cumulative in nature.
* That is, values 20, 40, 60, 80, 100 would generate five equal-sized segments. The final
* value does not have to be 100. 2,4,6,8,10 would produce the same donut
* (but with different mouse-overs in the enlarged version.) */
cumulative?: boolean;
}
// convert to Cartesian coord. toCartesian(centerX, centerY, Radius for arc to draw, arc (radian))
function toCartesian(
centerX: number,
centerY: number,
radius: number,
angleInRadianInput: number
) {
const angleInRadians = angleInRadianInput - Math.PI / 2;
return {
x: centerX + radius * Math.cos(angleInRadians),
y: centerY + radius * Math.sin(angleInRadians),
};
}
// input radian: makeArc(centerX, centerY, Radius for arc to draw, start point of arc (radian), end point of arc (radian))
function makeArc(
x: number,
y: number,
radius: number,
startAngle: number,
endAngle: number
) {
const endAngleOriginal = endAngle;
if (endAngleOriginal - startAngle === 2 * Math.PI) {
endAngle = (359 * Math.PI) / 180;
}
const start = toCartesian(x, y, radius, endAngle);
const end = toCartesian(x, y, radius, startAngle);
const arcSweep = endAngle - startAngle <= Math.PI ? '0' : '1';
if (endAngleOriginal - startAngle === 2 * Math.PI) {
const dValue = [
'M',
start.x,
start.y,
'A',
radius,
radius,
0,
arcSweep,
0,
end.x,
end.y,
'z',
].join(' ');
return dValue;
} else {
const dValue = [
'M',
start.x,
start.y,
'A',
radius,
radius,
0,
arcSweep,
0,
end.x,
end.y,
].join(' ');
return dValue;
}
}
/**
* this is a SVG donut marker icon
*/
export default function DonutMarker(props: DonutMarkerProps) {
const {
html: svgHTML,
size,
markerLabel,
sliceTextOverrides,
} = donutMarkerSVGIcon(props);
// set icon as divIcon
const SVGDonutIcon: any = L.divIcon({
className: 'leaflet-canvas-icon', // may need to change this className but just leave it as it for now
iconSize: new L.Point(size, size), // this will make icon to cover up SVG area!
iconAnchor: new L.Point(size / 2, size / 2), // location of topleft corner: this is used for centering of the icon like transform/translate in CSS
html: svgHTML, // divIcon HTML svg code generated above
});
// anim check duration exists or not
const duration: number = props.duration ? props.duration : 300;
const plotSize = 150;
const marginSize = 0;
const popupPlot = (