Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@evergis/charts

Package Overview
Dependencies
Maintainers
6
Versions
171
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 1.0.2 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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc