Refactor RangeBar to just a simple styled component
This commit is contained in:
parent
73d7852309
commit
eea49adfee
|
|
@ -1,4 +1,3 @@
|
|||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
import { ZoneType } from "zwiftout";
|
||||
|
||||
|
|
@ -33,35 +32,33 @@ export const Bar = styled.div<BarProps>`
|
|||
`;
|
||||
|
||||
export type RangeBarProps = {
|
||||
startZone: ZoneType;
|
||||
endZone: ZoneType;
|
||||
// Percentage of total workout length
|
||||
durationPercentage: number;
|
||||
// Percentage of maximum intensity in workout
|
||||
intensityStartPercentage: number;
|
||||
intensityEndPercentage: number;
|
||||
maxIntensityPercentage: number;
|
||||
// Percentage relative to `maxIntensityPercentage`
|
||||
relativeMinIntensityPercentage: number;
|
||||
startZone: ZoneType;
|
||||
endZone: ZoneType;
|
||||
direction: "up" | "down";
|
||||
};
|
||||
|
||||
const createUpPolygon = (middle: number) => `polygon(0% 100%, 100% 100%, 100% 0%, 0% ${middle}%)`;
|
||||
const createDownPolygon = (middle: number) => `polygon(0% 0%, 0% 100%, 100% 100%, 100% ${middle}%)`;
|
||||
|
||||
export const RangeContainer = styled.div<{
|
||||
height: number;
|
||||
width: number;
|
||||
startZone: ZoneType;
|
||||
endZone: ZoneType;
|
||||
middle: number;
|
||||
direction: "up" | "down";
|
||||
}>`
|
||||
export const RangeBar = styled.div<RangeBarProps>`
|
||||
display: inline-block;
|
||||
border-bottom-left-radius: 10px;
|
||||
border-bottom-right-radius: 10px;
|
||||
vertical-align: bottom;
|
||||
margin-right: 0.1%;
|
||||
/* exclude 0.1% margin from bar width */
|
||||
width: ${(props) => props.width - 0.1}%;
|
||||
height: ${(props) => props.height}%;
|
||||
clip-path: ${({ direction, middle }) => (direction === "up" ? createUpPolygon(middle) : createDownPolygon(middle))};
|
||||
width: ${(props) => props.durationPercentage - 0.1}%;
|
||||
height: ${(props) => props.maxIntensityPercentage}%;
|
||||
clip-path: ${({ direction, relativeMinIntensityPercentage }) =>
|
||||
direction === "up"
|
||||
? createUpPolygon(relativeMinIntensityPercentage)
|
||||
: createDownPolygon(relativeMinIntensityPercentage)};
|
||||
background: linear-gradient(
|
||||
to right,
|
||||
${(props) => zoneColorsMap[props.startZone]},
|
||||
|
|
@ -69,22 +66,3 @@ export const RangeContainer = styled.div<{
|
|||
);
|
||||
transition: width 0.1s, height 0.1s, background-color 0.1s;
|
||||
`;
|
||||
|
||||
export const RangeBar: React.FC<RangeBarProps> = (props) => {
|
||||
const minHeightPercentage = Math.min(props.intensityStartPercentage, props.intensityEndPercentage);
|
||||
const maxHeightPercentage = Math.max(props.intensityStartPercentage, props.intensityEndPercentage);
|
||||
const bottomHeight = (minHeightPercentage / maxHeightPercentage) * 100;
|
||||
const topHeight = 100 - bottomHeight;
|
||||
const direction = props.intensityStartPercentage < props.intensityEndPercentage ? "up" : "down";
|
||||
|
||||
return (
|
||||
<RangeContainer
|
||||
height={maxHeightPercentage}
|
||||
width={props.durationPercentage}
|
||||
middle={topHeight}
|
||||
direction={direction}
|
||||
startZone={props.startZone}
|
||||
endZone={props.endZone}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -26,13 +26,21 @@ const Plot = styled.div`
|
|||
margin: 10px 0;
|
||||
`;
|
||||
|
||||
const toRangeBarProps = (interval: Interval, workoutDuration: Duration, maxIntensity: Intensity): RangeBarProps => ({
|
||||
const toRangeBarProps = (interval: Interval, workoutDuration: Duration, maxIntensity: Intensity): RangeBarProps => {
|
||||
const minIntensityPercentage =
|
||||
(Math.min(interval.intensity.start, interval.intensity.end) / maxIntensity.value) * 100;
|
||||
const maxIntensityPercentage =
|
||||
(Math.max(interval.intensity.start, interval.intensity.end) / maxIntensity.value) * 100;
|
||||
|
||||
return {
|
||||
durationPercentage: (interval.duration.seconds / workoutDuration.seconds) * 100,
|
||||
maxIntensityPercentage: maxIntensityPercentage,
|
||||
relativeMinIntensityPercentage: 100 - (minIntensityPercentage / maxIntensityPercentage) * 100,
|
||||
direction: interval.intensity.start < interval.intensity.end ? "up" : "down",
|
||||
startZone: intensityValueToZoneType(interval.intensity.start),
|
||||
endZone: intensityValueToZoneType(interval.intensity.end),
|
||||
durationPercentage: (interval.duration.seconds / workoutDuration.seconds) * 100,
|
||||
intensityStartPercentage: (interval.intensity.start / maxIntensity.value) * 100,
|
||||
intensityEndPercentage: (interval.intensity.end / maxIntensity.value) * 100,
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
export const WorkoutPlot: React.FC<{ intervals: Interval[] }> = ({ intervals }) => {
|
||||
const workoutDuration = totalDuration(intervals);
|
||||
|
|
|
|||
Loading…
Reference in New Issue