Skip to content
Merged

Gauge #712

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,6 @@ <h1>
Share your ideas as low-fidelity mocks in minutes, perfect for
getting started.
</p>
<p class="community">Community preview</p>
</div>
<div>
<div class="video">
Expand Down
14 changes: 8 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added public/assets/omar-lorenzo.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions public/rich-components/gauge.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { Circle, Group, Path, Text } from 'react-konva';
import { ShapeSizeRestrictions, ShapeType } from '@/core/model';
import { forwardRef } from 'react';
import { ShapeProps } from '../../shape.model';
import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-restrictions';
import { useShapeProps } from '../../../shapes/use-shape-props.hook';

import { BASIC_SHAPE } from '@/common/components/mock-components/front-components/shape.const';
import { useGroupShapeProps } from '../../mock-components.utils';
import {
endsWhithPercentageSymbol,
extractNumbersAsTwoDigitString,
} from './gauge.utils';

const gaugeShapeSizeRestrictions: ShapeSizeRestrictions = {
minWidth: 70,
minHeight: 70,
maxWidth: -1,
maxHeight: -1,
defaultWidth: 150,
defaultHeight: 150,
};

export const getGaugeShapeSizeRestrictions = (): ShapeSizeRestrictions =>
gaugeShapeSizeRestrictions;

const shapeType: ShapeType = 'gauge';

export const Gauge = forwardRef<any, ShapeProps>((props, ref) => {
const {
x,
y,
width,
height,
id,
onSelected,
text,
otherProps,
...shapeProps
} = props;
const restrictedSize = fitSizeToShapeSizeRestrictions(
gaugeShapeSizeRestrictions,
width,
height
);

const { width: restrictedWidth, height: restrictedHeight } = restrictedSize;
const { fontSize } = useShapeProps(otherProps, BASIC_SHAPE);
const commonGroupProps = useGroupShapeProps(
props,
restrictedSize,
shapeType,
ref
);
const { stroke, fill, textColor } = useShapeProps(otherProps, BASIC_SHAPE);

const numericPart = extractNumbersAsTwoDigitString(text);

const progress = Number(numericPart);
const displayValue = endsWhithPercentageSymbol(text)
? `${numericPart}%`
: numericPart;

const size = Math.min(restrictedWidth, restrictedHeight);
const strokeWidth = Math.min(restrictedWidth, restrictedHeight) / 10;
const radius = (size - strokeWidth) / 2;
const center = size / 2;
const angle = (progress / 100.01) * 360;
const fontSizeScaled = fontSize * (size / 80);
const arcPath = () => {
const startAngle = -90;
const endAngle = startAngle + angle;
const largeArcFlag = angle > 180 ? 1 : 0;
const startX = center + radius * Math.cos((Math.PI * startAngle) / 180);
const startY = center + radius * Math.sin((Math.PI * startAngle) / 180);
const endX = center + radius * Math.cos((Math.PI * endAngle) / 180);
const endY = center + radius * Math.sin((Math.PI * endAngle) / 180);
return `M ${startX} ${startY} A ${radius} ${radius} 0 ${largeArcFlag} 1 ${endX} ${endY}`;
};
return (
<Group {...commonGroupProps} {...shapeProps}>
{/* Background */}
<Circle
x={center}
y={center}
radius={radius}
fill={fill}
stroke={fill}
strokeWidth={strokeWidth}
/>

{/* Moving Arc */}
<Path data={arcPath()} stroke={stroke} strokeWidth={strokeWidth + 1} />

{/* Percent */}
<Text
x={center - 10 - radius / 2}
y={center - fontSizeScaled / 2}
width={center + 10}
text={displayValue}
fontFamily="Arial, sans-serif"
fontSize={fontSizeScaled}
align="center"
fill={textColor}
fontStyle="bold"
/>
</Group>
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export const extractNumbersAsTwoDigitString = (text: string): string => {
const numbersAsString = text.replace(/\D/g, '');
return numbersAsString === '100' ? '100' : numbersAsString.slice(0, 2) || '0';
};

export const endsWhithPercentageSymbol = (text: string): boolean => {
return text.trim().endsWith('%');
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './gauge';
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ export * from './audio-player';
export * from './loading-indicator';
export * from './videoconference';
export * from './togglelightdark-shape';
export * from './gauge/gauge';
4 changes: 3 additions & 1 deletion src/core/model/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ export type ShapeType =
| 'richtext'
| 'loading-indicator'
| 'videoconference'
| 'richtext';
| 'richtext'
| 'gauge';

export const ShapeDisplayName: Record<ShapeType, string> = {
multiple: 'multiple',
Expand Down Expand Up @@ -138,6 +139,7 @@ export const ShapeDisplayName: Record<ShapeType, string> = {
cilinder: 'Cilinder',
'loading-indicator': 'Loading',
videoconference: 'Videoconference',
gauge: 'Gauge',
};

export type EditType = 'input' | 'textarea' | 'imageupload';
Expand Down
3 changes: 1 addition & 2 deletions src/pods/about/about.pod.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ export const AboutPod = () => {
<div className={classes.container}>
<QuickmockLogoComponent styleClass={classes.projectLogo} />
<h2 className={classes.projectName}>Quickmock</h2>
<p className={classes.projectVersion}>Version 0.0</p>
<p className={classes.projectCommunity}>Community preview</p>
<p className={classes.projectVersion}>Version 1.0</p>
<DevelopmentTeamComponent />
</div>
);
Expand Down
11 changes: 9 additions & 2 deletions src/pods/about/members.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,14 +145,21 @@ export const memberList: Member[] = [
},
{
id: '19',
name: 'Omar',
surname: 'Lorenzo',
urlLinkedin: 'https://www.linkedin.com/in/omar-lorenzo-montelongo/',
image: './assets/omar-lorenzo.jpeg',
},
{
id: '20',
name: 'Gabriel',
surname: 'Ionut',
urlLinkedin: 'https://www.linkedin.com/in/gabriel-ionut-birsan-b14816307/',
image: './assets/gabriel-ionut.jpeg',
},

{
id: '20',
id: '21',
name: 'Antonio',
surname: 'Contreras',
urlLinkedin:
Expand All @@ -161,7 +168,7 @@ export const memberList: Member[] = [
},

{
id: '21',
id: '22',
name: 'Braulio',
surname: 'Diez',
urlLinkedin: 'https://www.linkedin.com/in/brauliodiez/',
Expand Down
3 changes: 3 additions & 0 deletions src/pods/canvas/model/inline-editable.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const inlineEditableShapes = new Set<ShapeType>([
'datepickerinput',
'browser',
'modalDialog',
'gauge',
'loading-indicator',
]);

Expand Down Expand Up @@ -78,6 +79,7 @@ const shapeTypesWithDefaultText = new Set<ShapeType>([
'browser',
'modalDialog',
'loading-indicator',
'gauge',
]);

// Map of ShapeTypes to their default text values
Expand Down Expand Up @@ -108,6 +110,7 @@ const defaultTextValueMap: Partial<Record<ShapeType, string>> = {
modal:
'Alert\nWarning: The action you are about to perform may affect existing data. Are you sure you want to proceed? Once confirmed, this action cannot be undone.\nConfirm,Cancel',
appBar: 'AppBar',
gauge: '10%',
buttonBar: 'Button 1, Button 2, Button 3',
tabsBar: 'Tab 1, Tab 2, Tab 3',
link: 'Link',
Expand Down
6 changes: 6 additions & 0 deletions src/pods/canvas/model/shape-other-props.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ export const generateDefaultOtherProps = (
disabled: BASIC_SHAPE.DEFAULT_DISABLED,
};
case 'modal':
case 'gauge':
return {
backgroundColor: '#d3d3d3',
stroke: '#808080',
textColor: BASIC_SHAPE.DEFAULT_FILL_TEXT,
};
case 'buttonBar':
return {
stroke: BASIC_SHAPE.DEFAULT_STROKE_COLOR,
Expand Down
2 changes: 2 additions & 0 deletions src/pods/canvas/model/shape-size.mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import {
getVerticalMenuShapeSizeRestrictions,
getVideoPlayerShapeSizeRestrictions,
getVideoconferenceShapeSizeRestrictions,
getGaugeShapeSizeRestrictions,
// other imports
} from '@/common/components/mock-components/front-rich-components';
import {
Expand Down Expand Up @@ -148,6 +149,7 @@ const shapeSizeMap: Record<ShapeType, () => ShapeSizeRestrictions> = {
cilinder: getCilinderShapeSizeRestrictions,
'loading-indicator': getLoadIndicatorSizeRestrictions,
videoconference: getVideoconferenceShapeSizeRestrictions,
gauge: getGaugeShapeSizeRestrictions,
};

export default shapeSizeMap;
4 changes: 4 additions & 0 deletions src/pods/canvas/shape-renderer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import {
renderTabsBar,
renderToggleLightDark,
renderVideoconference,
renderGauge,
} from './simple-rich-components';
import {
renderDiamond,
Expand Down Expand Up @@ -197,6 +198,9 @@ export const renderShapeComponent = (
return renderLoadingIndicator(shape, shapeRenderedProps);
case 'videoconference':
return renderVideoconference(shape, shapeRenderedProps);
case 'gauge':
return renderGauge(shape, shapeRenderedProps);

default:
return renderNotFound(shape, shapeRenderedProps);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Gauge } from '@/common/components/mock-components/front-rich-components';
import { ShapeRendererProps } from '../model';
import { ShapeModel } from '@/core/model';

export const renderGauge = (
shape: ShapeModel,
shapeRenderedProps: ShapeRendererProps
) => {
const { handleSelected, shapeRefs, handleDragEnd, handleTransform } =
shapeRenderedProps;

return (
<Gauge
id={shape.id}
key={shape.id}
ref={shapeRefs.current[shape.id]}
x={shape.x}
y={shape.y}
name="shape"
width={shape.width}
height={shape.height}
draggable
typeOfTransformer={shape.typeOfTransformer}
onSelected={handleSelected}
onDragEnd={handleDragEnd(shape.id)}
onTransform={handleTransform}
onTransformEnd={handleTransform}
editType={shape.editType}
isEditable={true}
text={shape.text}
otherProps={shape.otherProps}
/>
);
};
Loading