Skip to content
Open
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
4 changes: 4 additions & 0 deletions src/core/config/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ export const DEFAULT_PROPS = {

// Accessibility related props
svgAriaLabel: 'React d3 speedometer', // aria-label of speedometer

onSegmentClick: () => {}, // Default no-op function
}

// default config
Expand Down Expand Up @@ -150,6 +152,8 @@ export const getConfig = ({ PROPS, parentWidth, parentHeight }) => {

// Accessibility related props
svgAriaLabel: PROPS.svgAriaLabel, // aria-label of speedometer

onSegmentClick: PROPS.onSegmentClick,
}

return Object.assign({}, DEFAULT_CONFIG, config)
Expand Down
24 changes: 24 additions & 0 deletions src/core/render/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,30 @@ function _renderArcs({ config, svg, centerTx }) {
return config.arcColorFn(d * i)
})
.attr('d', arc)
.attr('data-label', (d, i) => {
return config.customSegmentLabels[i]?.text || 'Default Label';
})
.attr('data-sstop', (d, i) => {
const startStop = config.customSegmentStops[i];
const endStop = config.customSegmentStops[i + 1];

// Check if startStop or endStop are undefined, null, or not numbers
if (typeof startStop !== 'number' || startStop === null || isNaN(startStop) ||
typeof endStop !== 'number' || endStop === null || isNaN(endStop)) {
// Provide a default value or skip setting the attribute
return 'unknown';
} else {
// Both startStop and endStop are valid numbers
return `${startStop}-${endStop}`;
}
})
.on('click', function (event, d) {
const label = event.target.getAttribute('data-label');
const value = event.target.getAttribute('data-sstop');
if (config.onSegmentClick) {
config.onSegmentClick(label,value);
}
});
}

export function _renderLabels({ config, svg, centerTx, r }) {
Expand Down
160 changes: 85 additions & 75 deletions src/stories/ReactSpeedometer.stories.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,83 +38,93 @@ export const ConfiguringValues = () => (
/>
)

export const CustomSegmentLabels = () => (
<div>
<div>
<ReactSpeedometer
width={500}
needleHeightRatio={0.7}
value={777}
currentValueText="Happiness Level"
customSegmentLabels={[
{
text: 'Very Bad',
position: 'INSIDE',
color: '#555',
},
{
text: 'Bad',
position: 'INSIDE',
color: '#555',
},
{
text: 'Ok',
position: 'INSIDE',
color: '#555',
fontSize: '19px',
},
{
text: 'Good',
position: 'INSIDE',
color: '#555',
},
{
text: 'Very Good',
position: 'INSIDE',
color: '#555',
},
]}
ringWidth={47}
needleTransitionDuration={3333}
needleTransition="easeElastic"
needleColor={'#90f2ff'}
textColor={'#d8dee9'}
/>
</div>
export const CustomSegmentLabels = () => {

const handleSegmentClick = (segmentLabel, segmentValue) => {
console.log('Segment clicked:', segmentLabel, segmentValue);
// Perform actions based on the segment clicked, like updating state or displaying a message
};

return (
<div>
<ReactSpeedometer
width={500}
needleHeightRatio={0.7}
value={777}
customSegmentStops={[0, 250, 750, 1000]}
segmentColors={['#9399ff', '#14ffec', '#00bbf0']}
currentValueText="How are you?"
customSegmentLabels={[
{
text: 'Good',
position: 'OUTSIDE',
color: '#d8dee9',
},
{
text: 'Great',
position: 'OUTSIDE',
color: '#d8dee9',
},
{
text: 'Awesome!',
position: 'OUTSIDE',
color: '#d8dee9',
},
]}
ringWidth={47}
needleTransitionDuration={3333}
needleTransition="easeElastic"
needleColor={'#a7ff83'}
textColor={'#d8dee9'}
/>
<div>
<ReactSpeedometer
width={500}
needleHeightRatio={0.7}
value={777}
currentValueText="Happiness Level1"
customSegmentLabels={[
{
text: 'Very Bad',
position: 'INSIDE',
color: '#555',
},
{
text: 'Bad',
position: 'INSIDE',
color: '#555',
},
{
text: 'Ok',
position: 'INSIDE',
color: '#555',
fontSize: '19px',
},
{
text: 'Good',
position: 'INSIDE',
color: '#555',
},
{
text: 'Very Good',
position: 'INSIDE',
color: '#555',
},
]}
ringWidth={47}
needleTransitionDuration={3333}
needleTransition="easeElastic"
needleColor={'#90f2ff'}
textColor={'#d8dee9'}
onSegmentClick={handleSegmentClick} // Here is your click handler
/>
</div>
<div>
<ReactSpeedometer
width={500}
needleHeightRatio={0.7}
value={777}
customSegmentStops={[0, 250, 750, 1000]}
segmentColors={['#9399ff', '#14ffec', '#00bbf0']}
currentValueText="How are you?"
customSegmentLabels={[
{
text: 'Good',
position: 'OUTSIDE',
color: '#d8dee9',
},
{
text: 'Great',
position: 'OUTSIDE',
color: '#d8dee9',
},
{
text: 'Awesome!',
position: 'OUTSIDE',
color: '#d8dee9',
},
]}
ringWidth={47}
needleTransitionDuration={3333}
needleTransition="easeElastic"
needleColor={'#a7ff83'}
textColor={'#d8dee9'}
onSegmentClick={handleSegmentClick} // Here is your click handler
/>
</div>
</div>
</div>
)
);
};

export const CustomSegmentColors = () => (
<div>
Expand Down