recharts#ComposedChart JavaScript Examples

The following examples show how to use recharts#ComposedChart. 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: SimpleComposedChart.js    From paper-and-ink with MIT License 6 votes vote down vote up
function SimpleComposedChart() {
  const theme = useTheme();
  return (
    <ResponsiveContainer width="100%" minWidth={500} height={350}>
      <ComposedChart margin={{ top: 0, right: -15, left: -15, bottom: 0 }} data={sales}>
        <YAxis ticks={[0, 2500, 5000, 9800]} tick={{ fontSize: 12 }} tickLine={false} />
        <XAxis dataKey="month" tick={{ fontSize: 12 }} tickLine={false} />
        <Area
          type="natural"
          dataKey="area"
          fill={theme.palette.primary.light}
          strokeWidth={0}
          activeDot={false}
        />
        <Line type="monotone" dataKey="sales" stroke={theme.palette.primary.dark} strokeWidth={2} />
        <Line
          type="monotone"
          dataKey="orders"
          stroke={theme.palette.success.light}
          strokeWidth={2}
          dot={{
            stroke: theme.palette.success.dark,
            strokeWidth: 2,
            fill: theme.palette.success.main
          }}
        />
      </ComposedChart>
    </ResponsiveContainer>
  );
}
Example #2
Source File: ComposedCharts.js    From gedge-platform with Apache License 2.0 6 votes vote down vote up
ComposedCharts = observer(() => {
  return (
    <div>
      <ComposedChart width={730} height={250} data={data}>
        <XAxis dataKey="name" />
        <YAxis />
        <Tooltip />
        <Legend />
        <CartesianGrid stroke="#f5f5f5" />
        <Area type="monotone" dataKey="amt" fill="#8884d8" stroke="#8884d8" />
        <Bar dataKey="pv" barSize={20} fill="#413ea0" />
        <Line type="monotone" dataKey="uv" stroke="#ff7300" />
      </ComposedChart>
    </div>
  );
})
Example #3
Source File: FeesChart.js    From acy-dex-interface with MIT License 5 votes vote down vote up
export default function FeesChart(props) {
  const {
    data,
    loading,
    chartHeight,
    yaxisWidth,
    xaxisTickFormatter,
    yaxisTickFormatter,
    tooltipFormatter,
    tooltipLabelFormatter
  } = props

  const csvFields = [
    // {key: 'swap', name: 'Swap'},
    {key: 'margin', name: 'Margin trading'},
    {key: 'mint', name: 'Mint ALP'},
    {key: 'burn', name: 'Burn ALP'},
    {key: 'liquidation', name: 'Liquidation'},
    {key: 'cumulative', name: 'Cumulative'}
  ]

  return <ChartWrapper title="Fees" loading={loading} csvFields={csvFields} data={data}>
    <ResponsiveContainer width="100%" height={chartHeight}>
      <ComposedChart data={data} syncId="syncA">
        <CartesianGrid strokeDasharray="3 3" stroke='#333333' />
        <XAxis dataKey="timestamp" tickFormatter={xaxisTickFormatter} minTickGap={30} />
        <YAxis dataKey="all" interval="preserveStartEnd" tickCount={7} tickFormatter={yaxisTickFormatter} width={yaxisWidth} />
        <YAxis dataKey="cumulative" orientation="right" yAxisId="right" tickFormatter={yaxisTickFormatter} width={yaxisWidth} />
        <Tooltip
          formatter={tooltipFormatter}
          labelFormatter={tooltipLabelFormatter}
          contentStyle={{ textAlign: 'left' }}
        />
        <Legend />
        {/* <Bar isAnimationActive={false} type="monotone" dataKey="swap" stackId="a" name="Swap" fill={COLORS[0]} /> */}
        <Bar isAnimationActive={false} type="monotone" dataKey="mint" stackId="a" name="Mint ALP" fill={COLORS[1]} />
        <Bar isAnimationActive={false} type="monotone" dataKey="burn" stackId="a" name="Burn ALP" fill={COLORS[2]} />
        <Bar isAnimationActive={false} type="monotone" dataKey="liquidation" stackId="a" name="Liquidation" fill={COLORS[3]} />
        <Bar isAnimationActive={false} type="monotone" dataKey="margin" stackId="a" name="Margin trading" fill={COLORS[4]} />
        <Line isAnimationActive={false} type="monotone" strokeWidth={3} dot={false} stroke={COLORS[0]} dataKey="cumulative" yAxisId="right" name="Cumulative" />
      </ComposedChart>
    </ResponsiveContainer>
    <div className="chart-description">
      Collected fees. USD value is calculated with token price at the moment of swap, trade, minting or redeeming ALP
    </div>
  </ChartWrapper>
}
Example #4
Source File: GraphDeathProjection.js    From covid-19 with MIT License 5 votes vote down vote up
GraphDeathProjectionRender = (props) => {
  let data = props.data;
  const max_date = props.max_date;
  const data_keys = props.data_keys;

  data = data.map(d => {
    d.name = moment(d.fulldate, "MM/DD/YYYY").format("M/D");
    return d;
  });
  data = data.sort((a, b) => moment(a.fulldate, "MM/DD/YYYY").toDate() - (moment(b.fulldate, "MM/DD/YYYY")).toDate());

  const [state, setState] = React.useState({
    showall: false,
  });

  const handleLogScaleToggle = event => {
    setState({ ...state, showall: !state.showall });
  };
  const cutoff = moment().subtract(30, 'days')
  const future = moment().add(30, 'days')
  data = data.filter(d => {
    let day = moment(d.fulldate, "MM/DD/YYYY");
    return day.isAfter(cutoff) && day.isBefore(future);
  });
  const formatYAxis = (tickItem) => {
    return myShortNumber(tickItem);
  }

  return <>
    <Grid container alignItems="center" spacing={1}>
      <Grid item onClick={handleLogScaleToggle}>
        <Typography>
          Daily
                </Typography>
      </Grid>
      <Grid item>
        <AntSwitch checked={state.showall} onClick={handleLogScaleToggle} />
      </Grid>
      <Grid item onClick={handleLogScaleToggle}>
        <Typography>
          Total
                </Typography>
      </Grid>
      <Grid item></Grid>
    </Grid>
    <ResponsiveContainer height={300} >
      <ComposedChart data={data} margin={{ top: 5, right: 30, left: 5, bottom: 5 }} >
        <XAxis dataKey="name" />
        <YAxis yAxisId={0} tickFormatter={formatYAxis} />
        <ReferenceLine x={moment(max_date, "MM/DD/YYYY").format("M/D")} label={{ value: props.max_label, fill: '#a3a3a3' }} stroke="#e3e3e3" strokeWidth={3} />
        <CartesianGrid stroke="#d5d5d5" strokeDasharray="5 5" />
        <Line type="monotone" dataKey={data_keys.key_mean} stroke="#000000" dot={{ r: 1 }} yAxisId={0} strokeWidth={2} />
        <Area type='monotone' dataKey={data_keys.key_lower} stackId="1" stroke='#8884d8' fill='#FFFFFF' />
        <Area type='monotone' dataKey={data_keys.key_delta} stackId="1" stroke='#82ca9d' fill='#82ca9d' />
        <Line type="monotone" dataKey="actualDeath_daily" stroke="#FF0000" dot={{ r: 1 }} strokeDasharray="2 2" yAxisId={0} strokeWidth={2} />
        <Line type="monotone" dataKey="actualDeath_moving_avg" stroke="#FF0000" dot={{ r: 1 }} yAxisId={0} strokeWidth={3} />
        {state.showall && <Line type="monotone" dataKey={data_keys.key_mean_cumulative} dot={{ r: 1 }} stroke="#000000" yAxisId={0} strokeWidth={1} />}
        {state.showall && <Line type="monotone" dataKey="actualDeath_total" dot={{ r: 1 }} stroke="#ff0000" yAxisId={0} strokeWidth={2} />}
        {state.showall && <Area type='monotone' dataKey={data_keys.key_lower_cumulative} stackId="2" stroke='#8884d8' fill='#FFFFFF' />}
        {state.showall && <Area type='monotone' dataKey={data_keys.key_delta_cumulative} stackId="2" stroke='#82ca9d' fill='#82ca9d' />}
        <Tooltip content={props.tooltip} />
        <Legend verticalAlign="top" payload={[
          { value: 'Actual Death', type: 'line', color: '#ff0000' },
          { value: 'Projection', type: 'line', color: '#000000' },
        ]} />
      </ComposedChart>
    </ResponsiveContainer>
    <Typography variant="body2">
      Source: The Institute for Health Metrics and Evaluation
                </Typography>
  </>
}
Example #5
Source File: Chart.jsx    From breviews with MIT License 5 votes vote down vote up
Chart = ({ mainpageData }) => { 

    let chartData = [];
    mainpageData.map(obj => {
      if(obj.chartData.length !== 0) {
        chartData.push(obj.chartData);
      } 
    })
    // if chartData is empty use initial data from constants
    if (chartData.length === 0) {
      chartData = data
    }
    return (
      <div
        className="chart-wrapper"
        style={{
          backgroundColor: "#f2f2f2",
          width: "90%",
          margin: "0 auto",
          padding: "0.8em",
          borderRadius: "2px",
          color: "#333"
        }}
      >
        <div>
          <h4 style={{ marginBottom: "0.2em" }}>Employment Rate</h4>
          <span style={{ fontStyle: "italic", fontSize: "11px" }}>
            Based on reviews
          </span>
        </div>
        <ResponsiveContainer width={"100%"} height={520}>
          <ComposedChart
            layout="vertical"
            data={chartData}
            margin={{
              top: 20,
              right: 80,
              bottom: 20,
              left: 120
            }}
          >
            <CartesianGrid stroke="#f7b0c8" />
            <XAxis type="number" />
            <YAxis dataKey="name" type="category" />
            <Tooltip />
            <Bar dataKey="rate" barSize={10} fill="#c3352b" />
          </ComposedChart>
        </ResponsiveContainer>
      </div>
    );
  }
Example #6
Source File: ApiCallMetricsView.jsx    From amazon-connect-snippets with MIT No Attribution 5 votes vote down vote up
render() {
        const {
            classes, className: classNameProp, log, indexedLogs,
        } = this.props;

        // 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'));

        return (
            <div className={clsx(classes.root, classNameProp)}>
                <Container
                    title="API Call Metrics"
                    gutters={false}
                >
                    <div className={classes.content}>
                        <ResponsiveContainer width="100%" height={300}>
                            <ComposedChart
                                data={latencies}
                                margin={{
                                    top: 5, right: 20, bottom: 5, left: 20,
                                }}
                            >
                                <YAxis>
                                    <Label angle={270} position="left" style={{ textAnchor: 'middle' }}>
                                        Latency (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 */}
                                <Line type="linear" dataKey="latency" stroke="#8884d8" strokeWidth={2} dot={this.renderDots} activeDot={this.renderActiveDots} connectNulls isAnimationActive={false} />
                                <Tooltip content={this.renderCustomTooltip} />
                            </ComposedChart>
                        </ResponsiveContainer>
                    </div>
                </Container>
            </div>
        );
    }
Example #7
Source File: PlotLinReg.js    From Otto with MIT License 5 votes vote down vote up
export default function PlotLinReg() {
  const { model_state } = useModelState();
  const { linreg_test_result, linreg_test_set } = model_state;
  const { state } = useState();

  const data = [];
  linreg_test_set.map((point, index) => {
    if (linreg_test_result[index][1] >= 0) {
      data.push({
        x: point[0],
        scatter: point[1],
        line: linreg_test_result[index][1],
      });
    }
  });
  data.sort(compareX);

  return (
    <>
      {!model_state.viz_loading ? (
        <ResponsiveContainer
          className="graph-wrapper"
          width="100%"
          height="100%"
        >
          <ComposedChart
            data={data}
            margin={{
              top: 20,
              right: 20,
              bottom: 20,
              left: 20,
            }}
          >
            <CartesianGrid />
            <XAxis dataKey="x" name={model_state.linreg_x_name} type="number">
              <Label
                value={model_state.linreg_x_name}
                position="insideBottom"
                offset={-12}
              />
            </XAxis>
            <YAxis
              unit={state.sample_dataset === SampleDataset.BOSTON ? "k$" : ""}
              name={model_state.linreg_y_name}
              type="number"
            >
              <Label
                value={model_state.linreg_y_name}
                angle={-90}
                position="insideLeft"
              />
            </YAxis>
            <Tooltip cursor={{ strokeDasharray: "3 3" }} />
            <Legend verticalAlign="top" height={36} />
            <Scatter name="Test Data" dataKey="scatter" fill="#e06aa6" />
            <Line
              dataKey="line"
              name="Line of Best Fit (Train Data)"
              stroke="#5D5DE1"
              dot={false}
            />
          </ComposedChart>
        </ResponsiveContainer>
      ) : (
        <LoadingComponent />
      )}
    </>
  );
}
Example #8
Source File: VolumeChart.js    From acy-dex-interface with MIT License 5 votes vote down vote up
export default function VolumeChart(props) {
  const {
    data,
    loading,
    chartHeight,
    yaxisWidth,
    xaxisTickFormatter,
    yaxisTickFormatter,
    tooltipFormatter,
    tooltipLabelFormatter
  } = props

  const csvFields = [
    // {key: 'swap', name: 'Swap'},
    {key: 'margin', name: 'Margin trading'},
    {key: 'mint', name: 'Mint GLP'},
    {key: 'burn', name: 'Burn GLP'},
    {key: 'liquidation', name: 'Liquidation'},
    {key: 'cumulative', name: 'Cumulative'}
  ]

  useEffect( () => {
    console.log("DATA VOLUME CHART:", data);
  },[data])

  return <ChartWrapper title="Volume" loading={loading} csvFields={csvFields} data={data}>
    <ResponsiveContainer width="100%" height={chartHeight}>
      <ComposedChart data={data} syncId="syncA">
        <CartesianGrid strokeDasharray="3 3" stroke='#333333' />
        <XAxis dataKey="timestamp" tickFormatter={xaxisTickFormatter} minTickGap={30} />
        <YAxis dataKey="all" interval="preserveStartEnd" tickCount={7} tickFormatter={yaxisTickFormatter} width={yaxisWidth} />
        <YAxis dataKey="cumulative" orientation="right" yAxisId="right" tickFormatter={yaxisTickFormatter} width={yaxisWidth} />
        <Tooltip
          formatter={tooltipFormatter}
          labelFormatter={tooltipLabelFormatter}
          contentStyle={{ textAlign: 'right' }}
        />
        <Legend />
        {/* <Bar isAnimationActive={false} type="monotone" dataKey="swap" stackId="a" name="Swap" fill={COLORS[0]} /> */}
        <Bar isAnimationActive={false} type="monotone" dataKey="mint" stackId="a" name="Mint GLP" fill={COLORS[1]} />
        <Bar isAnimationActive={false} type="monotone" dataKey="burn" stackId="a" name="Burn GLP" fill={COLORS[2]} />
        <Bar isAnimationActive={false} type="monotone" dataKey="liquidation" stackId="a" name="Liquidation" fill={COLORS[3]} />
        <Bar isAnimationActive={false} type="monotone" dataKey="margin" stackId="a" name="Margin trading" fill={COLORS[4]} />
        <Line isAnimationActive={false} type="monotone" dot={false} strokeWidth={3} stroke={COLORS[0]} dataKey="cumulative" yAxisId="right" name="Cumulative" />
      </ComposedChart>
    </ResponsiveContainer>
  </ChartWrapper>
}
Example #9
Source File: MetricsView.jsx    From amazon-connect-snippets with MIT No Attribution 4 votes vote down vote up
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 #10
Source File: SkewMetricsView.jsx    From amazon-connect-snippets with MIT No Attribution 4 votes vote down vote up
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 #11
Source File: StateIndiaRecoveryProgress.js    From covid-19 with MIT License 4 votes vote down vote up
StateIndiaRecoveryProgress = props => {
    const data = props.data;
    
    let topNData = data.filter((elem) => {
        return elem.confirmed > 100 && elem.state != 'State Unassigned';
    });

    let refinedData = [];
    topNData.forEach(element => {
        let obj = {};
        obj['State'] = element['state'];
        obj['% Recovered'] = element['perctRecoverd'];
        obj['% Deaths'] = element['perctDeaths'];
        obj['active'] = element['active'];
        obj['% Active'] = element['perctActive'];
        obj['confirmed'] = element['confirmed'];
        obj['recovered'] = element['recovered'];
        obj['deaths'] = element['deaths'];
        obj['State Code'] = INDIA_STATE_CODES[element['state']];
        refinedData.push(obj);
    });

    const CustomTooltip = ({ active, payload, label }) => {
        if (active) {
            return (
                <div className="custom-tooltip">
                    <p className="label">
                        <span>{payload[0].payload.State}({`Cases: ${payload[0].payload.confirmed}`})</span>
                    </p>
                    <p className="intro">
                        <span style={{color: '#FFC107'}}>
                            {`Acive Cases: ${payload[0].payload.active}(${payload[0].payload['% Active']}%)`}
                        </span> <br />
                        <span style={{color: '#28A745'}}>
                            {`Recovered Cases: ${payload[0].payload.recovered}(${payload[0].payload['% Recovered']}%)`}
                        </span> <br />
                        <span style={{color: '#DC3545'}}>
                            {`Death Cases: ${payload[0].payload.deaths}(${payload[0].payload['% Deaths']}%)`}
                        </span>
                    </p>
                </div>
            );
        }

        return null;
    };

    const renderCustomizedLabel = (props) => {
        const { x, y, width, height, value } = props;
        const radius = 18;

        return (
            <g>
                <circle cx={x + width / 2} cy={y - radius} r={radius} fill="#FFF" />
                <text x={x + width / 2} y={y - radius} fill="#000" textAnchor="middle" dominantBaseline="middle">
                    {value}%
                </text>
            </g>
        );
    };

    return (
        <Card>
            <Card.Body>
                <Card.Title>State: Recovery Progress(Min. 100 Cases)</Card.Title>
                <Card.Subtitle className="mb-2 text-muted">
                    State with the Active, Recovery and Death percentages
                </Card.Subtitle>
                <ResponsiveContainer width='100%' height={330}>
                    <ComposedChart  data={refinedData}
                        margin={{
                            top: 30, right: 0, left: 0, bottom: 5,
                        }}>
                        <XAxis dataKey="State Code" />
                        <YAxis/>
                        <Tooltip content={<CustomTooltip />} />
                        <Legend/>
                        <CartesianGrid strokeDasharray="3 3" />
                        <Bar dataKey="% Recovered" fill="rgba(40, 167, 69, 1.0)">
                            <LabelList dataKey="% Recovered" position="top" content={renderCustomizedLabel} />
                        </Bar>
                        <Area type='monotone' dataKey='% Active' fill='#FFC107' stroke='#FFC107'/>
                        <Line type='monotone' dataKey='% Deaths' stroke='#DC3545'/>
                    </ComposedChart>
                </ResponsiveContainer>
            </Card.Body>
        </Card>
    );
}
Example #12
Source File: MultiLinePlot.jsx    From covince with MIT License 4 votes vote down vote up
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 #13
Source File: MultiLinePlot.jsx    From covince with MIT License 4 votes vote down vote up
MultiLinePlot = props => {
  const {
    activeLineages,
    area_data,
    chartZoom,
    className,
    darkMode,
    date,
    groupStackedColours = true,
    height = 120,
    parameter,
    preset: deprecatedPreset,
    setDate,
    stroke = 'blueGray',
    tooltipEnabled,
    type,
    width,
    /* xAxis: xAxisConfig = {}, */
    yAxis: yAxisConfig,
    zoomEnabled
  } = props

  const preset = useMemo(() => {
    if (parameter && parameter.format === 'percentage') return 'percentage'

    // back compat
    if (deprecatedPreset) return deprecatedPreset
    if (parameter && parameter.id === 'p') return 'percentage'

    return null
  }, [parameter, deprecatedPreset])

  const precision = useMemo(() => {
    return parameter ? parameter.precision : undefined
  }, [parameter])

  const chart = useMemo(() => {
    const dataByDate = {}
    const lineageSum = {}

    for (const d of area_data) {
      if (d.parameter === parameter.id && d.lineage !== 'total') {
        const next = {
          ...dataByDate[d.date],
          date: d.date,
          [d.lineage]: d.mean,
          [`${d.lineage}_range`]: d.range
        }
        if (d.lineage in activeLineages && activeLineages[d.lineage].active) {
          next.maxY = Math.max(next.maxY || 0, d.range[1] || d.mean)
          next.sumY = (next.sumY || 0) + d.mean
        }
        dataByDate[d.date] = next
        const sum = lineageSum[d.lineage] || 0
        lineageSum[d.lineage] = (sum + d.mean)
      }
    }

    const data =
      orderBy(Object.values(dataByDate), 'date', 'asc')
        .map((d, index) => ({ ...d, index }))

    const dates = data.map(_ => _.date)

    const lineages = []
    for (const lineage of Object.keys(lineageSum)) {
      const { active, colour } = activeLineages[lineage]
      if (active) {
        lineages.push({ lineage, colour, average: lineageSum[lineage] / dates.length })
      }
    }

    const ordered = orderBy(lineages, 'average', 'asc')
    let sorted

    if (groupStackedColours) {
      sorted = []
      while (ordered.length > 0) {
        const [item] = ordered.splice(0, 1)
        if (sorted.includes(item)) continue
        sorted.push(item)
        for (let i = 0; i < ordered.length; i++) {
          const other = ordered[i]
          if (item.colour === other.colour) {
            sorted.push(other)
          }
        }
      }
    } else {
      sorted = ordered
    }

    return {
      lineages: sorted,
      data,
      dates
    }
  }, [area_data, activeLineages, groupStackedColours])

  const { data, dates } = chart

  const chartProps = useMemo(() => ({
    width,
    height,
    margin: { top: 12, left: 0, right: 24 }
  }), [width, height])

  const { dateRange, setChartZoom, clearChartZoom } = chartZoom

  const xAxisDomain = useMemo(() => {
    const minIndex = 0
    const maxIndex = data.length - 1
    if (dateRange && dates.length) {
      const [minDate, maxDate] = dateRange
      const min = minDate ? Math.max(dates.indexOf(minDate), minIndex) : minIndex
      let max = maxDate ? dates.indexOf(maxDate) : maxIndex
      if (max === -1) max = maxIndex
      return min < max ? [min, max] : [max, min]
    }
    return [minIndex, maxIndex]
  }, [dateRange, dates])

  const xAxisProps = useMemo(() => {
    const indices = Object.keys(dates)
    let ticks = indices
    if (dateRange) {
      const [minIndex, maxIndex] = xAxisDomain
      ticks = indices.slice(minIndex, maxIndex + 1)
    }
    return {
      allowDataOverflow: true,
      dataKey: 'index',
      domain: xAxisDomain,
      ticks,
      type: 'number'
    }
  }, [xAxisDomain, dates])

  const [zoomArea, setZoomArea] = React.useState({})
  const [isHovering, setIsHovering] = React.useState(false)

  const eventHandlers = useMemo(() => {
    const clickHandlers = {
      onClick: item => {
        if (date && item && !zoomArea.dragged) { // do not set date if not visible on chart
          setDate(data[item.activeLabel].date)
        }
        if (zoomEnabled) {
          setZoomArea({ dragged: zoomArea.dragged })
        }
      },
      onMouseDown: e => {
        if (e && zoomEnabled) {
          setZoomArea({ start: e.activeLabel, end: e.activeLabel, dragged: false })
        }
      },
      onMouseMove: e => {
        if (e) {
          setIsHovering(e.activeLabel !== undefined)
          if (zoomArea.start === undefined) return
          let end = e.activeLabel
          if (e.activeLabel === undefined) { // outside of axes
            end = xAxisDomain[zoomArea.end >= data.length / 2 ? 1 : 0]
          }
          setZoomArea({ start: zoomArea.start, end, dragged: true })
        }
      },
      onMouseLeave: e => {
        setIsHovering(false)
      },
      onMouseUp: (_, e) => {
        if (zoomArea.end !== zoomArea.start) {
          const xStart = data[zoomArea.start].date
          const xEnd = data[zoomArea.end].date
          const args = xStart < xEnd ? [xStart, xEnd] : [xEnd, xStart]
          setChartZoom(...args)
        }
        setZoomArea({ dragged: zoomArea.dragged })
      }
    }
    if (!tooltipEnabled) { // touch handlers need to be replaced when tooltip is missing
      return {
        ...clickHandlers,
        onTouchStart: clickHandlers.onMouseDown,
        onTouchMove: clickHandlers.onMouseMove,
        onTouchEnd: clickHandlers.onMouseUp
      }
    }
    return clickHandlers
  }, [zoomEnabled, data, zoomArea, isHovering])

  const cursor = useMemo(() => {
    if (zoomArea.start) return 'ew-resize'
    if (isHovering) return 'crosshair'
    return undefined
  }, [zoomArea, isHovering])

  return (
    <div
      className={classNames('relative select-none focus:outline-none', className)}
      onDoubleClick={clearChartZoom}
    >
      <MainChart
        {...{
          ...chartProps,
          ...eventHandlers,
          activeLineages,
          chart,
          dateRange,
          cursor,
          darkMode,
          precision,
          preset,
          stroke,
          tooltipEnabled,
          type,
          xAxisProps,
          yAxisConfig,
          zoomArea
        }}
      />
      <div className='absolute top-0 left-0 pointer-events-none'>
        <ComposedChart {...chartProps} data={data}>
          <XAxis
            {...xAxisProps}
            tick={false}
            stroke='none'
          />
          <YAxis
            width={48}
            tick={false}
            stroke='none'
          />
          <ReferenceLine
            x={dates.indexOf(date)}
            stroke={tailwindColors[stroke][darkMode ? 300 : 400]}
            label=''
            strokeWidth={2}
            style={{ mixBlendMode: darkMode ? 'screen' : 'multiply' }}
          />
        </ComposedChart>
      </div>
    </div>
  )
}
Example #14
Source File: Dashboard.js    From react-code-splitting-2021-04-26 with MIT License 4 votes vote down vote up
export default function Dashboard(props) {
  var classes = useStyles();
  var theme = useTheme();

  // local
  var [mainChartState, setMainChartState] = useState("monthly");

  return (
    <>
      <PageTitle title="Dashboard" button={<Button
      variant="contained"
      size="medium"
      color="secondary"
    >
        Latest Reports
    </Button>} />
      <Grid container spacing={4}>
        <Grid item lg={3} md={4} sm={6} xs={12}>
          <Widget
            title="Visits Today"
            upperTitle
            bodyClass={classes.fullHeightBody}
            className={classes.card}
          >
            <div className={classes.visitsNumberContainer}>
              <Grid container item alignItems={"center"}>
                <Grid item xs={6}>
              <Typography size="xl" weight="medium" noWrap>
                12, 678
              </Typography>
                </Grid>
                <Grid item xs={6}>
              <LineChart
                width={100}
                height={30}
                data={[
                  { value: 10 },
                  { value: 15 },
                  { value: 10 },
                  { value: 17 },
                  { value: 18 },
                ]}
              >
                <Line
                  type="natural"
                  dataKey="value"
                  stroke={theme.palette.success.main}
                  strokeWidth={2}
                  dot={false}
                />
              </LineChart>
                </Grid>
              </Grid>
            </div>
            <Grid
              container
              direction="row"
              justify="space-between"
              alignItems="center"
            >
              <Grid item xs={4}>
                <Typography color="text" colorBrightness="secondary" noWrap>
                  Registrations
                </Typography>
                <Typography size="md">860</Typography>
              </Grid>
              <Grid item xs={4}>
                <Typography color="text" colorBrightness="secondary" noWrap>
                  Sign Out
                </Typography>
                <Typography size="md">32</Typography>
              </Grid>
              <Grid item xs={4}>
                <Typography color="text" colorBrightness="secondary" noWrap>
                  Rate
                </Typography>
                <Typography size="md">3.25%</Typography>
              </Grid>
            </Grid>
          </Widget>
        </Grid>
        <Grid item lg={3} md={8} sm={6} xs={12}>
          <Widget
            title="App Performance"
            upperTitle
            className={classes.card}
            bodyClass={classes.fullHeightBody}
          >
            <div className={classes.performanceLegendWrapper}>
              <div className={classes.legendElement}>
                <Dot color="warning" />
                <Typography
                  color="text"
                  colorBrightness="secondary"
                  className={classes.legendElementText}
                >
                  Integration
                </Typography>
              </div>
              <div className={classes.legendElement}>
                <Dot color="primary" />
                <Typography
                  color="text"
                  colorBrightness="secondary"
                  className={classes.legendElementText}
                >
                  SDK
                </Typography>
              </div>
            </div>
            <div className={classes.progressSection}>
              <Typography
                size="md"
                color="text"
                colorBrightness="secondary"
                className={classes.progressSectionTitle}
              >
                Integration
              </Typography>
              <LinearProgress
                variant="determinate"
                value={77}
                classes={{ barColorPrimary: classes.progressBarPrimary }}
                className={classes.progress}
              />
            </div>
            <div>
              <Typography
                size="md"
                color="text"
                colorBrightness="secondary"
                className={classes.progressSectionTitle}
              >
                SDK
              </Typography>
              <LinearProgress
                variant="determinate"
                value={73}
                classes={{ barColorPrimary: classes.progressBarWarning }}
                className={classes.progress}
              />
            </div>
          </Widget>
        </Grid>
        <Grid item lg={3} md={8} sm={6} xs={12}>
          <Widget
            title="Server Overview"
            upperTitle
            className={classes.card}
            bodyClass={classes.fullHeightBody}
          >
            <div className={classes.serverOverviewElement}>
              <Typography
                color="text"
                colorBrightness="secondary"
                className={classes.serverOverviewElementText}
                noWrap
              >
                60% / 37°С / 3.3 Ghz
              </Typography>
              <div className={classes.serverOverviewElementChartWrapper}>
                <ResponsiveContainer height={50} width="99%">
                  <AreaChart data={getRandomData(10)}>
                    <Area
                      type="natural"
                      dataKey="value"
                      stroke={theme.palette.secondary.main}
                      fill={theme.palette.secondary.light}
                      strokeWidth={2}
                      fillOpacity="0.25"
                    />
                  </AreaChart>
                </ResponsiveContainer>
              </div>
            </div>
            <div className={classes.serverOverviewElement}>
              <Typography
                color="text"
                colorBrightness="secondary"
                className={classes.serverOverviewElementText}
                noWrap
              >
                54% / 31°С / 3.3 Ghz
              </Typography>
              <div className={classes.serverOverviewElementChartWrapper}>
                <ResponsiveContainer height={50} width="99%">
                  <AreaChart data={getRandomData(10)}>
                    <Area
                      type="natural"
                      dataKey="value"
                      stroke={theme.palette.primary.main}
                      fill={theme.palette.primary.light}
                      strokeWidth={2}
                      fillOpacity="0.25"
                    />
                  </AreaChart>
                </ResponsiveContainer>
              </div>
            </div>
            <div className={classes.serverOverviewElement}>
              <Typography
                color="text"
                colorBrightness="secondary"
                className={classes.serverOverviewElementText}
                noWrap
              >
                57% / 21°С / 3.3 Ghz
              </Typography>
              <div className={classes.serverOverviewElementChartWrapper}>
                <ResponsiveContainer height={50} width="99%">
                  <AreaChart data={getRandomData(10)}>
                    <Area
                      type="natural"
                      dataKey="value"
                      stroke={theme.palette.warning.main}
                      fill={theme.palette.warning.light}
                      strokeWidth={2}
                      fillOpacity="0.25"
                    />
                  </AreaChart>
                </ResponsiveContainer>
              </div>
            </div>
          </Widget>
        </Grid>
        <Grid item lg={3} md={4} sm={6} xs={12}>
          <Widget title="Revenue Breakdown" upperTitle className={classes.card}>
            <Grid container spacing={2}>
              <Grid item xs={6}>
                <ResponsiveContainer width="100%" height={144}>
                  <PieChart>
                    <Pie
                      data={PieChartData}
                      innerRadius={30}
                      outerRadius={40}
                      dataKey="value"
                    >
                      {PieChartData.map((entry, index) => (
                        <Cell
                          key={`cell-${index}`}
                          fill={theme.palette[entry.color].main}
                        />
                      ))}
                    </Pie>
                  </PieChart>
                </ResponsiveContainer>
              </Grid>
              <Grid item xs={6}>
                <div className={classes.pieChartLegendWrapper}>
                  {PieChartData.map(({ name, value, color }, index) => (
                    <div key={color} className={classes.legendItemContainer}>
                      <Dot color={color} />
                      <Typography style={{ whiteSpace: "nowrap", fontSize: 12 }} >
                        &nbsp;{name}&nbsp;
                      </Typography>
                      <Typography color="text" colorBrightness="secondary">
                        &nbsp;{value}
                      </Typography>
                    </div>
                  ))}
                </div>
              </Grid>
            </Grid>
          </Widget>
        </Grid>
        <Grid item xs={12}>
          <Widget
            bodyClass={classes.mainChartBody}
            header={
              <div className={classes.mainChartHeader}>
                <Typography
                  variant="h5"
                  color="text"
                  colorBrightness="secondary"
                >
                  Daily Line Chart
                </Typography>
                <div className={classes.mainChartHeaderLabels}>
                  <div className={classes.mainChartHeaderLabel}>
                    <Dot color="warning" />
                    <Typography className={classes.mainChartLegentElement}>
                      Tablet
                    </Typography>
                  </div>
                  <div className={classes.mainChartHeaderLabel}>
                    <Dot color="primary" />
                    <Typography className={classes.mainChartLegentElement}>
                      Mobile
                    </Typography>
                  </div>
                  <div className={classes.mainChartHeaderLabel}>
                    <Dot color="secondary" />
                    <Typography className={classes.mainChartLegentElement}>
                      Desktop
                    </Typography>
                  </div>
                </div>
                <Select
                  value={mainChartState}
                  onChange={e => setMainChartState(e.target.value)}
                  input={
                    <OutlinedInput
                      labelWidth={0}
                      classes={{
                        notchedOutline: classes.mainChartSelectRoot,
                        input: classes.mainChartSelect,
                      }}
                    />
                  }
                  autoWidth
                >
                  <MenuItem value="daily">Daily</MenuItem>
                  <MenuItem value="weekly">Weekly</MenuItem>
                  <MenuItem value="monthly">Monthly</MenuItem>
                </Select>
              </div>
            }
          >
            <ResponsiveContainer width="100%" minWidth={500} height={350}>
              <ComposedChart
                margin={{ top: 0, right: -15, left: -15, bottom: 0 }}
                data={mainChartData}
              >
                <YAxis
                  ticks={[0, 2500, 5000, 7500]}
                  tick={{ fill: theme.palette.text.hint + "80", fontSize: 14 }}
                  stroke={theme.palette.text.hint + "80"}
                  tickLine={false}
                />
                <XAxis
                  tickFormatter={i => i + 1}
                  tick={{ fill: theme.palette.text.hint + "80", fontSize: 14 }}
                  stroke={theme.palette.text.hint + "80"}
                  tickLine={false}
                />
                <Area
                  type="natural"
                  dataKey="desktop"
                  fill={theme.palette.background.light}
                  strokeWidth={0}
                  activeDot={false}
                />
                <Line
                  type="natural"
                  dataKey="mobile"
                  stroke={theme.palette.primary.main}
                  strokeWidth={2}
                  dot={false}
                  activeDot={false}
                />
                <Line
                  type="linear"
                  dataKey="tablet"
                  stroke={theme.palette.warning.main}
                  strokeWidth={2}
                  dot={{
                    stroke: theme.palette.warning.dark,
                    strokeWidth: 2,
                    fill: theme.palette.warning.main,
                  }}
                />
              </ComposedChart>
            </ResponsiveContainer>
          </Widget>
        </Grid>
        {mock.bigStat.map(stat => (
          <Grid item md={4} sm={6} xs={12} key={stat.product}>
            <BigStat {...stat} />
          </Grid>
        ))}
        <Grid item xs={12}>
          <Widget
            title="Support Requests"
            upperTitle
            noBodyPadding
            bodyClass={classes.tableWidget}
          >
            <Table data={mock.table} />
          </Widget>
        </Grid>
      </Grid>
    </>
  );
}
Example #15
Source File: GenericChart.js    From acy-dex-interface with MIT License 4 votes vote down vote up
export default function GenericChart(props) {
  const {
    loading,
    title,
    data,
    description,
    height = CHART_HEIGHT,
    yaxisWidth = YAXIS_WIDTH,
    yaxisDataKey = 'all',
    yaxisTickFormatter = yaxisFormatter,
    yaxisDomain,
    xaxisDataKey = 'timestamp',
    xaxisTickFormatter = tooltipLabelFormatter_,
    tooltipFormatter = tooltipFormatter_,
    tooltipLabelFormatter = tooltipLabelFormatter_,
    items,
    type,
    syncId,
    children,
    rightYaxisDataKey,
    isCoinChart
  } = props

  let ChartComponent
  if (type === 'Line') {
    ChartComponent = LineChart
  } else if (type === 'Bar') {
    ChartComponent = BarChart
  } else {
    ChartComponent = ComposedChart
  }

  // Previous update
  // fill: item.color || (isCoinChart ? COINCOLORS[i % COINCOLORS.length] : COLORS[i % COLORS.length]),
  // stroke: item.color || (isCoinChart ? COINCOLORS[i % COINCOLORS.length] : COLORS[i % COLORS.length]),

  const htmlItems = (items || []).map((item, i) => {
    const props = {
      type: "monotone",
      dataKey: item.key,
      stackId: "a",
      name: item.name || item.key,
      fill: item.color || COLORS[i % COLORS.length],
      stroke: item.color || COLORS[i % COLORS.length],
      dot: item.dot || false,
      key: 'item-' + i,
      unit: item.unit,
      strokeWidth: item.strokeWidth,
      yAxisId: item.yAxisId
    }
    if (item.type === 'Line' || type === 'Line') {
      return <Line {...props} isAnimationActive={false} />
    }
    return <Bar {...props} isAnimationActive={false} />
  })

  const csvFields = items.map(item => ({ key: item.key, name: item.name }))

  return <ChartWrapper title={title} loading={loading} data={data} csvFields={csvFields}>
    <ResponsiveContainer width="100%" height={height}>
      {React.createElement(ChartComponent, { data, syncId }, [
        <CartesianGrid strokeDasharray="3 3" stroke='#333333' key="a" />,
        <XAxis dataKey={xaxisDataKey} tickFormatter={xaxisTickFormatter} minTickGap={30} key="b" />,
        <YAxis domain={yaxisDomain} dataKey={yaxisDataKey} tickFormatter={yaxisTickFormatter} key="c" />,
        (
          rightYaxisDataKey ?
            <YAxis dataKey={rightYaxisDataKey} tickFormatter={yaxisTickFormatter} orientation="right" yAxisId="right" key="c2" />
            : null
        ),
        <Tooltip
          formatter={tooltipFormatter}
          labelFormatter={tooltipLabelFormatter}
          contentStyle={{ textAlign: 'left' }}
          key="d"
        />,
        <Legend key="e" />,
        ...htmlItems,
        children
      ])}
    </ResponsiveContainer>
    {description && (
      <div className="chart-description">
        {description}
      </div>
    )}
  </ChartWrapper>
}
Example #16
Source File: Index.js    From acy-dex-interface with MIT License 4 votes vote down vote up
Stats = (props) => {
  const DEFAULT_GROUP_PERIOD = 86400
  const [groupPeriod, setGroupPeriod] = useState(DEFAULT_GROUP_PERIOD)

  const [fromValue, setFromValue] = useState()
  const [toValue, setToValue] = useState()


  const { mode } = props

  const setDateRange = useCallback(range => {
    setFromValue(new Date(Date.now() - range * 1000).toISOString().slice(0, 10))
    setToValue(undefined)
  }, [setFromValue, setToValue])

  const from = fromValue ? +new Date(fromValue) / 1000 : undefined
  const to = toValue ? +new Date(toValue) / 1000 : NOW

  const params = { from, to, groupPeriod }



  const [borrowRateData, borrowRateLoading] = useBorrowRateData(params)
  const [volumeData, volumeLoading] = useVolumeData(params)
  const [totalVolume] = useTotalVolumeFromServer()
  const totalVolumeDelta = useMemo(() => {
    if (!volumeData) {
      return null
    }
    return volumeData[volumeData.length - 1].all
  }, [volumeData])

  const [volumeTest, volumeTestLoading] = useVolumesData(params)
  const [feesData, feesLoading] = useFeesData(params)
  const [totalFees, totalFeesDelta] = useMemo(() => {
    if (!feesData) {
      return []
    }
    const total = feesData[feesData.length - 1]?.cumulative
    const delta = total - feesData[feesData.length - 2]?.cumulative
    return [total, delta]
  }, [feesData])

  const [alpData, alpLoading] = useAlpData(params)
  const [totalAum, totalAumDelta] = useMemo(() => {
    if (!alpData) {
      return []
    }
    const total = alpData[alpData.length - 1]?.aum
    const delta = total - alpData[alpData.length - 2]?.aum
    return [total, delta]
  }, [alpData])

  const [aumPerformanceData, aumPerformanceLoading] = useAumPerformanceData(params)
  const [alpPerformanceData, alpPerformanceLoading] = useAlpPerformanceData(alpData, feesData, params)
  const [alpPriceData, alpPriceDataLoading] = useAlpPriceData(alpData, feesData, params)

  const [tradersData, tradersLoading] = useTradersData(params)
  const [openInterest, openInterestDelta] = useMemo(() => {
    if (!tradersData) {
      return []
    }
    const total = tradersData.data[tradersData.data.length - 1]?.openInterest
    const delta = total - tradersData.data[tradersData.data.length - 2]?.openInterest
    return [total, delta]
  }, [tradersData])
  const [swapSources, swapSourcesLoading] = useSwapSources(params)
  const swapSourcesKeys = Object.keys((swapSources || []).reduce((memo, el) => {
    Object.keys(el).forEach(key => {
      if (key === 'all' || key === 'timestamp') return
      memo[key] = true
    })
    return memo
  }, {}))

  const [usersData, usersLoading] = useUsersData(params)
  const [totalUsers, totalUsersDelta] = useMemo(() => {
    if (!usersData) {
      return [null, null]
    }
    const total = usersData[usersData.length - 1]?.uniqueCountCumulative
    const prevTotal = usersData[usersData.length - 2]?.uniqueCountCumulative
    const delta = total && prevTotal ? total - prevTotal : null
    return [
      total,
      delta
    ]
  }, [usersData])

  const [lastSubgraphBlock] = useLastSubgraphBlock()
  const [lastBlock] = useLastBlock()

  const isObsolete = lastSubgraphBlock && lastBlock && lastBlock.timestamp - lastSubgraphBlock.timestamp > 3600

  const [isExperiment, setIsExperiment] = useState(false)
  useEffect(() => {
    setIsExperiment(window.localStorage.getItem('experiment'))
  }, [setIsExperiment])

  const showForm = false
  const [selectedIndexLine, setselectedIndexLine] = useState(0);
  const [selectedDataLine, setselectedDataLine] = useState(0);
  const [volumeFeeIndex, setVolumeFeeIndex] = useState(0);
  const onLineGraphHover = (newData, newIndex) => {
    if (volumeFeeIndex != newIndex) {
    }
  };

  const history = useHistory()

  return (
    <div className='container'>
      <div className="Home">
        {/* <h1>Analytics / Arbitrum</h1> */}
        {lastSubgraphBlock && lastBlock &&
          <p className={cx('page-description', { warning: isObsolete })} style={{ marginTop: '-1rem' }}>
            {isObsolete && "Data is obsolete. "}
            Updated {moment(lastSubgraphBlock.timestamp * 1000).fromNow()}
            &nbsp;at block <a target="_blank" href={`https://arbiscan.io/block/${lastSubgraphBlock.number}`}>{lastSubgraphBlock.number}</a>
          </p>
        }
        <div className={`${styles.colItem}`}>
          <a
            className={`${styles.colItem} ${styles.optionTab}`}
            onClick={() => {
              history.push('/statistics/market')
            }}
          >
            Market
          </a>
          <a className={`${styles.colItem} ${styles.optionTabSelected}`}>Future</a>
          <a
            className={`${styles.colItem} ${styles.optionTab}`}
            onClick={() => {
              history.push('/statistics/stablecoin')
            }}
          >
            StableCoin
          </a>
        </div>
        {showForm &&
          <div className="form">
            <p>
              <label>Period</label>
              <input type="date" value={fromValue} onChange={evt => setFromValue(evt.target.value)} />
              &nbsp;—&nbsp;
              <input type="date" value={toValue} onChange={evt => setToValue(evt.target.value)} />
              <button onClick={evt => setDateRange(86400 * 29)}>30 days</button>
              <button onClick={evt => setDateRange(86400 * 6)}>7 days</button>
            </p>
          </div>
        }
        <div className="chart-grid">
          <div className="chart-cell stats">
            {totalVolume ? <>
              <div className="total-stat-label">Total Volume</div>
              <div className="total-stat-value">
                {formatNumber(totalVolume, { currency: true })}
                {totalVolumeDelta &&
                  <span className="total-stat-delta plus" title="Change since previous day">+{formatNumber(totalVolumeDelta, { currency: true, compact: true })}</span>
                }
              </div>
            </> : <RiLoader5Fill size="3em" className="loader" />}
          </div>
          <div className="chart-cell stats">
            {totalFees ? <>
              <div className="total-stat-label">Total Fees</div>
              <div className="total-stat-value">
                {formatNumber(totalFees, { currency: true })}
                <span className="total-stat-delta plus" title="Change since previous day">+{formatNumber(totalFeesDelta, { currency: true, compact: true })}</span>
              </div>
            </> : <RiLoader5Fill size="3em" className="loader" />}
          </div>
          <div className="chart-cell stats">
            {totalAum ? <>
              <div className="total-stat-label">ALP Pool</div>
              <div className="total-stat-value">
                {formatNumber(totalAum, { currency: true })}
                <span className={cx("total-stat-delta", (totalAumDelta > 0 ? 'plus' : 'minus'))} title="Change since previous day">{totalAumDelta > 0 ? '+' : ''}{formatNumber(totalAumDelta, { currency: true, compact: true })}</span>
              </div>
            </> : <RiLoader5Fill size="3em" className="loader" />}
          </div>
          <div className="chart-cell stats">
            {totalUsers ? <>
              <div className="total-stat-label">Total Users</div>
              <div className="total-stat-value">
                {formatNumber(totalUsers)}
                <span className="total-stat-delta plus" title="Change since previous day">+{formatNumber(totalUsersDelta)}</span>
              </div>
            </> : <RiLoader5Fill size="3em" className="loader" />}
          </div>
          <div className="chart-cell stats">
            {openInterest ? <>
              <div className="total-stat-label">Open Interest</div>
              <div className="total-stat-value">
                {formatNumber(openInterest, { currency: true })}
                <span className={cx("total-stat-delta", (openInterestDelta > 0 ? 'plus' : 'minus'))} title="Change since previous day">
                  {openInterestDelta > 0 ? '+' : ''}{formatNumber(openInterestDelta, { currency: true, compact: true })}
                </span>
              </div>
            </> : <RiLoader5Fill size="3em" className="loader" />}
          </div>
          <div className="chart-cell">
            <VolumeFeesChart
              data={volumeData}
              loading={volumeLoading}
              title="VOLUME 24H"
              onHover={onLineGraphHover}
            />

            {/* <VolumeChart
              data={volumeData}
              loading={volumeLoading}
              chartHeight={CHART_HEIGHT}
              yaxisWidth={YAXIS_WIDTH}
              xaxisTickFormatter={tooltipLabelFormatter}
              yaxisTickFormatter={yaxisFormatter}
              tooltipLabelFormatter={tooltipLabelFormatter}
              tooltipFormatter={tooltipFormatter}
            /> */}
          </div>
          <div className="chart-cell">
            <VolumeFeesChart
              data={feesData}
              loading={feesLoading}
              title="Fee"
              onHover={onLineGraphHover}
            />
            {/* <FeesChart
              data={feesData?feesData.slice(0,10):feesData}
              loading={feesLoading}
              chartHeight={CHART_HEIGHT}
              yaxisWidth={YAXIS_WIDTH}
              xaxisTickFormatter={tooltipLabelFormatter}
              yaxisTickFormatter={yaxisFormatter}
              tooltipLabelFormatter={tooltipLabelFormatter}
              tooltipFormatter={tooltipFormatter}
            /> */}
          </div>
          <div className="chart-cell">
            <ChartWrapper title="AUM & Alp Supply" loading={alpLoading} data={alpData} csvFields={[{ key: 'aum' }, { key: 'alpSupply' }]}>
              <ResponsiveContainer width="100%" height={CHART_HEIGHT}>
                <LineChart data={alpData} syncId="syncAlp">
                  <CartesianGrid strokeDasharray="3 3" stroke='#333333' />
                  <XAxis dataKey="timestamp" tickFormatter={tooltipLabelFormatter} minTickGap={30} />
                  <YAxis dataKey="aum" tickFormatter={yaxisFormatter} width={YAXIS_WIDTH} />
                  <Tooltip
                    formatter={tooltipFormatterNumber}
                    labelFormatter={tooltipLabelFormatter}
                    contentStyle={{ textAlign: 'left' }}
                  />
                  <Legend />
                  <Line isAnimationActive={false} type="monotone" strokeWidth={2} unit="$" dot={false} dataKey="aum" stackId="a" name="AUM" stroke={COLORS[0]} />
                  <Line isAnimationActive={false} type="monotone" strokeWidth={2} dot={false} dataKey="alpSupply" stackId="a" name="Alp Supply" stroke={COLORS[1]} />
                </LineChart>
              </ResponsiveContainer>
            </ChartWrapper>
          </div>
          <div className="chart-cell">
            <ChartWrapper
              title="Alp Price Comparison"
              loading={alpLoading}
              data={alpPriceData}
              csvFields={[{ key: 'syntheticPrice' }, { key: 'alpPrice' }, { key: 'alpPlusFees' }, { key: 'lpBtcPrice' }, { key: 'lpEthPrice' }]}
            >
              <ResponsiveContainer width="100%" height={CHART_HEIGHT}>
                <LineChart data={alpPriceData} syncId="syncAlp">
                  <CartesianGrid strokeDasharray="3 3" stroke='#333333' />
                  <XAxis dataKey="timestamp" tickFormatter={tooltipLabelFormatter} minTickGap={30} />
                  <YAxis dataKey="performanceSyntheticCollectedFees" domain={[60, 210]} unit="%" tickFormatter={yaxisFormatterNumber} width={YAXIS_WIDTH} />
                  <YAxis dataKey="alpPrice" domain={[0.4, 1.7]} orientation="right" yAxisId="right" tickFormatter={yaxisFormatterNumber} width={YAXIS_WIDTH} />
                  <Tooltip
                    formatter={tooltipFormatterNumber}
                    labelFormatter={tooltipLabelFormatter}
                    contentStyle={{ textAlign: 'left' }}
                  />
                  <Legend />
                  {/* <Line dot={false} isAnimationActive={false} type="monotone" unit="%" strokeWidth={2} dataKey="performanceLpBtcCollectedFees" name="% LP BTC-USDC (w/ fees)" stroke={COLORS[2]} />
                  <Line dot={false} isAnimationActive={false} type="monotone" unit="%" strokeWidth={2} dataKey="performanceLpEthCollectedFees" name="% LP ETH-USDC (w/ fees)" stroke={COLORS[4]} />
                  <Line dot={false} isAnimationActive={false} type="monotone" unit="%" strokeWidth={2} dataKey="performanceSyntheticCollectedFees" name="% Index (w/ fees)" stroke={COLORS[0]} /> */}

                  {/* <Line isAnimationActive={false} type="monotone" unit="$" strokeWidth={1} yAxisId="right" dot={false} dataKey="syntheticPrice" name="Index Price" stroke={COLORS[2]} /> */}
                  <Line isAnimationActive={false} type="monotone" unit="$" strokeWidth={1} yAxisId="right" dot={false} dataKey="alpPrice" name="Alp Price" stroke={COLORS[1]} strokeWidth={1} />
                  <Line isAnimationActive={false} type="monotone" unit="$" strokeWidth={1} yAxisId="right" dot={false} dataKey="alpPlusFees" name="Alp w/ fees" stroke={COLORS[3]} strokeWidth={1} />
                  {/* <Line isAnimationActive={false} type="monotone" unit="$" strokeWidth={1} yAxisId="right" dot={false} dataKey="lpBtcPrice" name="LP BTC-USDC" stroke={COLORS[2]} />
                  <Line isAnimationActive={false} type="monotone" unit="$" strokeWidth={1} yAxisId="right" dot={false} dataKey="lpEthPrice" name="LP ETH-USDC" stroke={COLORS[4]} /> */}
                </LineChart>
              </ResponsiveContainer>
              <div className="chart-description">
                <p>
                  <span style={{ color: COLORS[3] }}>Alp with fees</span> is based on ALP share of fees received and excluding esGMX rewards<br />
                  {/* <span style={{ color: COLORS[0] }}>% of Index (with fees)</span> is Alp with fees / Index Price * 100<br />
                  <span style={{ color: COLORS[4] }}>% of LP ETH-USDC (with fees)</span> is Alp Price with fees / LP ETH-USDC * 100<br />
                  <span style={{ color: COLORS[2] }}>Index Price</span> is 25% BTC, 25% ETH, 50% USDC */}
                </p>
              </div>
            </ChartWrapper>
          </div>
          {isExperiment && <div className="chart-cell experiment">
            <ChartWrapper title="Performance vs. Index" loading={alpLoading}>
              <ResponsiveContainer width="100%" height={CHART_HEIGHT}>
                <LineChart data={alpPerformanceData} syncId="syncAlp">
                  <CartesianGrid strokeDasharray="3 3" stroke='#333333' />
                  <XAxis dataKey="timestamp" tickFormatter={tooltipLabelFormatter} minTickGap={30} />
                  <YAxis dataKey="performanceSyntheticCollectedFees" domain={[80, 120]} unit="%" tickFormatter={yaxisFormatterNumber} width={YAXIS_WIDTH} />
                  <Tooltip
                    formatter={tooltipFormatterNumber}
                    labelFormatter={tooltipLabelFormatter}
                    contentStyle={{ textAlign: 'left' }}
                  />
                  <Legend />
                  <Line isAnimationActive={false} dot={false} type="monotone" unit="%" strokeWidth={2} dataKey="performanceSyntheticCollectedFees" name="Collected Fees" stroke={COLORS[0]} />
                  <Line isAnimationActive={false} dot={false} type="monotone" unit="%" strokeWidth={2} dataKey="performanceSyntheticDistributedUsd" name="Distributed Usd" stroke={COLORS[1]} />
                  <Line isAnimationActive={false} dot={false} type="monotone" unit="%" strokeWidth={2} dataKey="performanceSyntheticDistributedEth" name="Distributed Eth" stroke={COLORS[2]} />
                  <Line isAnimationActive={false} dot={false} type="monotone" unit="%" strokeWidth={2} dataKey="performanceSynthetic" name="No Fees" stroke={COLORS[3]} />
                </LineChart>
              </ResponsiveContainer>
            </ChartWrapper>
          </div>}
          {isExperiment && <div className="chart-cell experiment">
            <ChartWrapper title="Performance vs. ETH LP" loading={alpLoading}>
              <ResponsiveContainer width="100%" height={CHART_HEIGHT}>
                <LineChart data={alpPerformanceData} syncId="syncAlp">
                  <CartesianGrid strokeDasharray="3 3" stroke='#333333' />
                  <XAxis dataKey="timestamp" tickFormatter={tooltipLabelFormatter} minTickGap={30} />
                  <YAxis dataKey="performanceLpEthCollectedFees" domain={[80, 120]} unit="%" tickFormatter={yaxisFormatterNumber} width={YAXIS_WIDTH} />
                  <Tooltip
                    formatter={tooltipFormatterNumber}
                    labelFormatter={tooltipLabelFormatter}
                    contentStyle={{ textAlign: 'left' }}
                  />
                  <Legend />
                  <Line isAnimationActive={false} dot={false} type="monotone" unit="%" strokeWidth={2} dataKey="performanceLpEthCollectedFees" name="Collected Fees" stroke={COLORS[0]} />
                  <Line isAnimationActive={false} dot={false} type="monotone" unit="%" strokeWidth={2} dataKey="performanceLpEthDistributedUsd" name="Distributed Usd" stroke={COLORS[1]} />
                  <Line isAnimationActive={false} dot={false} type="monotone" unit="%" strokeWidth={2} dataKey="performanceLpEthDistributedEth" name="Distributed Eth" stroke={COLORS[2]} />
                  <Line isAnimationActive={false} dot={false} type="monotone" unit="%" strokeWidth={2} dataKey="performanceLpEth" name="No Fees" stroke={COLORS[3]} />
                </LineChart>
              </ResponsiveContainer>
            </ChartWrapper>
          </div>}
          <div className="chart-cell">
            <ChartWrapper
              title="Traders Net PnL"
              loading={tradersLoading}
              data={tradersData?.data}
              csvFields={[{ key: 'pnl', name: 'Net PnL' }, { key: 'pnlCumulative', name: 'Cumulative PnL' }]}
            >
              <ResponsiveContainer width="100%" syncId="tradersId" height={CHART_HEIGHT}>
                <ComposedChart data={tradersData?.data}>
                  <CartesianGrid strokeDasharray="3 3" stroke='#333333' />
                  <XAxis dataKey="timestamp" tickFormatter={tooltipLabelFormatter} minTickGap={30} />
                  <YAxis domain={[-tradersData?.stats.maxAbsOfPnlAndCumulativePnl * 1.05, tradersData?.stats.maxAbsOfPnlAndCumulativePnl * 1.05]} tickFormatter={yaxisFormatter} width={YAXIS_WIDTH} />
                  <Tooltip
                    formatter={tooltipFormatter}
                    labelFormatter={tooltipLabelFormatter}
                    contentStyle={{ textAlign: 'left' }}
                  />
                  <Legend />
                  <Bar type="monotone" fill={mode == "dark" ? "#FFFFFF" : "#000000"} dot={false} dataKey="pnl" name="Net PnL">
                    {(tradersData?.data || []).map((item, i) => {
                      return <Cell key={`cell-${i}`} fill={item.pnl > 0 ? '#22c761' : '#f93333'} />
                    })}
                  </Bar>
                  <Line type="monotone" strokeWidth={2} stroke={COLORS[4]} dataKey="pnlCumulative" name="Cumulative PnL" />
                </ComposedChart>
              </ResponsiveContainer>
              <div className="chart-description">
                <p>Considers settled (closed) positions</p>
                <p>Fees are not factored into PnL</p>
              </div>
            </ChartWrapper>
          </div>
          <div className="chart-cell">
            <ChartWrapper
              title="Traders Profit vs. Loss"
              loading={tradersLoading}
              data={tradersData?.data}
              csvFields={[{ key: 'profit' }, { key: 'loss' }, { key: 'profitCumulative' }, { key: 'lossCumulative' }]}
            >
              <ResponsiveContainer width="100%" syncId="tradersId" height={CHART_HEIGHT}>
                <ComposedChart data={tradersData?.data} barGap={0}>
                  <CartesianGrid strokeDasharray="3 3" stroke='#333333' />
                  <XAxis dataKey="timestamp" tickFormatter={tooltipLabelFormatter} minTickGap={30} />
                  <YAxis domain={[-tradersData?.stats.maxProfitLoss * 1.05, tradersData?.stats.maxProfitLoss * 1.05]} tickFormatter={yaxisFormatter} width={YAXIS_WIDTH} />
                  <YAxis domain={[-tradersData?.stats.maxCumulativeProfitLoss * 1.1, tradersData?.stats.maxCumulativeProfitLoss * 1.1]} orientation="right" yAxisId="right" tickFormatter={yaxisFormatter} width={YAXIS_WIDTH} />
                  <Tooltip
                    formatter={tooltipFormatter}
                    labelFormatter={tooltipLabelFormatter}
                    contentStyle={{ textAlign: 'left' }}
                  />
                  <Legend />
                  <Area yAxisId="right" type="monotone" stroke={0} fill="#22c761" fillOpacity="0.4" dataKey="profitCumulative" name="Cumulative Profit" />
                  <Area yAxisId="right" type="monotone" stroke={0} fill="#f93333" fillOpacity="0.4" dataKey="lossCumulative" name="Cumulative Loss" />
                  <Bar type="monotone" fill="#22c761" dot={false} dataKey="profit" name="Profit" />
                  <Bar type="monotone" fill="#f93333" dot={false} dataKey="loss" name="Loss" />
                </ComposedChart>
              </ResponsiveContainer>
              <div className="chart-description">
                <p>Considers settled (closed) positions</p>
                <p>Fees are not factored into PnL</p>
              </div>
            </ChartWrapper>
          </div>
          <div className="chart-cell">
            <GenericChart
              loading={borrowRateLoading}
              title="Borrowing Rate Annualized"
              data={borrowRateData}
              yaxisDataKey="ETH"
              yaxisTickFormatter={yaxisFormatterPercent}
              tooltipFormatter={tooltipFormatterPercent}
              items={[{ key: 'ETH' }, { key: 'BTC' }, { key: 'USDC' }, { key: 'USDT' }, { key: 'MATIC' }]}
              type="Line"
              yaxisDomain={[0, 90 /* ~87% is a maximum yearly borrow rate */]}
              isCoinChart={true}
            />
          </div>
          <div className="chart-cell">
            <GenericChart
              loading={tradersLoading}
              title="Open Interest"
              data={tradersData?.data.map(item => ({ all: item.openInterest, ...item }))}
              yaxisDataKey="openInterest"
              items={[{ key: 'shortOpenInterest', name: 'Short', color: "#f93333" }, { key: 'longOpenInterest', name: 'Long', color: '#22c761' }]}
              type="Bar"
            />
          </div>
          <div className="chart-cell">
            <GenericChart
              syncId="syncAlp"
              loading={aumPerformanceLoading}
              title="AUM Performance Annualized"
              data={aumPerformanceData}
              yaxisDataKey="apr"
              yaxisTickFormatter={yaxisFormatterPercent}
              tooltipFormatter={tooltipFormatterPercent}
              items={[{ key: 'apr', name: 'APR', color: COLORS[0] }]}
              description="Formula = Daily Fees / ALP Pool * 365 days * 100"
              type="Composed"
            />
          </div>
          <div className="chart-cell">
            <GenericChart
              syncId="syncAlp"
              loading={aumPerformanceLoading}
              title="AUM Daily Usage"
              data={aumPerformanceData}
              yaxisDataKey="usage"
              yaxisTickFormatter={yaxisFormatterPercent}
              tooltipFormatter={tooltipFormatterPercent}
              items={[{ key: 'usage', name: 'Daily Usage', color: COLORS[4] }]}
              description="Formula = Daily Volume / ALP Pool * 100"
              type="Composed"
            />
          </div>
          <div className="chart-cell">
            <GenericChart
              syncId="syncAlp"
              loading={usersLoading}
              title="Unique Users"
              data={usersData}
              yaxisDataKey="uniqueSum"
              yaxisTickFormatter={yaxisFormatterNumber}
              tooltipFormatter={tooltipFormatterNumber}
              tooltipLabelFormatter={tooltipLabelFormatterUnits}
              items={[
                { key: 'uniqueSwapCount', name: 'Swaps' },
                { key: 'uniqueMarginCount', name: 'Margin trading' },
                { key: 'uniqueMintBurnCount', name: 'Mint & Burn ALP' }
              ]}
              type="Composed"
            />
          </div>
          <div className="chart-cell">
            <GenericChart
              syncId="syncAlp"
              loading={usersLoading}
              title="New Users"
              data={usersData?.map(item => ({ ...item, all: item.newCount }))}
              yaxisDataKey="newCount"
              rightYaxisDataKey="uniqueCountCumulative"
              yaxisTickFormatter={yaxisFormatterNumber}
              tooltipFormatter={tooltipFormatterNumber}
              tooltipLabelFormatter={tooltipLabelFormatterUnits}
              items={[
                { key: 'newSwapCount', name: 'Swap' },
                { key: 'newMarginCount', name: 'Margin trading' },
                { key: 'newMintBurnCount', name: 'Mint & Burn' },
                { key: 'uniqueCountCumulative', name: 'Cumulative', type: 'Line', yAxisId: 'right', strokeWidth: 2, color: COLORS[4] }
              ]}
              type="Composed"
            />
          </div>
          <div className="chart-cell">
            <GenericChart
              syncId="syncAlp"
              loading={usersLoading}
              title="New vs. Existing Users"
              data={usersData?.map(item => ({ ...item, all: item.uniqueCount }))}
              yaxisDataKey="newCount"
              rightYaxisDataKey="oldPercent"
              yaxisTickFormatter={yaxisFormatterNumber}
              tooltipFormatter={tooltipFormatterNumber}
              tooltipLabelFormatter={tooltipLabelFormatterUnits}
              items={[
                { key: 'newCount', name: 'New' },
                { key: 'oldCount', name: 'Existing' },
                { key: 'oldPercent', name: 'Existing %', yAxisId: 'right', type: 'Line', strokeWidth: 2, color: COLORS[4], unit: '%' }
              ]}
              type="Composed"
            />
          </div>
          <div className="chart-cell">
            <GenericChart
              syncId="syncAlp"
              loading={usersLoading}
              title="User Actions"
              data={(usersData || []).map(item => ({ ...item, all: item.actionCount }))}
              yaxisDataKey="actionCount"
              yaxisTickFormatter={yaxisFormatterNumber}
              tooltipFormatter={tooltipFormatterNumber}
              tooltipLabelFormatter={tooltipLabelFormatterUnits}
              items={[{ key: 'actionSwapCount', name: 'Swaps' }, { key: 'actionMarginCount', name: 'Margin trading' }, { key: 'actionMintBurnCount', name: 'Mint & Burn ALP' }]}
              type="Composed"
            />
          </div>
          {/* <div className="chart-cell">
            <GenericChart
              loading={swapSourcesLoading}
              title="Swap Sources"
              data={swapSources}
              items={swapSourcesKeys.map(key => ({ key }))}
            />
          </div> */}
        </div>
      </div>
    </div>
  );
}
Example #17
Source File: RtcMetricsView.jsx    From amazon-connect-snippets with MIT No Attribution 3 votes vote down vote up
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 &amp; 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>
        );
    }