You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

@evergis/charts

Package Overview
Dependencies
Maintainers
6
Versions
189
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@evergis/charts - npm Package Compare versions

Comparing version

to
1.0.3

dist/common/components/Wrapper.d.ts

446

dist/charts.cjs.development.js

@@ -7,12 +7,448 @@ 'use strict';

var React = _interopDefault(require('react'));
var React = require('react');
var React__default = _interopDefault(React);
var d3 = require('d3');
var ReactDOMServer = _interopDefault(require('react-dom/server'));
var styled = require('styled-components');
var styled__default = _interopDefault(styled);
const Charts = (_ref) => {
function useNode() {
const [node, onSetNode] = React.useState(null);
const ref = React.useCallback(nodeElement => onSetNode(nodeElement), []);
return [ref, node];
}
function throttle(fn, wait) {
let isCalled = false;
return function () {
if (!isCalled) {
fn(...arguments);
isCalled = true;
setTimeout(function () {
isCalled = false;
}, wait);
}
};
}
const isNumber = value => {
// First: Check typeof and make sure it returns number
// This code coerces neither booleans nor strings to numbers,
// although it would be possible to do so if desired.
if (typeof value !== 'number') {
return false;
} // Reference for typeof:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof
// Second: Check for NaN, as NaN is a number to typeof.
// NaN is the only JavaScript value that never equals itself.
if (value !== Number(value)) {
return false;
} // Reference for NaN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN
// Note isNaN() is a broken function, but checking for self-equality works as NaN !== NaN
// Alternatively check for NaN using Number.isNaN(), an ES2015 feature that works how one would expect
// Third: Check for Infinity and -Infinity.
// Realistically we want finite numbers, or there was probably a division by 0 somewhere.
// @ts-ignore
if (value === Infinity || value === !Infinity) {
return false;
}
return true;
};
const useResize = (width, callback) => {
const wait = 44;
React.useEffect(() => {
callback && !isNumber(width) && window.addEventListener('resize', throttle(callback, wait));
return () => callback && window.removeEventListener('resize', throttle(callback, wait));
}, [width, callback]);
};
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
function _taggedTemplateLiteralLoose(strings, raw) {
if (!raw) {
raw = strings.slice(0);
}
strings.raw = raw;
return strings;
}
const appendSvg = (node, width, height) => {
d3.select(node).select('svg').remove();
const svg = d3.select(node).append('svg').attr('width', width).attr('height', height);
return svg;
};
const degByIndex = (index, count) => {
const degs = 360;
const deg = degs / count * index;
return deg;
};
const getTextAnchor = (index, data) => {
const deg = degByIndex(index, data.length);
const halfAngle = 180;
if ([0, halfAngle].includes(deg)) {
return 'middle';
}
if (deg < halfAngle) {
return 'start';
}
return 'end';
};
function _templateObject() {
const data = _taggedTemplateLiteralLoose(["\n position: relative;\n width: 100%;\n"]);
_templateObject = function _templateObject() {
return data;
};
return data;
}
const Wrapper = /*#__PURE__*/styled__default.div( /*#__PURE__*/_templateObject());
function _templateObject8() {
const data = _taggedTemplateLiteralLoose(["\n margin-left: 0.25rem;\n font-size: 0.625rem;\n color: rgba(255, 255, 255, 0.54);\n"]);
_templateObject8 = function _templateObject8() {
return data;
};
return data;
}
function _templateObject7() {
const data = _taggedTemplateLiteralLoose(["\n ", "\n"]);
_templateObject7 = function _templateObject7() {
return data;
};
return data;
}
function _templateObject6() {
const data = _taggedTemplateLiteralLoose(["\n display: flex;\n align-items: center;\n padding: 0.125rem 0.25rem;\n border-radius: 0.25rem;\n color: rgb(255, 255, 255);\n background-color: rgb(144, 197, 61);\n margin-left: 0.5rem;\n"]);
_templateObject6 = function _templateObject6() {
return data;
};
return data;
}
function _templateObject5() {
const data = _taggedTemplateLiteralLoose(["\n position: absolute;\n top: 50%;\n right: 0;\n transform: translate(calc(100% + 0.5rem), -50%);\n"]);
_templateObject5 = function _templateObject5() {
return data;
};
return data;
}
function _templateObject4() {
const data = _taggedTemplateLiteralLoose(["\n text-align: center;\n max-width: 7.5rem;\n"]);
_templateObject4 = function _templateObject4() {
return data;
};
return data;
}
function _templateObject3() {
const data = _taggedTemplateLiteralLoose(["\n display: flex;\n align-items: center;\n font-size: 0.75rem;\n"]);
_templateObject3 = function _templateObject3() {
return data;
};
return data;
}
function _templateObject2() {
const data = _taggedTemplateLiteralLoose(["\n position: absolute;\n"]);
_templateObject2 = function _templateObject2() {
return data;
};
return data;
}
function _templateObject$1() {
const data = _taggedTemplateLiteralLoose(["\n .", " {\n path,\n line,\n circle {\n fill: none;\n stroke-width: 1px;\n stroke: #959595;\n stroke-opacity: 0.18;\n }\n }\n .", " {\n font-size: 0.75rem;\n fill-opacity: 0.56;\n }\n .", " {\n fill-opacity: 0.06;\n stroke-width: 2px;\n fill: rgb(144, 197, 61);\n stroke: rgb(144, 197, 61);\n }\n .", " {\n fill: rgb(144, 197, 61);\n }\n"]);
_templateObject$1 = function _templateObject() {
return data;
};
return data;
}
const radarChartclassNames = {
radar: 'radar',
radarAxis: 'radarAxis',
radarAxisText: 'radarAxisText',
radarPolygon: 'radarPolygon',
radarLabel: 'radarLabel',
radarLabelName: 'radarLabelName',
radarLabelBadge: 'radarLabelBadge',
radarLabelBadgePrefix: 'radarLabelBadgePrefix',
radarCircle: 'radarCircle'
};
const SvgWrapper = /*#__PURE__*/styled__default(Wrapper)( /*#__PURE__*/_templateObject$1(), radarChartclassNames.radarAxis, radarChartclassNames.radarAxisText, radarChartclassNames.radarPolygon, radarChartclassNames.radarCircle);
const getTranslate = (_ref) => {
let {
children
anchor,
index,
translateX,
translateY
} = _ref;
return React.createElement("div", null, children || "the snozzberries taste like snozzberries");
if (index === 0 && anchor === 'middle') {
return "translate(calc(-50% + " + translateX + "px), calc(-100% + " + translateY + "px))";
} else if (anchor === 'middle') {
return "translate(calc(-50% + " + translateX + "px), calc(" + translateY + "px))";
} else if (anchor === 'start') {
return "translate(calc(" + translateX + "px), calc(-50% + " + translateY + "px))";
} else if (anchor === 'end') {
return "translate(calc(-100% + " + translateX + "px), calc(-50% + " + translateY + "px))";
}
return "translate(" + translateX + "px, " + translateY + "px)";
};
exports.Charts = Charts;
const LabelContainer = /*#__PURE__*/styled__default.div.attrs(props => ({
style: {
transform: getTranslate(props)
}
}))( /*#__PURE__*/_templateObject2());
const Label = /*#__PURE__*/styled__default.div( /*#__PURE__*/_templateObject3());
const Name = /*#__PURE__*/styled__default.div( /*#__PURE__*/_templateObject4());
const middleBadgeStyles = /*#__PURE__*/styled.css( /*#__PURE__*/_templateObject5());
const DefaultBadge = /*#__PURE__*/styled__default.div( /*#__PURE__*/_templateObject6());
const MiddleBadge = /*#__PURE__*/styled__default(DefaultBadge)( /*#__PURE__*/_templateObject7(), middleBadgeStyles);
const BadgePrefix = /*#__PURE__*/styled__default.div( /*#__PURE__*/_templateObject8());
const draw = (node, props) => {
const {
data,
curve,
polar,
formatValue,
badgePrefix,
labelOffset,
circleRadius,
gradient
} = props;
if (node !== null && data.length) {
const defaultBleedLength = 10;
const bleedLength = typeof props.bleedLength === 'number' ? props.bleedLength : defaultBleedLength;
const {
width: nodeWidth
} = node.getBoundingClientRect();
const width = props.width || nodeWidth;
const defaultHeight = 400;
const height = props.height || defaultHeight;
const minValue = props.minValue || Math.min(0, d3.min(data, i => d3.min(i.map((_ref) => {
let {
value
} = _ref;
return value;
}))));
const maxValue = (props.maxValue || Math.max(0, d3.max(data, i => d3.max(i.map((_ref2) => {
let {
value
} = _ref2;
return value;
}))))) - minValue;
const paddingX = props.paddingX || 0;
const paddingY = props.paddingY || 0;
const radius = Math.min((width - paddingX * 2 - bleedLength * 2) / 2, (height - paddingY * 2 - bleedLength * 2) / 2);
const radiusScale = d3.scaleLinear().range([0, radius]).domain([0, maxValue]);
const defaultLevels = 4;
const levels = props.levels || defaultLevels;
const angleSlice = Math.PI * 2 / data[0].length;
const radarLine = d3.lineRadial().curve(d3.curveLinearClosed) // @ts-ignore
.radius((_ref3) => {
let {
value
} = _ref3;
return radiusScale(value);
}).angle((_, i) => i * angleSlice);
const radarValue = d3.lineRadial().curve(curve || d3.curveLinearClosed) // @ts-ignore
.radius((_ref4) => {
let {
value
} = _ref4;
return radiusScale(value);
}).angle((_, i) => i * angleSlice);
const svg = appendSvg(node, width, height);
const globalCenter = svg.append('g');
const levelsGrid = d3.range(1, levels + 1).reverse();
const axisGridY = value => -value * radius / levels;
const getAxisValue = value => maxValue * value / levels;
const gridGlobal = globalCenter.append('g').attr('class', radarChartclassNames.radarAxis).selectAll().data([data[0]]).enter();
const radarGlobal = globalCenter.append('g').attr('class', radarChartclassNames.radar);
const axis = gridGlobal.selectAll().data(data[0].map((_ref5) => {
let {
name
} = _ref5;
return name;
})).enter();
let maxGridHeight = 0;
if (polar) {
levelsGrid.forEach(value => {
const path = gridGlobal.append('circle').attr('cx', 0).attr('cy', 0).attr('r', () => radius / levels * value);
const circleNode = path.node();
const circleHeight = circleNode.getBoundingClientRect().height;
maxGridHeight = Math.max(maxGridHeight, circleHeight);
});
} else {
levelsGrid.map(getAxisValue).forEach(value => {
const path = gridGlobal.append('path').attr('d', () => // @ts-ignore
radarLine(Array.from({
length: data[0].length
}, () => ({
value
}))));
const pathNode = path.node();
const pathHeight = pathNode.getBoundingClientRect().height;
maxGridHeight = Math.max(maxGridHeight, pathHeight);
});
}
const radiusByMaxValue = radiusScale(maxValue) + bleedLength;
axis.append('line').attr('x1', 0).attr('y1', 0).attr('x2', (_, i) => radiusByMaxValue * Math.cos(angleSlice * i - Math.PI / 2)).attr('y2', (_, i) => radiusByMaxValue * Math.sin(angleSlice * i - Math.PI / 2));
data.forEach(d => {
radarGlobal.append('path').attr('class', radarChartclassNames.radarPolygon).attr('d', () => radarValue( // @ts-ignore
d.map(dataItem => _extends({}, dataItem, {
value: dataItem.value - minValue
}))));
});
globalCenter.selectAll('text').data(levelsGrid).enter().append('text').attr('class', radarChartclassNames.radarAxisText).attr('x', '4').attr('y', axisGridY).attr('dy', 0).attr('dominant-baseline', 'central').text(value => getAxisValue(value) + minValue);
circleRadius && data.forEach(item => {
const circleGlobal = radarGlobal.append('g').attr('class', radarChartclassNames.radarCircle);
item.forEach((_ref6, i) => {
let {
value
} = _ref6;
circleGlobal.append('circle').attr('cx', radiusScale(value) * Math.cos(angleSlice * i - Math.PI / 2)).attr('cy', radiusScale(value * Math.sin(angleSlice * i - Math.PI / 2))).attr('r', circleRadius);
});
});
const pxToValue = value => maxValue / radius * value;
const defaultLabelOffset = 8;
const axisX = i => radiusScale(maxValue + pxToValue(bleedLength + (labelOffset || defaultLabelOffset))) * Math.cos(angleSlice * i - Math.PI / 2);
const axisY = i => radiusScale((maxValue + pxToValue(bleedLength + (labelOffset || defaultLabelOffset))) * Math.sin(angleSlice * i - Math.PI / 2));
const labels = data[0].map((_, i) => ({
x: Math.ceil(axisX(i)),
y: Math.ceil(axisY(i))
}));
const heightInner = height - bleedLength - paddingY;
const translateX = width / 2;
const translateY = heightInner / 2 + (heightInner - maxGridHeight) / 2;
globalCenter.attr('transform', "translate(" + translateX + "," + translateY + ")");
const d3container = d3.select(node);
d3container.selectAll("." + radarChartclassNames.radarLabel).remove();
labels.forEach((_ref7, index) => {
let {
x,
y
} = _ref7;
const anchor = getTextAnchor(index, data[0]);
const Badge = anchor === 'middle' ? MiddleBadge : DefaultBadge;
const html = ReactDOMServer.renderToString(React__default.createElement(LabelContainer, {
anchor: anchor,
translateX: translateX,
translateY: translateY,
index: index,
style: {
left: x,
top: y
}
}, React__default.createElement(Label, {
className: radarChartclassNames.radarLabel
}, React__default.createElement(Name, {
className: radarChartclassNames.radarLabelName
}, data[0][index].name), data.length === 1 && React__default.createElement(Badge, {
className: radarChartclassNames.radarLabelBadge
}, typeof formatValue === 'function' ? formatValue(data[0][index].value) : data[0][index].value, badgePrefix && React__default.createElement(BadgePrefix, {
className: radarChartclassNames.radarLabelBadgePrefix
}, badgePrefix)))));
d3container.append('div').attr('class', radarChartclassNames.radarLabel).html(html);
});
if (gradient) {
const html = ReactDOMServer.renderToString(gradient);
svg.append('g').html(html);
}
}
};
const RadarChart = props => {
const {
className,
style
} = props;
const [ref, node] = useNode();
React.useEffect(() => {
node && draw(node, props);
}, [node, props]);
const onDraw = () => draw(node, props);
useResize(props.width, onDraw);
return React__default.createElement("div", {
className: className,
style: style
}, React__default.createElement(SvgWrapper, {
ref: ref
}));
};
RadarChart.defaultProps = {
height: 400,
data: [],
curve: d3.curveLinearClosed
};
exports.RadarChart = RadarChart;
exports.radarChartclassNames = radarChartclassNames;
//# sourceMappingURL=charts.cjs.development.js.map

2

dist/charts.cjs.production.min.js

@@ -1,2 +0,2 @@

"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e,t=(e=require("react"))&&"object"==typeof e&&"default"in e?e.default:e;exports.Charts=e=>{let{children:r}=e;return t.createElement("div",null,r||"the snozzberries taste like snozzberries")};
"use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}Object.defineProperty(exports,"__esModule",{value:!0});var t=require("react"),a=e(t),r=require("d3"),n=e(require("react-dom/server")),l=require("styled-components"),i=e(l);function c(e,t){let a=!1;return function(){a||(e(...arguments),a=!0,setTimeout((function(){a=!1}),t))}}function s(){return(s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var a=arguments[t];for(var r in a)Object.prototype.hasOwnProperty.call(a,r)&&(e[r]=a[r])}return e}).apply(this,arguments)}function o(e,t){return t||(t=e.slice(0)),e.raw=t,e}function d(){const e=o(["\n position: relative;\n width: 100%;\n"]);return d=function(){return e},e}function u(){const e=o(["\n margin-left: 0.25rem;\n font-size: 0.625rem;\n color: rgba(255, 255, 255, 0.54);\n"]);return u=function(){return e},e}function p(){const e=o(["\n ","\n"]);return p=function(){return e},e}function f(){const e=o(["\n display: flex;\n align-items: center;\n padding: 0.125rem 0.25rem;\n border-radius: 0.25rem;\n color: rgb(255, 255, 255);\n background-color: rgb(144, 197, 61);\n margin-left: 0.5rem;\n"]);return f=function(){return e},e}function m(){const e=o(["\n position: absolute;\n top: 50%;\n right: 0;\n transform: translate(calc(100% + 0.5rem), -50%);\n"]);return m=function(){return e},e}function h(){const e=o(["\n text-align: center;\n max-width: 7.5rem;\n"]);return h=function(){return e},e}function g(){const e=o(["\n display: flex;\n align-items: center;\n font-size: 0.75rem;\n"]);return g=function(){return e},e}function x(){const e=o(["\n position: absolute;\n"]);return x=function(){return e},e}function v(){const e=o(["\n ."," {\n path,\n line,\n circle {\n fill: none;\n stroke-width: 1px;\n stroke: #959595;\n stroke-opacity: 0.18;\n }\n }\n ."," {\n font-size: 0.75rem;\n fill-opacity: 0.56;\n }\n ."," {\n fill-opacity: 0.06;\n stroke-width: 2px;\n fill: rgb(144, 197, 61);\n stroke: rgb(144, 197, 61);\n }\n ."," {\n fill: rgb(144, 197, 61);\n }\n"]);return v=function(){return e},e}const b={radar:"radar",radarAxis:"radarAxis",radarAxisText:"radarAxisText",radarPolygon:"radarPolygon",radarLabel:"radarLabel",radarLabelName:"radarLabelName",radarLabelBadge:"radarLabelBadge",radarLabelBadgePrefix:"radarLabelBadgePrefix",radarCircle:"radarCircle"},y=i(i.div(d()))(v(),b.radarAxis,b.radarAxisText,b.radarPolygon,b.radarCircle),L=e=>{let{anchor:t,index:a,translateX:r,translateY:n}=e;return 0===a&&"middle"===t?"translate(calc(-50% + "+r+"px), calc(-100% + "+n+"px))":"middle"===t?"translate(calc(-50% + "+r+"px), calc("+n+"px))":"start"===t?"translate(calc("+r+"px), calc(-50% + "+n+"px))":"end"===t?"translate(calc(-100% + "+r+"px), calc(-50% + "+n+"px))":"translate("+r+"px, "+n+"px)"},M=i.div.attrs(e=>({style:{transform:L(e)}}))(x()),P=i.div(g()),E=i.div(h()),w=l.css(m()),A=i.div(f()),C=i(A)(p(),w),N=i.div(u()),B=(e,t)=>{const{data:l,curve:i,polar:c,formatValue:o,badgePrefix:d,labelOffset:u,circleRadius:p,gradient:f}=t;if(null!==e&&l.length){const m=10,h="number"==typeof t.bleedLength?t.bleedLength:m,{width:g}=e.getBoundingClientRect(),x=t.width||g,v=400,y=t.height||v,L=t.minValue||Math.min(0,r.min(l,e=>r.min(e.map(e=>{let{value:t}=e;return t})))),w=(t.maxValue||Math.max(0,r.max(l,e=>r.max(e.map(e=>{let{value:t}=e;return t})))))-L,B=t.paddingY||0,I=Math.min((x-2*(t.paddingX||0)-2*h)/2,(y-2*B-2*h)/2),k=r.scaleLinear().range([0,I]).domain([0,w]),R=4,T=t.levels||R,z=2*Math.PI/l[0].length,O=r.lineRadial().curve(r.curveLinearClosed).radius(e=>{let{value:t}=e;return k(t)}).angle((e,t)=>t*z),j=r.lineRadial().curve(i||r.curveLinearClosed).radius(e=>{let{value:t}=e;return k(t)}).angle((e,t)=>t*z),q=((e,t,a)=>(r.select(e).select("svg").remove(),r.select(e).append("svg").attr("width",t).attr("height",a)))(e,x,y),S=q.append("g"),V=r.range(1,T+1).reverse(),X=e=>-e*I/T,Y=e=>w*e/T,_=S.append("g").attr("class",b.radarAxis).selectAll().data([l[0]]).enter(),D=S.append("g").attr("class",b.radar),F=_.selectAll().data(l[0].map(e=>{let{name:t}=e;return t})).enter();let G=0;c?V.forEach(e=>{const t=_.append("circle").attr("cx",0).attr("cy",0).attr("r",()=>I/T*e).node().getBoundingClientRect().height;G=Math.max(G,t)}):V.map(Y).forEach(e=>{const t=_.append("path").attr("d",()=>O(Array.from({length:l[0].length},()=>({value:e})))).node().getBoundingClientRect().height;G=Math.max(G,t)});const H=k(w)+h;F.append("line").attr("x1",0).attr("y1",0).attr("x2",(e,t)=>H*Math.cos(z*t-Math.PI/2)).attr("y2",(e,t)=>H*Math.sin(z*t-Math.PI/2)),l.forEach(e=>{D.append("path").attr("class",b.radarPolygon).attr("d",()=>j(e.map(e=>s({},e,{value:e.value-L}))))}),S.selectAll("text").data(V).enter().append("text").attr("class",b.radarAxisText).attr("x","4").attr("y",X).attr("dy",0).attr("dominant-baseline","central").text(e=>Y(e)+L),p&&l.forEach(e=>{const t=D.append("g").attr("class",b.radarCircle);e.forEach((e,a)=>{let{value:r}=e;t.append("circle").attr("cx",k(r)*Math.cos(z*a-Math.PI/2)).attr("cy",k(r*Math.sin(z*a-Math.PI/2))).attr("r",p)})});const J=e=>w/I*e,K=8,Q=e=>k(w+J(h+(u||K)))*Math.cos(z*e-Math.PI/2),U=e=>k((w+J(h+(u||K)))*Math.sin(z*e-Math.PI/2)),W=l[0].map((e,t)=>({x:Math.ceil(Q(t)),y:Math.ceil(U(t))})),Z=y-h-B,$=x/2,ee=Z/2+(Z-G)/2;S.attr("transform","translate("+$+","+ee+")");const te=r.select(e);if(te.selectAll("."+b.radarLabel).remove(),W.forEach((e,t)=>{let{x:r,y:i}=e;const c=((e,t)=>{const a=((e,t)=>360/t*e)(e,t.length),r=180;return[0,r].includes(a)?"middle":a<r?"start":"end"})(t,l[0]),s="middle"===c?C:A,u=n.renderToString(a.createElement(M,{anchor:c,translateX:$,translateY:ee,index:t,style:{left:r,top:i}},a.createElement(P,{className:b.radarLabel},a.createElement(E,{className:b.radarLabelName},l[0][t].name),1===l.length&&a.createElement(s,{className:b.radarLabelBadge},"function"==typeof o?o(l[0][t].value):l[0][t].value,d&&a.createElement(N,{className:b.radarLabelBadgePrefix},d)))));te.append("div").attr("class",b.radarLabel).html(u)}),f){const e=n.renderToString(f);q.append("g").html(e)}}},I=e=>{const{className:r,style:n}=e,[l,i]=function(){const[e,a]=t.useState(null);return[t.useCallback(e=>a(e),[]),e]}();return t.useEffect(()=>{i&&B(i,e)},[i,e]),t.useEffect(()=>{var e;return o&&("number"!=typeof(e=s)||e!==Number(e)||Infinity===e||!1===e)&&window.addEventListener("resize",c(o,44)),()=>o&&window.removeEventListener("resize",c(o,44))},[s=e.width,o=()=>B(i,e)]),a.createElement("div",{className:r,style:n},a.createElement(y,{ref:l}));var s,o};I.defaultProps={height:400,data:[],curve:r.curveLinearClosed},exports.RadarChart=I,exports.radarChartclassNames=b;
//# sourceMappingURL=charts.cjs.production.min.js.map

@@ -1,11 +0,444 @@

import React from 'react';
import React, { useState, useCallback, useEffect } from 'react';
import { select, min, max, scaleLinear, lineRadial, curveLinearClosed, range } from 'd3';
import ReactDOMServer from 'react-dom/server';
import styled, { css } from 'styled-components';
const Charts = (_ref) => {
function useNode() {
const [node, onSetNode] = useState(null);
const ref = useCallback(nodeElement => onSetNode(nodeElement), []);
return [ref, node];
}
function throttle(fn, wait) {
let isCalled = false;
return function () {
if (!isCalled) {
fn(...arguments);
isCalled = true;
setTimeout(function () {
isCalled = false;
}, wait);
}
};
}
const isNumber = value => {
// First: Check typeof and make sure it returns number
// This code coerces neither booleans nor strings to numbers,
// although it would be possible to do so if desired.
if (typeof value !== 'number') {
return false;
} // Reference for typeof:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof
// Second: Check for NaN, as NaN is a number to typeof.
// NaN is the only JavaScript value that never equals itself.
if (value !== Number(value)) {
return false;
} // Reference for NaN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN
// Note isNaN() is a broken function, but checking for self-equality works as NaN !== NaN
// Alternatively check for NaN using Number.isNaN(), an ES2015 feature that works how one would expect
// Third: Check for Infinity and -Infinity.
// Realistically we want finite numbers, or there was probably a division by 0 somewhere.
// @ts-ignore
if (value === Infinity || value === !Infinity) {
return false;
}
return true;
};
const useResize = (width, callback) => {
const wait = 44;
useEffect(() => {
callback && !isNumber(width) && window.addEventListener('resize', throttle(callback, wait));
return () => callback && window.removeEventListener('resize', throttle(callback, wait));
}, [width, callback]);
};
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
function _taggedTemplateLiteralLoose(strings, raw) {
if (!raw) {
raw = strings.slice(0);
}
strings.raw = raw;
return strings;
}
const appendSvg = (node, width, height) => {
select(node).select('svg').remove();
const svg = select(node).append('svg').attr('width', width).attr('height', height);
return svg;
};
const degByIndex = (index, count) => {
const degs = 360;
const deg = degs / count * index;
return deg;
};
const getTextAnchor = (index, data) => {
const deg = degByIndex(index, data.length);
const halfAngle = 180;
if ([0, halfAngle].includes(deg)) {
return 'middle';
}
if (deg < halfAngle) {
return 'start';
}
return 'end';
};
function _templateObject() {
const data = _taggedTemplateLiteralLoose(["\n position: relative;\n width: 100%;\n"]);
_templateObject = function _templateObject() {
return data;
};
return data;
}
const Wrapper = /*#__PURE__*/styled.div( /*#__PURE__*/_templateObject());
function _templateObject8() {
const data = _taggedTemplateLiteralLoose(["\n margin-left: 0.25rem;\n font-size: 0.625rem;\n color: rgba(255, 255, 255, 0.54);\n"]);
_templateObject8 = function _templateObject8() {
return data;
};
return data;
}
function _templateObject7() {
const data = _taggedTemplateLiteralLoose(["\n ", "\n"]);
_templateObject7 = function _templateObject7() {
return data;
};
return data;
}
function _templateObject6() {
const data = _taggedTemplateLiteralLoose(["\n display: flex;\n align-items: center;\n padding: 0.125rem 0.25rem;\n border-radius: 0.25rem;\n color: rgb(255, 255, 255);\n background-color: rgb(144, 197, 61);\n margin-left: 0.5rem;\n"]);
_templateObject6 = function _templateObject6() {
return data;
};
return data;
}
function _templateObject5() {
const data = _taggedTemplateLiteralLoose(["\n position: absolute;\n top: 50%;\n right: 0;\n transform: translate(calc(100% + 0.5rem), -50%);\n"]);
_templateObject5 = function _templateObject5() {
return data;
};
return data;
}
function _templateObject4() {
const data = _taggedTemplateLiteralLoose(["\n text-align: center;\n max-width: 7.5rem;\n"]);
_templateObject4 = function _templateObject4() {
return data;
};
return data;
}
function _templateObject3() {
const data = _taggedTemplateLiteralLoose(["\n display: flex;\n align-items: center;\n font-size: 0.75rem;\n"]);
_templateObject3 = function _templateObject3() {
return data;
};
return data;
}
function _templateObject2() {
const data = _taggedTemplateLiteralLoose(["\n position: absolute;\n"]);
_templateObject2 = function _templateObject2() {
return data;
};
return data;
}
function _templateObject$1() {
const data = _taggedTemplateLiteralLoose(["\n .", " {\n path,\n line,\n circle {\n fill: none;\n stroke-width: 1px;\n stroke: #959595;\n stroke-opacity: 0.18;\n }\n }\n .", " {\n font-size: 0.75rem;\n fill-opacity: 0.56;\n }\n .", " {\n fill-opacity: 0.06;\n stroke-width: 2px;\n fill: rgb(144, 197, 61);\n stroke: rgb(144, 197, 61);\n }\n .", " {\n fill: rgb(144, 197, 61);\n }\n"]);
_templateObject$1 = function _templateObject() {
return data;
};
return data;
}
const radarChartclassNames = {
radar: 'radar',
radarAxis: 'radarAxis',
radarAxisText: 'radarAxisText',
radarPolygon: 'radarPolygon',
radarLabel: 'radarLabel',
radarLabelName: 'radarLabelName',
radarLabelBadge: 'radarLabelBadge',
radarLabelBadgePrefix: 'radarLabelBadgePrefix',
radarCircle: 'radarCircle'
};
const SvgWrapper = /*#__PURE__*/styled(Wrapper)( /*#__PURE__*/_templateObject$1(), radarChartclassNames.radarAxis, radarChartclassNames.radarAxisText, radarChartclassNames.radarPolygon, radarChartclassNames.radarCircle);
const getTranslate = (_ref) => {
let {
children
anchor,
index,
translateX,
translateY
} = _ref;
return React.createElement("div", null, children || "the snozzberries taste like snozzberries");
if (index === 0 && anchor === 'middle') {
return "translate(calc(-50% + " + translateX + "px), calc(-100% + " + translateY + "px))";
} else if (anchor === 'middle') {
return "translate(calc(-50% + " + translateX + "px), calc(" + translateY + "px))";
} else if (anchor === 'start') {
return "translate(calc(" + translateX + "px), calc(-50% + " + translateY + "px))";
} else if (anchor === 'end') {
return "translate(calc(-100% + " + translateX + "px), calc(-50% + " + translateY + "px))";
}
return "translate(" + translateX + "px, " + translateY + "px)";
};
export { Charts };
const LabelContainer = /*#__PURE__*/styled.div.attrs(props => ({
style: {
transform: getTranslate(props)
}
}))( /*#__PURE__*/_templateObject2());
const Label = /*#__PURE__*/styled.div( /*#__PURE__*/_templateObject3());
const Name = /*#__PURE__*/styled.div( /*#__PURE__*/_templateObject4());
const middleBadgeStyles = /*#__PURE__*/css( /*#__PURE__*/_templateObject5());
const DefaultBadge = /*#__PURE__*/styled.div( /*#__PURE__*/_templateObject6());
const MiddleBadge = /*#__PURE__*/styled(DefaultBadge)( /*#__PURE__*/_templateObject7(), middleBadgeStyles);
const BadgePrefix = /*#__PURE__*/styled.div( /*#__PURE__*/_templateObject8());
const draw = (node, props) => {
const {
data,
curve,
polar,
formatValue,
badgePrefix,
labelOffset,
circleRadius,
gradient
} = props;
if (node !== null && data.length) {
const defaultBleedLength = 10;
const bleedLength = typeof props.bleedLength === 'number' ? props.bleedLength : defaultBleedLength;
const {
width: nodeWidth
} = node.getBoundingClientRect();
const width = props.width || nodeWidth;
const defaultHeight = 400;
const height = props.height || defaultHeight;
const minValue = props.minValue || Math.min(0, min(data, i => min(i.map((_ref) => {
let {
value
} = _ref;
return value;
}))));
const maxValue = (props.maxValue || Math.max(0, max(data, i => max(i.map((_ref2) => {
let {
value
} = _ref2;
return value;
}))))) - minValue;
const paddingX = props.paddingX || 0;
const paddingY = props.paddingY || 0;
const radius = Math.min((width - paddingX * 2 - bleedLength * 2) / 2, (height - paddingY * 2 - bleedLength * 2) / 2);
const radiusScale = scaleLinear().range([0, radius]).domain([0, maxValue]);
const defaultLevels = 4;
const levels = props.levels || defaultLevels;
const angleSlice = Math.PI * 2 / data[0].length;
const radarLine = lineRadial().curve(curveLinearClosed) // @ts-ignore
.radius((_ref3) => {
let {
value
} = _ref3;
return radiusScale(value);
}).angle((_, i) => i * angleSlice);
const radarValue = lineRadial().curve(curve || curveLinearClosed) // @ts-ignore
.radius((_ref4) => {
let {
value
} = _ref4;
return radiusScale(value);
}).angle((_, i) => i * angleSlice);
const svg = appendSvg(node, width, height);
const globalCenter = svg.append('g');
const levelsGrid = range(1, levels + 1).reverse();
const axisGridY = value => -value * radius / levels;
const getAxisValue = value => maxValue * value / levels;
const gridGlobal = globalCenter.append('g').attr('class', radarChartclassNames.radarAxis).selectAll().data([data[0]]).enter();
const radarGlobal = globalCenter.append('g').attr('class', radarChartclassNames.radar);
const axis = gridGlobal.selectAll().data(data[0].map((_ref5) => {
let {
name
} = _ref5;
return name;
})).enter();
let maxGridHeight = 0;
if (polar) {
levelsGrid.forEach(value => {
const path = gridGlobal.append('circle').attr('cx', 0).attr('cy', 0).attr('r', () => radius / levels * value);
const circleNode = path.node();
const circleHeight = circleNode.getBoundingClientRect().height;
maxGridHeight = Math.max(maxGridHeight, circleHeight);
});
} else {
levelsGrid.map(getAxisValue).forEach(value => {
const path = gridGlobal.append('path').attr('d', () => // @ts-ignore
radarLine(Array.from({
length: data[0].length
}, () => ({
value
}))));
const pathNode = path.node();
const pathHeight = pathNode.getBoundingClientRect().height;
maxGridHeight = Math.max(maxGridHeight, pathHeight);
});
}
const radiusByMaxValue = radiusScale(maxValue) + bleedLength;
axis.append('line').attr('x1', 0).attr('y1', 0).attr('x2', (_, i) => radiusByMaxValue * Math.cos(angleSlice * i - Math.PI / 2)).attr('y2', (_, i) => radiusByMaxValue * Math.sin(angleSlice * i - Math.PI / 2));
data.forEach(d => {
radarGlobal.append('path').attr('class', radarChartclassNames.radarPolygon).attr('d', () => radarValue( // @ts-ignore
d.map(dataItem => _extends({}, dataItem, {
value: dataItem.value - minValue
}))));
});
globalCenter.selectAll('text').data(levelsGrid).enter().append('text').attr('class', radarChartclassNames.radarAxisText).attr('x', '4').attr('y', axisGridY).attr('dy', 0).attr('dominant-baseline', 'central').text(value => getAxisValue(value) + minValue);
circleRadius && data.forEach(item => {
const circleGlobal = radarGlobal.append('g').attr('class', radarChartclassNames.radarCircle);
item.forEach((_ref6, i) => {
let {
value
} = _ref6;
circleGlobal.append('circle').attr('cx', radiusScale(value) * Math.cos(angleSlice * i - Math.PI / 2)).attr('cy', radiusScale(value * Math.sin(angleSlice * i - Math.PI / 2))).attr('r', circleRadius);
});
});
const pxToValue = value => maxValue / radius * value;
const defaultLabelOffset = 8;
const axisX = i => radiusScale(maxValue + pxToValue(bleedLength + (labelOffset || defaultLabelOffset))) * Math.cos(angleSlice * i - Math.PI / 2);
const axisY = i => radiusScale((maxValue + pxToValue(bleedLength + (labelOffset || defaultLabelOffset))) * Math.sin(angleSlice * i - Math.PI / 2));
const labels = data[0].map((_, i) => ({
x: Math.ceil(axisX(i)),
y: Math.ceil(axisY(i))
}));
const heightInner = height - bleedLength - paddingY;
const translateX = width / 2;
const translateY = heightInner / 2 + (heightInner - maxGridHeight) / 2;
globalCenter.attr('transform', "translate(" + translateX + "," + translateY + ")");
const d3container = select(node);
d3container.selectAll("." + radarChartclassNames.radarLabel).remove();
labels.forEach((_ref7, index) => {
let {
x,
y
} = _ref7;
const anchor = getTextAnchor(index, data[0]);
const Badge = anchor === 'middle' ? MiddleBadge : DefaultBadge;
const html = ReactDOMServer.renderToString(React.createElement(LabelContainer, {
anchor: anchor,
translateX: translateX,
translateY: translateY,
index: index,
style: {
left: x,
top: y
}
}, React.createElement(Label, {
className: radarChartclassNames.radarLabel
}, React.createElement(Name, {
className: radarChartclassNames.radarLabelName
}, data[0][index].name), data.length === 1 && React.createElement(Badge, {
className: radarChartclassNames.radarLabelBadge
}, typeof formatValue === 'function' ? formatValue(data[0][index].value) : data[0][index].value, badgePrefix && React.createElement(BadgePrefix, {
className: radarChartclassNames.radarLabelBadgePrefix
}, badgePrefix)))));
d3container.append('div').attr('class', radarChartclassNames.radarLabel).html(html);
});
if (gradient) {
const html = ReactDOMServer.renderToString(gradient);
svg.append('g').html(html);
}
}
};
const RadarChart = props => {
const {
className,
style
} = props;
const [ref, node] = useNode();
useEffect(() => {
node && draw(node, props);
}, [node, props]);
const onDraw = () => draw(node, props);
useResize(props.width, onDraw);
return React.createElement("div", {
className: className,
style: style
}, React.createElement(SvgWrapper, {
ref: ref
}));
};
RadarChart.defaultProps = {
height: 400,
data: [],
curve: curveLinearClosed
};
export { RadarChart, radarChartclassNames };
//# sourceMappingURL=charts.esm.js.map

@@ -1,1 +0,2 @@

export * from './Charts';
export { RadarChart } from './RadarChart';
export { radarChartclassNames } from './RadarChart/styled';
{
"version": "1.0.2",
"version": "1.0.3",
"license": "MIT",

@@ -46,4 +46,6 @@ "main": "dist/index.js",

"@storybook/react": "^6.0.26",
"@types/d3": "^5.16.3",
"@types/react": "^16.9.52",
"@types/react-dom": "^16.9.8",
"@types/styled-components": "^5.1.3",
"babel-loader": "^8.1.0",

@@ -53,6 +55,13 @@ "react": "^16.14.0",

"react-dom": "^16.14.0",
"react-is": "^16.13.1",
"ts-loader": "^8.0.5"
},
"gitHead": "8931f38f6684f15d08455229eb688a0fbb50ef7f"
"resolutions": {
"styled-components": "^5",
"d3": "^6"
},
"dependencies": {
"d3": "^6.2.0",
"styled-components": "^5.2.0"
},
"gitHead": "e01a311fdd5e5737d250e8a4b2b9b300715f114d"
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet