victory#VictoryChart JavaScript Examples
The following examples show how to use
victory#VictoryChart.
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: chart.js From astroport-lbp-frontend with MIT License | 6 votes |
function Chart({ xAxis, yAxis, children, ...rest }) {
return (
<VictoryChart theme={theme} { ...rest }>
<VictoryAxis
independentAxis
gridComponent={<LineSegment y2={10} />}
{ ...xAxis }
/>
<VictoryAxis
dependentAxis
tickLabelComponent={<VictoryLabel dy={-5} verticalAnchor={"end"} />}
{ ...yAxis }
/>
{children}
</VictoryChart>
);
}
Example #2
Source File: Graph.jsx From covid-trials-dashboard with MIT License | 6 votes |
Graph = () => {
return (
<div>
<VictoryChart
domainPadding={{ x: 50 }}
width={500}
height={500}
theme={VictoryTheme.material}
>
<VictoryGroup
horizontal
offset={20}
style={{ data: { width: 15 } }}
colorScale={[sadBlue, magenta, yellow, tourquese, green]}
>
{/* Need to bing the label data to the VictoryLabel for each bar */}
{vaccinesData.map((mockData, i) => (
<VictoryStack key={i}>
{mockData.map((data, index) => {
return <VictoryBar key={index} data={data} />
})}
</VictoryStack>
))}
</VictoryGroup>
</VictoryChart>
</div>
)
}
Example #3
Source File: SelectedPool.js From katanapools with GNU General Public License v2.0 | 6 votes |
render() {
const web3 = window.web3;
const currentNetwork = web3.currentProvider.networkVersion;
const {poolHistory, selectedPool: {symbol}} = this.props;
let graphData = poolHistory.map(function(item){
return {x: moment(item.timeStamp).format('MM-DD'), y: parseInt(item.data)}
});
if (graphData.length === 0) {
return <div className="graph-message-text">Volume graph data not available</div>
}
if (currentNetwork !== '1') {
return <div className="graph-message-text">Volume graph is available only on mainnet</div>
}
return (
<div>
<VictoryChart
>
<VictoryLine
style={{
data: { stroke: "#c43a31" },
parent: { border: "1px solid #ccc"}
}}
data={graphData}
/>
<VictoryAxis dependentAxis/>
<VictoryAxis fixLabelOverlap={true}/>
</VictoryChart>
<div className="h7 text-center">Daily conversion vol from reserve to {symbol} (ETH)</div>
</div>
)
}
Example #4
Source File: MonthlyScatter.js From Full-Stack-React-Projects-Second-Edition with MIT License | 5 votes |
export default function MonthlyScatter() {
const classes = useStyles()
const [error, setError] = useState('')
const [plot, setPlot] = useState([])
const [month, setMonth] = useState(new Date())
const jwt = auth.isAuthenticated()
useEffect(() => {
const abortController = new AbortController()
const signal = abortController.signal
plotExpenses({month: month},{t: jwt.token}, signal).then((data) => {
if (data.error) {
setError(data.error)
} else {
setPlot(data)
}
})
return function cleanup(){
abortController.abort()
}
}, [])
const handleDateChange = date => {
setMonth(date)
plotExpenses({month: date},{t: jwt.token}).then((data) => {
if (data.error) {
setError(data.error)
} else {
setPlot(data)
}
})
}
return (
<div style={{marginBottom: 20}}>
<Typography variant="h6" className={classes.title}>Expenses scattered over </Typography>
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<DatePicker value={month} onChange={handleDateChange} views={["year", "month"]}
disableFuture
label="Month"
animateYearScrolling
variant="inline"/>
</MuiPickersUtilsProvider>
<VictoryChart
theme={VictoryTheme.material}
height={400}
width={550}
domainPadding={40}
>
<VictoryScatter
style={{
data: { fill: "#01579b", stroke: "#69f0ae", strokeWidth: 2 },
labels: { fill: "#01579b", fontSize: 10, padding:8}
}}
bubbleProperty="y"
maxBubbleSize={15}
minBubbleSize={5}
labels={({ datum }) => `$${datum.y} on ${datum.x}th`}
labelComponent={<VictoryTooltip/>}
data={plot}
domain={{x: [0, 31]}}
/>
<VictoryLabel
textAnchor="middle"
style={{ fontSize: 14, fill: '#8b8b8b' }}
x={270} y={390}
text={`day of month`}
/>
<VictoryLabel
textAnchor="middle"
style={{ fontSize: 14, fill: '#8b8b8b' }}
x={6} y={190}
angle = {270}
text={`Amount ($)`}
/>
</VictoryChart>
</div>
)
}
Example #5
Source File: YearlyBar.js From Full-Stack-React-Projects-Second-Edition with MIT License | 5 votes |
export default function Reports() {
const classes = useStyles()
const [error, setError] = useState('')
const [year, setYear] = useState(new Date())
const [yearlyExpense, setYearlyExpense] = useState([])
const jwt = auth.isAuthenticated()
const monthStrings = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
useEffect(() => {
const abortController = new AbortController()
const signal = abortController.signal
yearlyExpenses({year: year.getFullYear()},{t: jwt.token}, signal).then((data) => {
if (data.error) {
setError(data.error)
}
setYearlyExpense(data)
})
return function cleanup(){
abortController.abort()
}
}, [])
const handleDateChange = date => {
setYear(date)
yearlyExpenses({year: date.getFullYear()},{t: jwt.token}).then((data) => {
if (data.error) {
setError(data.error)
}
setYearlyExpense(data)
})
}
return (
<div>
<Typography variant="h6" className={classes.title}>Your monthly expenditures in</Typography>
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<DatePicker value={year} onChange={handleDateChange} views={["year"]}
disableFuture
label="Year"
animateYearScrolling
variant="inline"/>
</MuiPickersUtilsProvider>
<VictoryChart
theme={VictoryTheme.material}
domainPadding={10}
height={300}
width={450}>
<VictoryAxis/>
<VictoryBar
categories={{
x: monthStrings
}}
style={{ data: { fill: "#69f0ae", width: 20 }, labels: {fill: "#01579b"} }}
data={yearlyExpense.monthTot}
x={monthStrings['x']}
domain={{x: [0, 13]}}
labels={({ datum }) => `$${datum.y}`}
/>
</VictoryChart>
</div>
)
}
Example #6
Source File: Chart.js From web with GNU General Public License v3.0 | 5 votes |
Chart = ({ data, footer, header }) => {
if (not(data)) {
return null;
}
if (data.every(value => not(value))) {
return null;
}
const parsedData = data && data.length > 2 ? data.slice(0, 2) : data;
const renderData = parsedData.map((values, index) => {
const points = values.map((y, x) => ({
x,
y
}));
return (
<VictoryArea
data={points}
height={80}
// eslint-disable-next-line
key={index}
labels={({ datum }) => (parsedData.length >= 2 ? null : `+ ${numberWithSpaces(datum.y)}`)}
labelComponent={<VictoryLabel renderInPortal verticalAnchor="middle" textAnchor="end" />}
style={styles[index]}
/>
);
});
return (
<Styled.Wrapper>
<Styled.Header>
<Small color={Color.lightGray}>{header}</Small>
</Styled.Header>
{/* Number of values is provided by props in order to display only the last value on the chart */}
{/* All data elements should have the same length at the moment (14 days) */}
<Styled.Chart numberOfValues={data[0].length}>
<VictoryChart height={80} padding={{ top: 15 }}>
{renderData}
<VictoryAxis style={{ axis: { stroke: Color.white } }} />
</VictoryChart>
</Styled.Chart>
<Styled.Footer>
<Small color={Color.lightGray}>{footer}</Small>
</Styled.Footer>
</Styled.Wrapper>
);
}
Example #7
Source File: CashFlowGraph.js From actual with MIT License | 5 votes |
function CashFlowGraph({ style, start, end, graphData, isConcise, compact }) {
return (
<Container>
{(width, height, portalHost) =>
graphData && (
<VictoryChart
scale={{ x: 'time' }}
theme={theme}
domainPadding={10}
width={width}
height={height}
containerComponent={
<VictoryVoronoiContainer voronoiDimension="x" />
}
>
<VictoryGroup>
<VictoryBar
data={graphData.expenses}
style={{ data: { fill: theme.colors.red } }}
/>
<VictoryBar data={graphData.income} />
</VictoryGroup>
<VictoryLine
data={graphData.balances}
labelComponent={<Tooltip portalHost={portalHost} />}
labels={x => x.premadeLabel}
style={{
data: { stroke: colors.n5 }
}}
/>
<VictoryAxis
tickFormat={x => d.format(x, isConcise ? "MMM ''yy" : 'MMM d')}
tickValues={graphData.balances.map(item => item.x)}
tickCount={Math.min(5, graphData.balances.length)}
offsetY={50}
/>
<VictoryAxis dependentAxis crossAxis={false} />
</VictoryChart>
)
}
</Container>
);
}
Example #8
Source File: NetWorthGraph.js From actual with MIT License | 5 votes |
function NetWorthGraph({ style, start, end, graphData, compact }) {
const Chart = compact ? VictoryGroup : VictoryChart;
return (
<Container style={[style, compact && { height: 'auto' }]}>
{(width, height, portalHost) =>
graphData && (
<Chart
scale={{ x: 'time' }}
theme={theme}
domainPadding={{ x: 0, y: 10 }}
width={width}
height={height}
containerComponent={
<VictoryVoronoiContainer voronoiDimension="x" />
}
padding={
compact && {
top: 0,
bottom: 0,
left: 0,
right: 0
}
}
>
<Area
start={graphData.start}
end={graphData.end}
data={graphData.data}
/>
{React.createElement(
graphData.data.length === 1 ? VictoryBar : VictoryArea,
{
data: graphData.data,
labelComponent: <Tooltip portalHost={portalHost} />,
labels: x => x.premadeLabel,
style: {
data:
graphData.data.length === 1
? { width: 50 }
: {
clipPath: 'url(#positive)',
fill: 'url(#positive-gradient)'
}
}
}
)}
{graphData.data.length > 1 && (
<VictoryArea
data={graphData.data}
style={{
data: {
clipPath: 'url(#negative)',
fill: 'url(#negative-gradient)',
stroke: theme.colors.red,
strokeLinejoin: 'round'
}
}}
/>
)}
{!compact && (
<VictoryAxis
tickFormat={x => d.format(x, "MMM ''yy")}
tickValues={graphData.data.map(item => item.x)}
tickCount={Math.min(5, graphData.data.length)}
offsetY={50}
/>
)}
{!compact && (
<VictoryAxis dependentAxis crossAxis={!graphData.hasNegative} />
)}
</Chart>
)
}
</Container>
);
}
Example #9
Source File: Rewards.js From testnets-cardano-org with MIT License | 5 votes |
RewardsGraph = ({ title, yLabel, currencySymbol, data, normalizeLargeNumber }) => (
<ChartContainer marginTop={8}>
<h4>{title}</h4>
<Theme.Consumer>
{({ theme }) => (
<VictoryChart
width={500}
height={300}
scale={{ x: 'linear' }}
padding={{ top: 75, bottom: 55, left: 100, right: 65 }}
containerComponent={
<VictoryVoronoiContainer
voronoiDimension='x'
labels={({ datum }) => `Epoch: ${datum.x}\n${currencySymbol} ${normalizeLargeNumber(datum.y, 6)}\n${currencySymbol} ${normalizeLargeNumber(datum.reward, 6)}`}
/>
}
>
<VictoryAxis
crossAxis={false}
label='Epoch'
style={{
tickLabels: { fill: theme.palette.text.primary },
axisLabel: { fill: theme.palette.text.primary, padding: 35 }
}}
/>
<VictoryAxis
dependentAxis
label={yLabel}
style={{
tickLabels: { fill: theme.palette.text.primary },
axisLabel: { fill: theme.palette.text.primary, padding: 70 }
}}
/>
<VictoryLine
style={{
data: { stroke: theme.palette.primary.light }
}}
data={data}
labelComponent={<VictoryTooltip />}
/>
</VictoryChart>
)}
</Theme.Consumer>
</ChartContainer>
)
Example #10
Source File: HELData.jsx From ChronoFactorem with GNU General Public License v3.0 | 4 votes |
HELData = () => {
const [studentData, setStudentData] = React.useState({
courseStats: []
});
const { courseStats } = studentData;
let result = "";
const HELstats = e => {
e.preventDefault();
let et = e.target.innerHTML.toLowerCase();
let event = et.split(" ");
event = event[0] + " " + event[1];
try {
axios.get(`/api/helData/searchHEL/${event}`).then(res => {
resp = true;
result = res.data.studentsInterestedInAllSlots;
let newCSarray = [];
if (result) {
for (let i = 0; i < 8; i++) {
newCSarray.push({ x: i + 1, y: result[i] });
}
}
setStudentData({ ...studentData, courseStats: newCSarray });
});
} catch (err) {
console.log("DB RETRIEVAL ERROR:", err);
}
if (courseStats.length === 0) return false;
courseData = et;
return true;
};
function filterItems(input) {
const userInput = input.target.value.toLowerCase();
let courses = JSON.parse(JSON.stringify(TimeTableData)).default;
let filterCourses = obj =>
Object.keys(obj)
.filter(
item =>
item.toLowerCase().search(userInput) !== -1 ||
obj[item]["name"].toLowerCase().search(userInput) !== -1
)
.filter(
code =>
code.startsWith("GS") ||
code.startsWith("HSS") ||
code.startsWith("BITS F214") ||
code.startsWith("BITS F385") ||
code.startsWith("BITS F399")
)
.reduce((res, key) => {res[key] = obj[key]; return res}, {});
humCourses = filterCourses(courses);
setStudentData({ ...studentData }); //force component update
}
let resp = true;
let str = [
<div style={{ float: "right", width: "35%" }}>
<Search action={filterItems} />
<ItemList
items={humCourses}
action={e => {
HELstats(e);
}}
/>
</div>
];
const [, loading] = useGetData("/api/heldata/searchHEL/:name");
if (!loading) {
if (resp === true && courseStats.length > 0) {
let max = 0;
for (let i of courseStats) max = i["y"] > max ? i["y"] : max;
str.push([
<div style={{ float: "left", width: "64%" }}>
<VictoryChart domainPadding={10} animate={{ duration: 2000 }}>
<VictoryAxis
tickValues={[1, 2, 3, 4, 5, 6, 7, 8]}
tickFormat={[
"Slot 1",
"Slot 2",
"Slot 3",
"Slot 4",
"Slot 5",
"Slot 6",
"Slot 7",
"Slot 8"
]}
/>
<VictoryAxis
dependentAxis
tickCount={max < 3 ? 2 : 5}
tickFormat={x => x}
/>
<VictoryBar
data={courseStats}
labels={({ datum }) => {
if (datum.y > 0) return Math.round(datum.y);
else return null;
}}
style={{ labels: { fill: "black" } }}
labelComponent={<VictoryLabel />}
/>
</VictoryChart>
</div>
]);
} else if (resp === false || courseStats.length === 0) {
str.push([
<div>
<h3>No data available for this course!</h3>
</div>
]);
}
} else {
str.push([<h2>LOADING....</h2>]);
}
return <>{str}</>;
}
Example #11
Source File: Search.js From medical-image-search with MIT No Attribution | 4 votes |
render() {
const { items, loading, negICD10s, posICD10s, searchQuery } = this.state
return (
<div className="App">
{
!!loading && (
<p>Searching...</p>
)
}
{
!loading && !items.length && (
<p>Sorry, no results.</p>
)
}
<Grid container devided='vertically'>
{
!loading && (
<Grid.Row columns={2} padded>
<Grid.Column>
<VictoryChart theme={VictoryTheme.material}>
<VictoryBar
horizontal
style={{ data: { fill: "Green" }, labels: { fontSize: 12 }}}
// labelComponent={<VictoryLabel textAnchor="end" dx={0} dy={10} />}
data={posICD10s}/>
<VictoryAxis tickFormat={() => ''} />
<VictoryLabel x={100} y={30} text="Positive ICD10 CMs" />
</VictoryChart>
</Grid.Column>
<Grid.Column>
<VictoryChart theme={VictoryTheme.material}>
<VictoryBar
horizontal
style={{ data: { fill: "Red" }, labels: { fontSize: 12 } }}
labelComponent={<VictoryLabel textAnchor="start" dx={0} />}
data={negICD10s}/>
<VictoryAxis tickFormat={() => ''} />
<VictoryLabel x={100} y={30} text="Negative ICD10 CMs" />
</VictoryChart>
</Grid.Column>
</Grid.Row>
)
}
<Grid.Row columns={1} padded>
<Grid.Column><Header size='large'>Search Terms</Header></Grid.Column>
</Grid.Row>
<Grid.Row columns={1} padded>
<Grid.Column><Input
fluid
size='big'
icon='search'
onChange={this.onChange.bind(this)}
placeholder='Search for Findings in Radiology Report'
/></Grid.Column>
</Grid.Row>
{
!loading && items.map((item, index) => (
<Grid.Row columns={2}>
<Grid.Column>
<Header>Impression: {item.Impression}</Header>
<List horizontal>
{
item.Images.map(
(image,i) =>
<List.Item key={i}>
<Link to={`/Image/${image.ImageId}`}>
<S3Image key={i} imgKey={image.Key} level='public' theme={{ photoImg: { height: '200px', width: '200px' } }}/>
</Link>
</List.Item>
)
}
</List>
</Grid.Column>
<Grid.Column>
<Segment.Group horizontal>
<Segment padded color='yellow'>
<Header>Signs</Header>
{item.PositiveSigns.map(
(posSigns, i) =>
<List.Item key={i}>
<p style={{ color: 'green' }}>{posSigns}</p>
</List.Item>
)}
{item.NegativeSigns.map(
(negSigns, i) =>
<List.Item key={i}>
<p style={{ color: 'red' }}>{negSigns}</p>
</List.Item>
)}
</Segment>
<Segment padded color='yellow'>
<Header>Diagnoses</Header>
{item.PositiveDiagnoses.map(
(positiveDiag, i) =>
<List.Item key={i}>
<p style={{ color: 'green' }}>{positiveDiag}</p>
</List.Item>
)}
{item.NegativeDiagnoses.map(
(negativeDiag, i) =>
<List.Item key={i}>
<p style={{ color: 'red' }}>{negativeDiag}</p>
</List.Item>
)}
</Segment>
<Segment padded color='yellow'>
<Header>Symptoms</Header>
{item.PositiveSymptoms.map(
(positiveSymp, i) =>
<List.Item key={i}>
<p style={{ color: 'green' }}>{positiveSymp}</p>
</List.Item>
)}
{item.NegativeSymptoms.map(
(negativeSymp, i) =>
<List.Item key={i}>
<p style={{ color: 'red' }}>{negativeSymp}</p>
</List.Item>
)}
</Segment>
</Segment.Group>
</Grid.Column>
</Grid.Row>
))
}
</Grid>
</div>
);
}
Example #12
Source File: Charts.js From ReactSourceCodeAnalyze with MIT License | 4 votes |
render() {
const streamData = this.props.data;
return (
<div>
<div style={{display: 'flex'}}>
<VictoryChart
theme={VictoryTheme.material}
width={400}
height={400}
style={{
parent: {
backgroundColor: '#222',
},
}}>
<VictoryAxis
style={{
axis: {stroke: 'white'},
tickLabels: {fill: 'white'},
}}
/>
<VictoryAxis
style={{
axis: {stroke: 'white'},
tickLabels: {fill: 'white'},
}}
dependentAxis
/>
<VictoryScatter
data={streamData[0]}
size={6}
style={{
data: {
fill: d => colors[d.x % 5],
},
}}
/>
</VictoryChart>
<VictoryChart
theme={VictoryTheme.material}
width={400}
height={400}
style={{
parent: {
backgroundColor: '#222',
},
}}
domainPadding={[20, 20]}>
<VictoryAxis
style={{
axis: {stroke: 'white'},
tickLabels: {fill: 'white'},
}}
/>
<VictoryAxis
style={{
axis: {stroke: 'white'},
tickLabels: {fill: 'white'},
}}
dependentAxis
/>
<VictoryBar
data={streamData[0]}
style={{
data: {
fill: d => colors[d.x % 5],
stroke: 'none',
padding: 5,
},
}}
/>
</VictoryChart>
</div>
<div
style={{
display: 'flex',
position: 'relative',
top: '-50px',
}}>
<VictoryChart
theme={VictoryTheme.material}
width={800}
height={350}
style={{
parent: {
backgroundColor: '#222',
},
}}>
<VictoryAxis
style={{
axis: {stroke: 'white'},
tickLabels: {fill: 'white'},
}}
/>
<VictoryAxis
style={{
axis: {stroke: 'white'},
tickLabels: {fill: 'white'},
}}
dependentAxis
/>
<VictoryStack>
{streamData.map((data, i) => (
<VictoryArea key={i} data={data} colorScale={colors} />
))}
</VictoryStack>
</VictoryChart>
</div>
</div>
);
}
Example #13
Source File: historyView.jsx From OpticQL with MIT License | 4 votes |
History = () => {
const { store } = useContext(Context);
// Declaring an empty array to store either the line chart, bar chart, or string (for no historical data)
let chartContainer = [];
// Container for line chart --> Used when there is more than ONE path
const containerLine = [
<VictoryChart
domainPadding={{ x: 10 }}
containerComponent={
<VictoryVoronoiContainer
voronoiDimension="x"
labels={({ datum }) =>
`Query: ${datum.t} ms,
Query String: ${datum.z}`
}
labelComponent={
<VictoryTooltip
cornerRadius={5}
flyoutStyle={{ fill: "#D4F1F4" }}
style={{ fontSize: 6 }}
constrainToVisibleArea
flyoutPadding={5}
/>
}
/>
}
>
<VictoryLine
style={{
data: { stroke: "#189AB4" },
}}
// Performance data inserted here
data={store.history}
/>
<VictoryAxis
label={"Query Database ID"}
style={{
tickLabels: { fontSize: 10, padding: 5, angle: -30, fill: "white" },
axis: { stroke: "white" },
axisLabel: { fontSize: 10, padding: 30, fill: "white" },
}}
/>
<VictoryAxis
label={"Response Duration (ms)"}
style={{
tickLabels: { fontSize: 10, padding: 5, fill: "white" },
axis: { stroke: "white" },
axisLabel: { fontSize: 10, padding: 30, fill: "white" },
}}
dependentAxis
/>
</VictoryChart>,
];
// Container for bar chart --> Used when there is ONLY ONE path
const containerBar = [
<VictoryChart
domainPadding={{ x: 5 }}
>
<VictoryBar
style={{
data: { fill: "#189AB4" },
}}
// Performance data object inserted here
data={store.history}
labels={({ datum }) =>
`Query: ${datum.t} ms,
Query String: ${datum.z}`
}
barWidth={({ index }) => index * 5 + 20}
labelComponent={
<VictoryTooltip
cornerRadius={5}
flyoutStyle={{ fill: "#D4F1F4" }}
style={{ fontSize: 6 }}
constrainToVisibleArea
flyoutPadding={5}
/>
}
/>
<VictoryAxis
label={"Query Database ID"}
style={{
tickLabels: { fontSize: 10, padding: 5, fill: "white" },
axis: { stroke: "white" },
axisLabel: { fontSize: 10, fill: "white" },
}}
/>
<VictoryAxis
label={"Response Duration (ms)"}
style={{
tickLabels: { fontSize: 10, padding: 5, fill: "white" },
axis: { stroke: "white" },
axisLabel: { fontSize: 10, fill: "white" },
}}
dependentAxis
/>
</VictoryChart>,
];
// Conditional statement to assign chartContainer to charting (line or bar) if there is data, or else, a string indicating no data to render
if (store.history.length === 0) {
chartContainer = '(No historical query information to display)';
} else if (store.history.length === 1) {
chartContainer.push(containerBar);
} else {
chartContainer.push(containerLine);
}
const headerStr = 'Historical GraphQL Performance (Overall response duration in ms)'
const linkStyle = {
"color": "#05445E",
"textDecoration": "none",
}
return (
// <div>
<div className="historyViewContainer">
<img src="./logo2.png" />
<button className="quadrantButton">
<Link to="/" style={linkStyle}>Home</Link>
</button>
<h3 style={{ "color": "#ffffff" }}>{headerStr}</h3>
<div style={{ "width": "80%", "color": "#ffffff", "textAlign": "center", "marginTop": "50px" }}>
{chartContainer}
</div>
</div>
// </div>
);
}
Example #14
Source File: performanceData.jsx From OpticQL with MIT License | 4 votes |
PerfData = () => {
const { store } = useContext(Context);
// Local state to show or hide the pop-up window
const [showWindowPortal, setWindowPortal] = useState(false);
// Change state of showWindowPortal whenever Expand Performance Metrics button is clicked
function toggleWindowPortal () {
setWindowPortal(!showWindowPortal)
}
// To format the response metrics with commas if 4 digits or more
function numberWithCommas (x) {
return x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
}
// Declaring variables to re-assign if store.query.extensions is not falsy
const data = [];
// Variable for rendering of the Summary Performance Metrics text in the upper right hand corner of lower left quadrant
const htmlContainer = [];
// Variable for rending of the main charting (bar or line Victory charts)
const chartContainer = [];
let overallResTime;
let startTime;
let endTime;
const performanceObj = {};
const perfAvg = {};
const anomaliesObj = {};
// If the request is valid (with an associated response), and it is not a mutation request
if (store.query.extensions && !store.mutationEvent) {
const topLevelQueryArr = [];
// Saving top-level request information --> formatting overall response time (in ms) to include commas before the decimal
overallResTime = numberWithCommas(
(store.query.extensions.tracing.duration / 1000000).toFixed(2)
);
// Saving the rest of the top-level (overall) request information
startTime = store.query.extensions.tracing.startTime;
endTime = store.query.extensions.tracing.endTime;
// Saving resolver-level information to a variable
const performanceDataArray = store.query.extensions.tracing.execution.resolvers;
// Resolver-level query information
for (let i = 0; i < performanceDataArray.length; i++) {
const currResolver = performanceDataArray[i];
// This captures 'parent' resolvers and associated duration
if (currResolver.path.length === 1) {
const pathStr = currResolver.path[0];
const pathDuration = currResolver.duration;
topLevelQueryArr.push([pathStr, pathDuration]);
} else {
// 'Children' resolvers and duration get stored in performanceObj
const pathStrJoined = currResolver.path.join(".");
const pathKey = currResolver.path.filter(function (curEl) {
return typeof curEl === "string";
});
const pathKeyJoined = pathKey.join(".");
if (performanceObj[pathKeyJoined]) {
performanceObj[pathKeyJoined].push([pathStrJoined, currResolver.duration]);
} else {
performanceObj[pathKeyJoined] = [[pathStrJoined, currResolver.duration]];
}
}
}
// Finding the average of all the 'children' resolvers duration time for each identified path
for (let perfQuery in performanceObj) {
let perfArr = performanceObj[perfQuery];
let average = 0;
for (let i = 0; i < perfArr.length; i++) {
average += perfArr[i][1];
}
const finalAvg = average / perfArr.length / 1000000;
perfAvg[perfQuery] = Number(finalAvg.toFixed(4));
}
// Isolating the 'children' resolvers where the duration time exceeds the average duration time for that identified path
for (const [pathName, avg] of Object.entries(perfAvg)) {
const anomaliesArr = [];
const arrayOfTimes = performanceObj[pathName];
arrayOfTimes.forEach((el) => {
const resTime = el[1] / 1000000;
if (resTime > avg) {
anomaliesArr.push(`${el[0]}: ${resTime} ms`);
}
});
anomaliesObj[pathName] = anomaliesArr;
}
// Declaring the performance data to be rendered in Victory chart
for (let queryKey in perfAvg) {
let queryKeyObj = {};
queryKeyObj.x = queryKey;
queryKeyObj.y = perfAvg[queryKey];
queryKeyObj.z = anomaliesObj[queryKey].length;
queryKeyObj.q = performanceObj[queryKey].length;
queryKeyObj.t = numberWithCommas(perfAvg[queryKey].toFixed(4));
data.push(queryKeyObj);
}
// Console logs for error-checking
// console.log("performanceObj ", performanceObj);
// console.log("topLevelQueryArr ", topLevelQueryArr);
// console.log("perfAvg:", perfAvg);
// console.log("anomaliesObj:", anomaliesObj);
// console.log("data: ", data);
// Container for line chart --> Used when there is MORE THAN ONE path
const containerLine = [
<VictoryChart
height={350}
padding={60}
domainPadding={{ x: 10 }}
containerComponent={
<VictoryVoronoiContainer
voronoiDimension="x"
labels={({ datum }) =>
`Avg. response time: ${datum.t} ms,
# total resolvers: ${datum.q},
# outlier resolvers: ${datum.z}`
}
labelComponent={
<VictoryTooltip
cornerRadius={5}
flyoutStyle={{ fill: "#D4F1F4" }}
style={{ fontSize: 9 }}
/>
}
/>
}
>
<VictoryLine
style={{
data: { stroke: "#189AB4" },
}}
// Performance data is inputted here
data={data}
/>
<VictoryAxis
label={"Path"}
style={{
tickLabels: { fontSize: 10, padding: 15, angle: -30, fill: "white" },
axis: { stroke: "white" },
axisLabel: { fontSize: 12, fill: "white", padding: 45 },
}}
/>
<VictoryAxis
label={"Duration Time (ms)"}
style={{
tickLabels: { fontSize: 10, padding: 5, fill: "white" },
axis: { stroke: "white" },
axisLabel: { fontSize: 12, fill: "white", padding: 40 },
}}
dependentAxis
/>
</VictoryChart>,
];
// Container for bar chart --> Used when there is ONLY ONE path
const containerBar = [
<VictoryChart
height={350}
padding={60}
domainPadding={{ x: 5 }}
>
<VictoryBar
style={{
data: { fill: "#189AB4" },
}}
// Performance data is inputted here
data={data}
labels={({ datum }) =>
`Avg. response time: ${datum.t} ms,
# total resolvers: ${datum.q},
# outlier resolvers: ${datum.z}`
}
barWidth={({ index }) => index * 5 + 20}
labelComponent={
<VictoryTooltip
dy={0}
style={{ fontSize: 8 }}
constrainToVisibleArea
/>
}
/>
<VictoryAxis
label={"Path"}
style={{
tickLabels: { fontSize: 10, padding: 5, fill: "white" },
axis: { stroke: "white" },
axisLabel: { fontSize: 12, fill: "white" },
}}
/>
<VictoryAxis
label={"Duration Time (ms)"}
style={{
tickLabels: { fontSize: 10, padding: 5, fill: "white" },
axis: { stroke: "white" },
axisLabel: { fontSize: 12, fill: "white", padding: 40 },
}}
dependentAxis
/>
</VictoryChart>,
];
// Adding <p> tags with top-level query information to HTMLcontainer array
htmlContainer.push(
<p key={"overallPerfMetric: 0"} className="perfMetricPTag" className="perfMetricPTagTitle">Summary Metrics:</p>
);
htmlContainer.push(
<p key={"overallPerfMetric: 3"} className="perfMetricPTag">
▫ Overall response time: {overallResTime} ms
</p>
);
for (let i = 0; i < topLevelQueryArr.length; i++) {
let overallParentResTime = numberWithCommas(
(topLevelQueryArr[i][1] / 1000000).toFixed(2)
);
htmlContainer.push(
<p
key={`Time Elapsed to parent resolver-${i}`}
className="perfMetricPTag"
>{` ▫ Response time to ${topLevelQueryArr[i][0]} field: ${overallParentResTime} ms`}</p>
);
}
// Conditional statement to assign chartContainer to either the line or bar chart
if (data.length === 1) {
chartContainer.push(containerBar);
} else {
chartContainer.push(containerLine);
}
}
// If the request is valid (with an associated response), and it is a MUTATION request
if (store.query.extensions && store.mutationEvent) {
// Saving the overall duration time for the MUTATION request
const overallDurationTime = numberWithCommas(((store.query.extensions.tracing.duration) / 1000000).toFixed(4));
// Saving the resolvers array to a variable
const resolverArr = store.query.extensions.tracing.execution.resolvers;
// For loop to create a data object to be rendered inside Victory charts
for (let i = 0; i < resolverArr.length; i++) {
// If conditional to isolate where the resolver path is only one field (which indicates a mutation request vs. the callback fields requested)
if (resolverArr[i].path.length === 1) {
const resolverDuration = (resolverArr[i].duration) / 1000000;
const resolverName = resolverArr[i].path[0];
const mutationObj = {};
mutationObj.x = resolverName;
mutationObj.y = resolverDuration;
mutationObj.z = numberWithCommas(resolverDuration.toFixed(4));
data.push(mutationObj);
}
}
// Adding <p> tags with top-level query information to HTMLcontainer array
htmlContainer.push(
<p key={"overallPerfMetric: 0"} className="perfMetricPTag" className="perfMetricPTagTitle">Summary Performance Metrics:</p>
);
htmlContainer.push(
<p key={"overallPerfMetric: 3"} className="perfMetricPTag">
▫ Overall response time: {overallDurationTime} ms
</p>
);
// Container for line chart --> Used when there is MORE THAN ONE path
const containerLine = [
<VictoryChart
height={350}
padding={60}
domainPadding={{ x: 10 }}
containerComponent={
<VictoryVoronoiContainer
voronoiDimension="x"
labels={({ datum }) =>
`Response time: ${datum.z} ms`
}
labelComponent={
<VictoryTooltip
cornerRadius={5}
flyoutStyle={{ fill: "#D4F1F4" }}
style={{ fontSize: 9 }}
/>
}
/>
}
>
<VictoryLine
style={{
data: { stroke: "#189AB4" },
}}
// Performance data is inserted here
data={data}
/>
<VictoryAxis
label={"Path"}
style={{
tickLabels: { fontSize: 10, padding: 15, angle: -30, fill: "white" },
axis: { stroke: "white" },
axisLabel: { fontSize: 12, fill: "white", padding: 45 },
}}
/>
<VictoryAxis
label={"Duration Time (ms)"}
style={{
tickLabels: { fontSize: 10, padding: 5, fill: "white" },
axis: { stroke: "white" },
axisLabel: { fontSize: 12, fill: "white", padding: 40 },
}}
dependentAxis
/>
</VictoryChart>,
];
// Container for bar chart --> Used when there is ONLY ONE path
const containerBar = [
<VictoryChart
height={350}
padding={60}
domainPadding={{ x: 5 }}
>
<VictoryBar
style={{
data: { fill: "#189AB4" },
}}
// Performance data is inserted here
data={data}
labels={({ datum }) =>
`Response time: ${datum.z} ms`
}
barWidth={({ index }) => index * 5 + 20}
labelComponent={
<VictoryTooltip
dy={0}
style={{ fontSize: 8 }}
constrainToVisibleArea
/>
}
/>
<VictoryAxis
label={"Path"}
style={{
tickLabels: { fontSize: 10, padding: 5, fill: "white" },
axis: { stroke: "white" },
axisLabel: { fontSize: 12, fill: "white" },
}}
/>
<VictoryAxis
label={"Duration Time (ms)"}
style={{
tickLabels: { fontSize: 10, padding: 5, fill: "white" },
axis: { stroke: "white" },
axisLabel: { fontSize: 12, fill: "white", padding: 40 },
}}
dependentAxis
/>
</VictoryChart>,
];
// Conditional statement to assign chartContainer to either the line or bar chart
if (data.length === 1) {
chartContainer.push(containerBar);
} else {
chartContainer.push(containerLine);
}
}
const linkStyle = {
"color": "#05445E",
"textDecoration": "none",
}
return (
<div>
{store.loading && <div className="loadingBox"><img className='loadingImg' src="./assets/loading.gif" /></div>}
{(!store.query.data && !store.loading) && <div id='queryPlaceholder'>No query results to display</div>}
{(store.query.data && !store.loading) &&
<div>
<div className="performanceMetricsButtonInfo">
<button onClick={toggleWindowPortal} className="performanceMetricsButton">
Expand Performance Metrics
</button>
<button className="performanceMetricsButton">
<Link to="/fullhistory" style={linkStyle}>View Historical Metrics</Link>
</button>
<ExpandPerfData key={'ExpandPerfData 1'} showWindow={showWindowPortal} performanceAvg={perfAvg} anomaliesObject={anomaliesObj} performance={performanceObj} />
<div>{htmlContainer}</div>
</div>
<div className="chartContainerDiv">{chartContainer}</div>
</div>
}
</div>
)
}
Example #15
Source File: [auctionId].js From pure.finance with MIT License | 4 votes |
DPAuctionPriceChart = function ({ auction }) {
const { t } = useTranslation('common')
const startPoint = {
block: auction.startBlock,
price: auction.ceiling
}
const endPoint = {
block: auction.endBlock,
price: auction.floor
}
const currentPoint = {
block: auction.currentBlock,
price: auction.currentPrice
}
const winningPoint = {
block: auction.winningBlock,
price: auction.winningPrice
}
const stoppingPoint = {
block: auction.stoppingBlock,
price: auction.stoppingPrice
}
const basePlotData =
auction.status === 'running'
? [startPoint, currentPoint, endPoint]
: auction.status === 'stopped'
? [startPoint, stoppingPoint, endPoint]
: auction.status === 'won'
? [startPoint, winningPoint, endPoint]
: [startPoint, currentPoint, endPoint]
const plotData = basePlotData
.map(({ block, price }) => ({
block: Number.parseInt(block),
price: numberFromUnit(price, auction.paymentToken.decimals)
}))
.sort((a, b) => a.block - b.block)
// Calculating the x-axis ticks manually prevents x-labels to overlap, to
// repeat or to show decimal block numbers. And since the auctions can be live
// for many blocks or just a few, black math magic is required.
//
// First, start by defining the start, end blocks and the domain length.
const xStart = plotData[0].block
const xEnd = plotData[2].block
const xLen = xEnd - xStart
// Then split the domain length in 3 to have at most 4 ticks. Since the chart
// is relatively small and the block numbers are large, having just a few
// ticks is ok.
// Finally force the steps to be a whole number and force it to be at least 1.
const xStep = Math.max(Math.floor(xLen / 3), 1)
// Once the steps are defined, calculate how many ticks fit in the domain. Sum
// one to add the "ending" tick. Otherwise only the start and "inner" ticks
// will be shown.
const xTicks = Math.floor(xLen / xStep) + 1
// Finally create an array of that length whose values will be one step
// appart. To get a better look, start from the end, subtract one step at a
// time and then revert the array. That way the end tick will always match the
// end block.
const xTickValues = new Array(Math.max(xTicks, 1))
.fill(null)
.map((_, i) => xEnd - xStep * i)
.reverse()
return (
<div>
<VictoryChart
minDomain={{ y: 0 }}
padding={{ bottom: 55, left: 90, right: 30, top: 10 }}
width={450}
>
<VictoryAxis
label={t('block-number')}
style={{
axisLabel: { padding: 40 },
ticks: { stroke: 'black', size: 5 }
}}
tickFormat={tick => tick.toString()}
tickValues={xTickValues}
/>
<VictoryAxis
dependentAxis
label={auction.paymentToken.symbol}
style={{
axisLabel: { padding: 75 },
ticks: { stroke: 'black', size: 5 }
}}
/>
<VictoryLine
data={plotData.slice(0, 2)}
style={{
data: { strokeWidth: 2 }
}}
x="block"
y="price"
/>
<VictoryLine
data={plotData.slice(1)}
style={{
data:
auction.status === 'floored' ||
auction.winningPrice === auction.floor ||
auction.stoppingPrice === auction.floor
? { strokeWidth: 3 }
: { strokeWidth: 1, strokeDasharray: '10,10' }
}}
x="block"
y="price"
/>
<VictoryScatter
data={[
plotData[
auction.status === 'floored' ||
auction.winningPrice === auction.floor ||
auction.stoppingPrice === auction.floor
? 2
: 1
]
]}
size={8}
style={{
data: {
strokeWidth: 1,
fill: auction.stopped ? 'black' : 'white',
stroke: 'black'
}
}}
x="block"
y="price"
/>
</VictoryChart>
</div>
)
}