/** @format */ import * as d3 from 'd3'; import _ from 'lodash'; import React, { useEffect, useRef } from 'react'; import { Transition } from 'react-spring/renderprops-universal'; import styled from 'styled-components'; const Box = styled.div``; interface ProgressProps { size?: any; [key: string]: any; } const Progress = (props: ProgressProps) => { const { size, count, totalCount, innerStartBg = 'rgba(56, 68, 102, 0.6)', innerEndBg = 'rgb(0, 206, 151)', outerStartBg = 'rgb(0, 206, 151)', outerEndBg = 'rgb(0, 206, 151)', borderHeight = 5, } = props; const styleBase = { height: 44, width: 120, }; const svgRef = useRef(null); const firstUpdate = useRef(true); useEffect(() => { if (firstUpdate.current) { firstUpdate.current = false; onDraw(true); } else { onDraw(false); } return () => { d3.select(svgRef.current) .selectAll('g') .remove(); }; }, [ size.width, size.height, count, totalCount, innerStartBg, innerEndBg, outerStartBg, outerEndBg, borderHeight, ]); function onDraw(flag: boolean) { const svg = d3.select(svgRef.current); const linerScale = d3 .scaleLinear() .domain([0, 100]) .range([0, size.width - 4]); const innerColor = svg .append('g') .append('linearGradient') .attr('id', `innerColor`) .attr('x1', 0) .attr('x2', '100%') .attr('y1', 0) .attr('y2', 0); innerColor .append('stop') .attr('offset', '0%') .attr('stop-color', innerStartBg); innerColor .append('stop') .attr('offset', '100%') .attr('stop-color', innerEndBg); const outerColor = svg .append('g') .append('linearGradient') .attr('id', `outerColor`) .attr('x1', 0) .attr('x2', '100%') .attr('y1', 0) .attr('y2', 0); outerColor .append('stop') .attr('offset', '0%') .attr('stop-color', outerStartBg); outerColor .append('stop') .attr('offset', '100%') .attr('stop-color', outerEndBg); svg .append('g') .append('rect') .attr('width', function() { return 0; }) .transition() .duration(500) .attr('width', function() { return linerScale((count / totalCount) * 100); }) .attr('height', borderHeight) .attr('x', 0) .attr('y', 0) .attr('fill', 'url(#innerColor)'); svg .append('g') .append('rect') .attr('width', function() { return 0; }) .attr('height', borderHeight) .attr('x', function() { return 4; }) .transition() .duration(500) .attr('x', function() { return linerScale((count / totalCount) * 100); }) .attr('width', function() { return linerScale(((totalCount - count) / totalCount) * 100); }) .attr('y', 0) .attr('fill', 'url(#outerColor)') .attr('transform', 'translate(4)'); } const style = _.merge(styleBase, size); return ( ); }; Progress.themeUpdate = function(params: any) { return { outerBg: params.primaryColor, innerBg: params.thirdColor, }; }; export default Progress;