recharts#ReferenceArea JavaScript Examples
The following examples show how to use
recharts#ReferenceArea.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: MainLineChart.js From covid with GNU General Public License v3.0 | 4 votes |
MainLineChart = () => {
const chartData = useSelector(state => state.chartData.data);
const maximums = useSelector(state => state.chartData.maximums);
const dataParams = useSelector(state => state.dataParams);
const nType = useSelector(state => state.dataParams.nType);
const dType = useSelector(state => state.dataParams.dType);
const currentVariable = useSelector(state => state.currentVariable);
const currentData = useSelector(state => state.currentData);
const selectionKeys = useSelector(state => state.selectionKeys);
const selectionNames = useSelector(state => state.selectionNames);
const storedData = useSelector(state => state.storedData);
const currentTable = useSelector(state => state.currentTable);
const populationNormalized = useSelector(state => state.chartParams.populationNormalized);
const [logChart, setLogChart] = useState(false);
const [showSummarized, setShowSummarized] = useState(true);
const [activeLine, setActiveLine] = useState(false);
const dispatch = useDispatch();
const handleSwitch = () => setLogChart(prev => !prev)
const handlePopSwitch = () => dispatch(setChartParams({populationNormalized: !populationNormalized}))
const handleSummarizedSwitch = () => setShowSummarized(prev => !prev)
const handleChange = (newValue) => {
if (nType === "time-series" && dType === "time-series") {
dispatch(setVariableParams({nIndex: newValue, dIndex: newValue}))
} else if (nType === "time-series") {
dispatch(setVariableParams({nIndex: newValue}))
} else if (dType === "time-series") {
dispatch(setVariableParams({dIndex: newValue}))
} else if (currentVariable.includes('Testing')){
dispatch(setVariableParams({nIndex: newValue}))
}
};
const chartSetDate = (e) => {
if (e?.activeTooltipIndex !== undefined) {
if (storedData[currentTable.numerator].dates.indexOf(e.activeTooltipIndex) !== -1) {
handleChange(e.activeTooltipIndex)
} else {
handleChange(storedData[currentTable.numerator].dates.reduce((a, b) => {return Math.abs(b - e.activeTooltipIndex) < Math.abs(a - e.activeTooltipIndex) ? b : a}))
}
}
}
const rangeIncrement = ( maximum ) => {
let returnArray = []
const increment = 2*10**(`${maximum}`.length-1);
for (let i=0; i<maximum; i+=increment) {
returnArray.push(i)
}
return returnArray;
}
const handleLegendHover = (o) => {
setActiveLine(o.dataKey)
}
const handleLegendLeave = () => {
setActiveLine(false)
}
if (maximums && chartData) {
return (
<ChartContainer id="lineChart">
{(selectionNames.length < 2) ?
<ChartTitle>Total Cases and 7-Day Average New Cases {selectionNames.length ? `: ${selectionNames[0]}` : ''}</ChartTitle>
:
<ChartTitle>7-Day Average New Cases</ChartTitle>
}
<ResponsiveContainer width="100%" height="80%">
<LineChart
data={chartData}
margin={{
top: 0, right: 10, left: 10, bottom: 20,
}}
onClick={nType === 'characteristic' ? '' : chartSetDate}
>
<XAxis
dataKey="date"
ticks={dateRange}
minTickGap={-50}
tick={
<CustomTick
style={{
fill: `${colors.white}88`,
fontSize: "10px",
fontFamily: "Lato",
fontWeight: 600,
transform:'translateY(10px)'
}}
labelFormatter={dateFormatter}
/>
}
/>
<YAxis yAxisId="left" type="number" scale={logChart ? "log" : "linear"} domain={[0.01, 'dataMax']} allowDataOverflow
ticks={selectionKeys.length === 0 ? rangeIncrement({maximum: maximums.sum}) : []}
minTickGap={1}
tick={
<CustomTick
style={{
fill: colors.lightgray,
fontSize: "10px",
fontFamily: "Lato",
fontWeight: 600
}}
labelFormatter={numberFormatter}
/>
}
>
<Label value="Total Cases" position='insideLeft' style={{marginTop:10, fill:colors.lightgray, fontFamily: 'Lato', fontWeight: 600}} angle={-90} />
</YAxis>
<YAxis yAxisId="right" orientation="right" scale={logChart ? "log" : "linear"} domain={[0.01, 'dataMax']} allowDataOverflow
ticks={selectionKeys.length === 0 ? rangeIncrement({maximum: maximums.count}) : []}
minTickGap={1}
tick={
<CustomTick
style={{
fill: colors.yellow,
fontSize: "10px",
fontFamily: "Lato",
fontWeight: 600,
}}
labelFormatter={numberFormatter}
/>
}
>
<Label value="7-Day Average New Cases" position='insideTopRight' style={{marginTop:10, fill:(selectionKeys.length < 2 ? colors.yellow : colors.lightgray), fontFamily: 'Lato', fontWeight: 600}} angle={-90} />
</YAxis>
<Tooltip
content={CustomTooltip}
/>
<ReferenceArea
yAxisId="left"
x1={dataParams.nRange === null ?
dataParams.variableName.indexOf('Testing') !== -1 ? dataParams.nIndex - 7 : 0
: dataParams.nIndex-dataParams.nRange}
x2={dataParams.nIndex}
fill="white"
fillOpacity={0.15}
isAnimationActive={false}
/>
{selectionKeys.length < 2 && <Line type="monotone" yAxisId="left" dataKey={"sum"} name="Total Cases" stroke={colors.lightgray} dot={false} isAnimationActive={false} /> }
{selectionKeys.length < 2 && <Line type="monotone" yAxisId="right" dataKey={selectionKeys.length > 0 ? selectionNames[0] : "count"} name="7-Day Average New Cases" stroke={colors.yellow} dot={false} isAnimationActive={false} /> }
{(selectionKeys.length > 1 && showSummarized) &&
<Line
type='monotone'
yAxisId='right'
dataKey='sum'
name='Total For Selection'
stroke={colors.lightgray}
strokeWidth={3}
dot={false}
isAnimationActive={false}
/>
}
{selectionKeys.length > 1 &&
selectionNames.map((key,index) => {
return <Line
type='monotone'
yAxisId='left'
dataKey={key}
name={key + ' 7-Day Ave'}
stroke={selectionKeys.length > colors.qualtitiveScale.length ? 'white' : colors.qualtitiveScale[index]}
dot={false}
isAnimationActive={false}
strokeOpacity={activeLine === key ? 1 : 0.7}
strokeWidth={activeLine === key ? 3 : 1}
/>}
)
}
{selectionKeys.length < colors.qualtitiveScale.length && <Legend
onMouseEnter={handleLegendHover}
onMouseLeave={handleLegendLeave}
/>}
</LineChart>
</ResponsiveContainer>
<SwitchesContainer>
<StyledSwitch>
<Switch
checked={logChart}
onChange={handleSwitch}
name='log chart switch'
inputProps={{ 'aria-label': 'secondary checkbox' }}
/>
<p>{logChart ? 'Log Scale' : 'Linear Scale'}</p>
</StyledSwitch>
<StyledSwitch>
<Switch
checked={populationNormalized}
onChange={handlePopSwitch}
name='population normalized chart switch'
inputProps={{ 'aria-label': 'secondary checkbox' }}
/>
<p>{populationNormalized ? 'Per 100k' : 'Counts'}</p>
</StyledSwitch>
{selectionKeys.length > 1 && <StyledSwitch>
<Switch
checked={showSummarized}
onChange={handleSummarizedSwitch}
name='show summarized chart switch'
inputProps={{ 'aria-label': 'secondary checkbox' }}
/>
<p>{showSummarized ? `Show ${populationNormalized ? 'Average' : 'Total'} For Selection` : `Show ${currentData.includes('state') ? 'States' : 'Counties'}` }</p>
</StyledSwitch>}
</SwitchesContainer>
</ChartContainer>
);
} else {
return <div></div>
}
}
Example #2
Source File: MetricsView.jsx From amazon-connect-snippets with MIT No Attribution | 4 votes |
render() {
const {
classes, className: classNameProp, log, indexedLogs,
} = this.props;
const {
skewThreshold,
hideReferenceArea,
referenceAreaOpacities,
hideLatencyGraph,
hideSkewGraph,
} = this.state;
const snapshots = log
.filter((event) => (event.text === 'GET_AGENT_SNAPSHOT succeeded.'))
.flatMap((event) => event.objects.map((object, idx) => ({
...object.snapshot,
_event: event,
_key: `${event._key}-${idx}`,
_date: object.snapshot.snapshotTimestamp.substring(0, 10),
_time: object.snapshot.snapshotTimestamp.substring(11, 23),
_timezone: object.snapshot.snapshotTimestamp.substring(23),
_snapshotTimestamp: dayjs(object.snapshot.snapshotTimestamp).valueOf(),
_localTimestamp: event._ts,
localTimestamp: dayjs(event._ts).toISOString(),
_type: 'SNAPSHOT',
})))
.map((snapshot, idx, arr) => {
const eventKeyFrom = snapshot._event._key;
// eslint-disable-next-line max-len
const eventKeyTo = (idx !== arr.length - 1) ? arr[idx + 1]._event._key : log[log.length - 1]._key;
return {
...snapshot,
// eslint-disable-next-line max-len
_targetEventKeys: Array.from(Array(eventKeyTo - eventKeyFrom), (v, k) => (k + eventKeyFrom)),
};
});
const seqSnapshots = snapshots // removing the duplications in states.
.reduce((acc, x) => {
if (acc.length > 0 && acc[acc.length - 1][0].state.name === x.state.name) {
acc[acc.length - 1].push(x);
} else {
acc.push([x]);
}
return acc;
}, []);
const gradientOffset = () => {
const dataMax = Math.max(...snapshots.map((s) => s.skew));
const dataMin = Math.min(...snapshots.map((s) => s.skew));
const y0 = Math.min(1, Math.max(0, (skewThreshold - dataMin) / (dataMax - dataMin)));
const y1 = Math.min(1, Math.max(0, (-skewThreshold - dataMin) / (dataMax - dataMin)));
return [
1 - y0,
1 - y1,
];
};
const off = gradientOffset();
// filtering out the following APIs for a better representation of the latency
const apiFilter = new Set([
'getAgentSnapshot',
]);
const latencies = log
.filter((event) => (indexedLogs.has(event._key)))
.flatMap((event) => ({
_localTimestamp: event._ts,
localTimestamp: event.time,
_type: 'LATENCY',
...indexedLogs.get(event._key),
}))
.filter((event) => !(apiFilter.has(event.apiName) || event.type === 'SEND'));
const data = () => {
if (hideLatencyGraph && !hideSkewGraph) {
return snapshots;
} if (!hideLatencyGraph && hideSkewGraph) {
return latencies;
}
return snapshots.concat(latencies)
.sort((a, b) => a._localTimestamp - b._localTimestamp);
};
return (
<div className={clsx(classes.root, classNameProp)}>
<Paper>
<div className={classes.header}>
<div className={classes.headerInside}>
<Typography className={classes.title} variant="h6" component="h3">
Metrics
</Typography>
{hideSkewGraph
? (
<Button
className={classes.toggleReferenceArea}
onClick={() => this.handleToggleSkewGraph()}
>
Show Skew Graph
</Button>
)
: (
<Button
className={classes.toggleReferenceArea}
onClick={() => this.handleToggleSkewGraph()}
>
Hide Skew Graph
</Button>
)}
{hideLatencyGraph
? (
<Button
className={classes.toggleReferenceArea}
onClick={() => this.handleToggleLatencyGraph()}
>
Show Latency Graph
</Button>
)
: (
<Button
className={classes.toggleReferenceArea}
onClick={() => this.handleToggleLatencyGraph()}
>
Hide Latency Graph
</Button>
)}
{hideReferenceArea
? (
<Button
className={classes.toggleReferenceArea}
onClick={() => this.handleToggleReferenceArea()}
>
Show Reference Area
</Button>
)
: (
<Button
className={classes.toggleReferenceArea}
onClick={() => this.handleToggleReferenceArea()}
>
Hide Reference Area
</Button>
)}
</div>
</div>
<div className={classes.content}>
<ResponsiveContainer width="100%" height={300}>
<ComposedChart
data={data()}
margin={{
top: 5, right: 20, bottom: 5, left: 20,
}}
>
<YAxis
yAxisId={1}
label={{
value: 'Skew (ms)', angle: -90, offset: 0, position: 'left',
}}
/>
<YAxis
yAxisId={2}
label={{
value: 'Latency (ms)', angle: 90, offset: 0, position: 'right',
}}
orientation="right"
/>
<XAxis dataKey="_localTimestamp" type="number" scale="time" domain={['auto', 'auto']} tick={this.renderCustomAxisTick} />
<CartesianGrid stroke="#ccc" strokeDasharray="5 5" />
{/* eslint-disable-next-line max-len */}
{/* <Line yAxisId={1} type="monotone" dataKey="skew" stroke="#000000" connectNulls={true}/> */}
{!hideSkewGraph
&& <Area yAxisId={1} type="monotone" dataKey="skew" stroke="#000" fill="url(#splitColor)" connectNulls isAnimationActive={false} />}
{!hideLatencyGraph
&& <Line yAxisId={2} type="linear" dataKey="latency" stroke="#0000ff" strokeWidth={2} dot={this.renderDots} activeDot={this.renderActiveDots} connectNulls isAnimationActive={false} />}
<Tooltip content={this.renderCustomTooltip} />
<defs>
<linearGradient id="splitColor" x1="0" y1="0" x2="0" y2="1">
<stop offset={off[0]} stopColor="red" stopOpacity={1} />
<stop offset={off[0]} stopColor="green" stopOpacity={1} />
<stop offset={off[1]} stopColor="green" stopOpacity={1} />
<stop offset={off[1]} stopColor="red" stopOpacity={1} />
</linearGradient>
</defs>
{!hideReferenceArea && seqSnapshots.map((s, i, arr) => {
const s0 = s[0];
const s1 = (i < arr.length - 1)
? arr[i + 1][0] : s[s.length - 1];
const stateHits = Object.keys(colorMap)
.filter((name) => s0.state.name.includes(name));
const color = (stateHits.length > 0)
? colorMap[stateHits[0]] : colorMap.__other;
// eslint-disable-next-line max-len
const opacity = (stateHits.length > 0) ? referenceAreaOpacities[stateHits[0]] : referenceAreaOpacities.__other;
return (
<ReferenceArea
yAxisId={1}
key={s0._key}
className={classes.referenceArea}
x1={s0._localTimestamp}
x2={s1._localTimestamp}
ifOverflow="extendDomain"
opacity={opacity}
fill={color}
/>
);
})}
{!hideReferenceArea && <Legend content={this.renderCustomLegend} />}
</ComposedChart>
</ResponsiveContainer>
</div>
</Paper>
</div>
);
}
Example #3
Source File: SkewMetricsView.jsx From amazon-connect-snippets with MIT No Attribution | 4 votes |
render() {
const {
classes, className: classNameProp, log,
} = this.props;
const {
skewThreshold,
hideReferenceArea,
referenceAreaOpacities,
} = this.state;
const snapshots = log
.filter((event) => (event.text === 'GET_AGENT_SNAPSHOT succeeded.'))
.flatMap((event) => event.objects.map((object, idx) => ({
...object.snapshot,
_event: event,
_key: `${event._key}-${idx}`,
_date: object.snapshot.snapshotTimestamp.substring(0, 10),
_time: object.snapshot.snapshotTimestamp.substring(11, 23),
_timezone: object.snapshot.snapshotTimestamp.substring(23),
_snapshotTimestamp: dayjs(object.snapshot.snapshotTimestamp).valueOf(),
_localTimestamp: event._ts,
localTimestamp: dayjs(event._ts).toISOString(),
_type: 'SNAPSHOT',
})))
.map((snapshot, idx, arr) => {
const eventKeyFrom = snapshot._event._key;
// eslint-disable-next-line max-len
const eventKeyTo = (idx !== arr.length - 1) ? arr[idx + 1]._event._key : log[log.length - 1]._key;
return {
...snapshot,
// eslint-disable-next-line max-len
_targetEventKeys: Array.from(Array(eventKeyTo - eventKeyFrom), (v, k) => (k + eventKeyFrom)),
};
});
const seqSnapshots = snapshots // removing the duplications in states.
.reduce((acc, x) => {
if (acc.length > 0 && acc[acc.length - 1][0].state.name === x.state.name) {
acc[acc.length - 1].push(x);
} else {
acc.push([x]);
}
return acc;
}, []);
const gradientOffset = () => {
const dataMax = Math.max(...snapshots.map((s) => s.skew));
const dataMin = Math.min(...snapshots.map((s) => s.skew));
const y0 = Math.min(1, Math.max(0, (skewThreshold - dataMin) / (dataMax - dataMin)));
const y1 = Math.min(1, Math.max(0, (-skewThreshold - dataMin) / (dataMax - dataMin)));
return [
1 - y0,
1 - y1,
];
};
const off = gradientOffset();
const data = () => snapshots;
return (
<div className={clsx(classes.root, classNameProp)}>
<Container
title="Skew Metrics"
gutters={false}
actionGroup={(
<>
{hideReferenceArea
? (
<Button
className={classes.toggleReferenceArea}
onClick={() => this.handleToggleReferenceArea()}
>
Show Reference Area
</Button>
)
: (
<Button
className={classes.toggleReferenceArea}
onClick={() => this.handleToggleReferenceArea()}
>
Hide Reference Area
</Button>
)}
</>
)}
>
<div className={classes.content}>
<ResponsiveContainer width="100%" height={300}>
<ComposedChart
data={data()}
margin={{
top: 5, right: 20, bottom: 5, left: 20,
}}
>
<YAxis>
<Label angle={270} position="left" style={{ textAnchor: 'middle' }}>
Skew (ms)
</Label>
</YAxis>
<XAxis dataKey="_localTimestamp" type="number" scale="time" domain={['auto', 'auto']} tick={this.renderCustomAxisTick} />
<CartesianGrid stroke="#ccc" strokeDasharray="5 5" />
{/* eslint-disable-next-line max-len */}
<Area type="monotone" dataKey="skew" stroke="#000" fill="url(#splitColor)" connectNulls isAnimationActive={false} />
<Tooltip content={this.renderCustomTooltip} />
<defs>
<linearGradient id="splitColor" x1="0" y1="0" x2="0" y2="1">
<stop offset={off[0]} stopColor="red" stopOpacity={1} />
<stop offset={off[0]} stopColor="green" stopOpacity={1} />
<stop offset={off[1]} stopColor="green" stopOpacity={1} />
<stop offset={off[1]} stopColor="red" stopOpacity={1} />
</linearGradient>
</defs>
{!hideReferenceArea && seqSnapshots.map((s, i, arr) => {
const s0 = s[0];
const s1 = (i < arr.length - 1)
? arr[i + 1][0] : s[s.length - 1];
const stateHits = Object.keys(colorMap)
.filter((name) => s0.state.name.includes(name));
const color = (stateHits.length > 0)
? colorMap[stateHits[0]] : colorMap.__other;
// eslint-disable-next-line max-len
const opacity = (stateHits.length > 0) ? referenceAreaOpacities[stateHits[0]] : referenceAreaOpacities.__other;
return (
<ReferenceArea
key={s0._key}
className={classes.referenceArea}
x1={s0._localTimestamp}
x2={s1._localTimestamp}
ifOverflow="extendDomain"
opacity={opacity}
fill={color}
/>
);
})}
{!hideReferenceArea && <Legend content={this.renderCustomLegend} />}
</ComposedChart>
</ResponsiveContainer>
</div>
</Container>
</div>
);
}
Example #4
Source File: MultiLinePlot.jsx From covince with MIT License | 4 votes |
MainChart = React.memo((props) => {
const {
activeLineages,
chart,
dateRange,
darkMode,
precision,
preset,
stroke,
tooltipEnabled,
type,
xAxisProps,
yAxisConfig = {},
zoomArea,
...chartProps
} = props
const { lineages, data, dates } = chart
const yAxisDomain = useMemo(() => {
if (yAxisConfig && yAxisConfig.domain) {
return yAxisConfig.domain
}
if (preset === 'percentage' && type === 'area' && lineages.length === Object.keys(activeLineages).length) {
return [0, 100]
}
if (dateRange && data.length) {
if (type === 'area') {
const [minIndex, maxIndex] = xAxisProps.domain
const range = data.slice(minIndex, maxIndex + 1)
let { sumY: max } = range[0]
for (const { sumY } of range.slice(1)) {
max = Math.max(sumY, max)
}
return [0, Math.ceil(max)]
} else {
const [minIndex, maxIndex] = xAxisProps.domain
const range = data.slice(minIndex, maxIndex + 1)
let { maxY: max } = range[0]
for (const { maxY } of range.slice(1)) {
max = Math.max(maxY, max)
}
return [0, Math.ceil(max)]
}
}
if (preset === 'percentage' && type === 'area' && lineages.length) {
return [0, 1]
}
return [0, 'auto']
}, [preset, type, yAxisConfig, lineages, xAxisProps.domain, data])
const yAxisTicks = useMemo(() => {
if (preset === 'percentage') {
if (lineages.length === 0) {
return { ticks: false }
}
const fullScale = lineages.length === Object.keys(activeLineages).length
if (fullScale) {
return {
tickFormatter: value => `${Math.min(parseFloat(value), 100)}%`,
ticks: dateRange ? undefined : [0, 25, 50, 75, 100]
}
}
return {
tickFormatter: value => {
if (value === 0) return '0%'
if (value >= 100) return '100%'
if (!Number.isInteger(value)) return `${value.toFixed(1)}%`
return `${value}%`
}
}
}
return {
tickFormatter: value => {
const valueStr = value.toString()
if (valueStr.length > 4) {
const tripleFigureCount = Math.floor((valueStr.length - 1) / 3)
const prefix = (value / Math.pow(1000, tripleFigureCount))
const prefixStr = prefix.toString()
return (
(prefixStr.length < 4 ? prefixStr : prefix.toPrecision(3)) +
(tripleFigureLabel[tripleFigureCount] || '')
)
}
return value.toLocaleString()
},
ticks: dateRange ? undefined : yAxisConfig.ticks
}
}, [preset, lineages, activeLineages, yAxisConfig, dateRange])
const grid =
<CartesianGrid stroke={tailwindColors[stroke][darkMode ? 500 : 300]} />
const [highlightedLineage, setHighlightedLineage] = useState(null)
const tooltip = useMemo(() =>
(tooltipEnabled && lineages.length > 0)
? <Tooltip
content={ChartTooltip}
cursor={{ stroke: tailwindColors[stroke][darkMode ? 300 : 400] }}
dates={dates}
percentage={preset === 'percentage'}
precision={precision}
sortByValue={type !== 'area'}
highlightedItem={highlightedLineage}
/>
: null
, [tooltipEnabled, stroke, dates, preset, precision, highlightedLineage, type])
const xAxis = useMemo(() =>
<XAxis
{...xAxisProps}
fontSize='12'
tick={data.length}
tickFormatter={i => i in data ? format(new Date(data[i].date), 'd MMM') : ''}
tickMargin='4'
stroke='currentcolor'
/>
, [data, xAxisProps])
const yAxis =
<YAxis
type='number'
allowDataOverflow={dateRange || yAxisConfig.allow_data_overflow || false}
domain={yAxisDomain}
width={48}
stroke='currentcolor'
tickMargin='4'
tick={data.length}
allowDecimals={false}
{...yAxisTicks}
/>
const areas = useMemo(() => {
if (type === 'area') {
return lineages.map(({ lineage, colour = fallbackColour }) => (
<Area
key={lineage}
activeDot={{ stroke: tailwindColors[stroke][400] }}
dataKey={lineage}
dot={false}
fill={colour}
fillOpacity={highlightedLineage === lineage ? 0.8 : undefined}
name={lineage}
stackId='1'
stroke={colour}
type='monotone'
animationDuration={animationDuration}
isAnimationActive={true}
onMouseEnter={({ name }) => { setHighlightedLineage(name) }}
onMouseLeave={() => { setHighlightedLineage(null) }}
/>
))
}
return lineages
.filter(_ => _.average !== 0)
.map(({ lineage, colour = fallbackColour }) => {
const key = `${lineage}_range`
return (
<Area
key={key}
activeDot={false}
dataKey={key}
fill={colour}
name='_range'
strokeWidth={0}
type='monotone'
animationDuration={animationDuration}
isAnimationActive={true}
/>
)
})
}, [lineages, stroke, type, highlightedLineage])
const lines = useMemo(() => {
if (type === 'area') return null
return lineages.map(({ lineage, colour = fallbackColour }) =>
<Line
key={lineage}
activeDot={{ stroke: tailwindColors[stroke][400] }}
dataKey={lineage}
dot={false}
name={lineage}
stroke={colour}
type='monotone'
animationDuration={animationDuration}
isAnimationActive={true}
/>
)
}, [lineages, stroke, type])
const yReference = useMemo(() => {
if (yAxisConfig.reference_line === undefined) return null
return (
<ReferenceLine
y={yAxisConfig.reference_line}
stroke={tailwindColors[stroke][darkMode ? 400 : 600]}
strokeDasharray={[8, 8]}
label=''
strokeWidth={2}
style={{ mixBlendMode: darkMode ? 'screen' : 'multiply' }}
/>
)
}, [yAxisConfig.reference_line, stroke])
return (
<ComposedChart
{...chartProps}
data={[...data] /* new array required for animations */}
>
{grid}
{areas}
{xAxis}
{yAxis}
{tooltip}
{yReference}
{lines}
{zoomArea.start !== undefined
? <ReferenceArea x1={zoomArea.start} x2={zoomArea.end} strokeOpacity={0.3} />
: null}
</ComposedChart>
)
})
Example #5
Source File: AdvancedGraph.js From covid-19 with MIT License | 4 votes |
Chart = (props) => {
const ordered = (props.specs || []).sort((a, b) => {
if (a.derived && !b.derived) {
return -1;
} else if (!a.derived && b.derived) {
return 1;
} else {
return a.label < b.label ? -1 : 1;
}
});
let YAxis0Color = "black";
let YAxis1Color = undefined;
for (const s of ordered) {
if (s.rightAxis) {
YAxis1Color = s.color;
} else {
YAxis0Color = s.color;
}
}
function getvRefLines(lines) {
let result = (lines || []).map((l, idx) => {
return <ReferenceLine key={`vrefline${idx}`}
x={l.date}
stroke="#e3e3e3"
strokeWidth={1}
>
<Label value={l.label} position={"insideTop"} fill="#b3b3b3" />
</ReferenceLine>
}
);
return result;
}
function getvRefAreas(lines) {
let result = (lines || []).map((l, idx) => {
const startdate = l.date;
const today = moment().unix();
let enddate = startdate + 14 * 24 * 60 * 60;
while (enddate > today) {
enddate -= 24 * 60 * 60;
}
return <ReferenceArea key={`vrefarea${idx}`}
x1={startdate} x2={enddate}
// stroke="red"
// strokeOpacity={0.3}
fillOpacity={0.15}
/>
}
);
return result;
}
function gethRefLines(lines) {
let result = (lines || []).map((l, idx) => {
return <ReferenceLine key={`hrefline${idx}`}
y={l.value}
stroke="#e3e3e3"
strokeWidth={1}
>
<Label value={l.label} position={"insideLeft"} ></Label>
</ReferenceLine>
}
);
return result;
}
let vRefLines = getvRefLines(props.vRefLines);
let hRefLines = gethRefLines(props.hRefLines);
return (
<ResponsiveContainer height={300}>
<LineChart data={props.data} margin={{ left: -4, right: 8 }}>
{vRefLines}
{hRefLines}
{getvRefAreas(props.vRefLines)}
<Tooltip
formatter={valueFormatter}
labelFormatter={props.timestampFormatter}
/>
<XAxis
dataKey="timestamp"
tickFormatter={props.timestampFormatter}
/>
<YAxis
yAxisId={0}
tick={{ fill: YAxis0Color }}
scale={props.scale === 'Log' ? logScale : props.scale}
width={50}
tickFormatter={props.yAxisFormatter}
/>
{YAxis1Color &&
<YAxis
yAxisId={1}
tickFormatter={props.yAxisFormatter}
width={35}
tick={{ fill: YAxis1Color }}
orientation="right"
/>
}
<CartesianGrid stroke="#d5d5d5" strokeDasharray="5 5" />
{ordered.flatMap(spec => specToElements(spec))}
</LineChart>
</ResponsiveContainer>
);
}
Example #6
Source File: RtcMetricsView.jsx From amazon-connect-snippets with MIT No Attribution | 3 votes |
render() {
const {
classes, className: classNameProp,
type, timeRange, indexRange: [startIndex, endIndex],
} = this.props;
const {
data, originalData,
brushHovering, refAreaLeft, refAreaRight,
} = this.state;
return (
<div className={clsx(classes.root, classNameProp)}>
<Container
title={`WebRTC Metrics - ${type}`}
gutters={false}
actionGroup={(
<Button
className={classes.zoomResetButton}
onClick={this.handleZoomReset}
>
Zoom Reset
</Button>
)}
>
<div className={classes.content}>
{/* Audio Level */}
<ResponsiveContainer width="100%" height={200}>
<LineChart
data={data}
margin={{
top: 5, right: 20, bottom: 5, left: 20,
}}
onMouseDown={this.handleMouseDown}
onMouseMove={this.handleMouseMove}
onMouseUp={this.handleZoom}
>
<YAxis allowDataOverflow type="number">
<Label angle={270} position="left" style={{ textAnchor: 'middle' }}>
Audio Level
</Label>
</YAxis>
<XAxis allowDataOverflow dataKey={TIMESTAMP_KEY} tick={this.renderCustomAxisTick} type="number" domain={timeRange} />
<CartesianGrid />
<Line
type="linear"
dataKey="audioLevel"
stroke={colorMap.audioLevel}
strokeWidth={2}
dot={false}
activeDot
connectNulls={false}
isAnimationActive={false}
/>
<Tooltip content={this.renderCustomTooltip(['audioLevel'])} />
<Legend verticalAlign="bottom" />
{ (refAreaLeft && refAreaRight) && (
<ReferenceArea
x1={refAreaLeft}
x2={refAreaRight}
strokeOpacity={0.3}
/>
)}
</LineChart>
</ResponsiveContainer>
{/* Packets */}
<ResponsiveContainer width="100%" height={200}>
<ComposedChart
data={data}
margin={{
top: 5, right: 20, bottom: 5, left: 20,
}}
onMouseDown={this.handleMouseDown}
onMouseMove={this.handleMouseMove}
onMouseUp={this.handleZoom}
>
<YAxis allowDataOverflow type="number">
<Label angle={270} position="left" style={{ textAnchor: 'middle' }}>
Packets
</Label>
</YAxis>
<XAxis allowDataOverflow dataKey={TIMESTAMP_KEY} tick={this.renderCustomAxisTick} type="number" domain={timeRange} />
<CartesianGrid />
<Line
type="linear"
dataKey="packetsLost"
stroke={colorMap.packetsLost}
strokeWidth={2}
dot={false}
activeDot
connectNulls={false}
isAnimationActive={false}
/>
<Line
type="linear"
dataKey="packetsCount"
stroke={colorMap.packetsCount}
strokeWidth={2}
dot={false}
activeDot
connectNulls={false}
isAnimationActive={false}
/>
<Tooltip content={this.renderCustomTooltip(['packetsLost', 'packetsCount'])} />
<Legend verticalAlign="bottom" />
{ (refAreaLeft && refAreaRight) && (
<ReferenceArea
x1={refAreaLeft}
x2={refAreaRight}
strokeOpacity={0.3}
/>
)}
</ComposedChart>
</ResponsiveContainer>
{/* Jitter Buffer and RTT */}
<ResponsiveContainer width="100%" height={200}>
<ComposedChart
data={data}
margin={{
top: 5, right: 20, bottom: 5, left: 20,
}}
onMouseDown={this.handleMouseDown}
onMouseMove={this.handleMouseMove}
onMouseUp={this.handleZoom}
>
<YAxis allowDataOverflow type="number">
{ type === 'audio_input' && (
<Label angle={270} position="left" style={{ textAnchor: 'middle' }}>
Jitter Buffer (ms)
</Label>
)}
{ type === 'audio_output' && (
<Label angle={270} position="left" style={{ textAnchor: 'middle' }}>
Jitter Buffer & RTT (ms)
</Label>
)}
</YAxis>
<XAxis allowDataOverflow dataKey={TIMESTAMP_KEY} tick={this.renderCustomAxisTick} type="number" domain={timeRange} />
<CartesianGrid />
<Line
type="linear"
dataKey="jitterBufferMillis"
stroke={colorMap.jitterBufferMillis}
strokeWidth={2}
dot={false}
activeDot
connectNulls={false}
isAnimationActive={false}
/>
{ type === 'audio_output' && (
<Line
type="linear"
dataKey="roundTripTimeMillis"
stroke={colorMap.roundTripTimeMillis}
strokeWidth={2}
dot={false}
activeDot
connectNulls={false}
isAnimationActive={false}
/>
)}
<Tooltip
content={
type === 'audio_output'
? this.renderCustomTooltip(['jitterBufferMillis', 'roundTripTimeMillis'])
: this.renderCustomTooltip(['jitterBufferMillis'])
}
/>
<Legend verticalAlign="bottom" />
{ (refAreaLeft && refAreaRight) && (
<ReferenceArea
x1={refAreaLeft}
x2={refAreaRight}
strokeOpacity={0.3}
/>
)}
</ComposedChart>
</ResponsiveContainer>
{/* Brush */}
<ResponsiveContainer width="100%" height={60}>
<ComposedChart
// update data to force re-rendering
data={brushHovering ? originalData : [...originalData]}
margin={{
top: 5, right: 20, bottom: 5, left: 20,
}}
onMouseEnter={() => this.setState({ brushHovering: true })}
onMouseLeave={() => this.setState({ brushHovering: false })}
>
<Brush
className="TimeLineChart-brush"
dataKey={TIMESTAMP_KEY}
stroke="#666666"
startIndex={startIndex || 0}
endIndex={endIndex || originalData.length - 1}
onChange={this.handleChangeBrush}
tickFormatter={this.formatBrushTick}
/>
</ComposedChart>
</ResponsiveContainer>
</div>
</Container>
</div>
);
}