mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2026-04-22 06:26:19 +00:00
Added order control to countries graph
This commit is contained in:
49
src/visits/CountriesGraph.js
Normal file
49
src/visits/CountriesGraph.js
Normal file
@@ -0,0 +1,49 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { fromPairs, head, keys, prop, reverse, sortBy, toPairs } from 'ramda';
|
||||
import SortingDropdown from '../utils/SortingDropdown';
|
||||
import GraphCard from './GraphCard';
|
||||
|
||||
export default class CountriesGraph extends React.Component {
|
||||
static propTypes = {
|
||||
stats: PropTypes.any,
|
||||
};
|
||||
|
||||
state = {
|
||||
orderField: undefined,
|
||||
orderDir: undefined,
|
||||
};
|
||||
|
||||
render() {
|
||||
const items = {
|
||||
name: 'Country name',
|
||||
amount: 'Visits amount',
|
||||
};
|
||||
const { stats } = this.props;
|
||||
const sortStats = () => {
|
||||
if (!this.state.orderField) {
|
||||
return stats;
|
||||
}
|
||||
|
||||
const sortedPairs = sortBy(prop(this.state.orderField === head(keys(items)) ? 0 : 1), toPairs(stats));
|
||||
|
||||
return fromPairs(this.state.orderDir === 'ASC' ? sortedPairs : reverse(sortedPairs));
|
||||
};
|
||||
|
||||
return (
|
||||
<GraphCard stats={sortStats()} isBarChart>
|
||||
Countries
|
||||
<div className="float-right">
|
||||
<SortingDropdown
|
||||
isButton={false}
|
||||
right
|
||||
orderField={this.state.orderField}
|
||||
orderDir={this.state.orderDir}
|
||||
items={items}
|
||||
onChange={(orderField, orderDir) => this.setState({ orderField, orderDir })}
|
||||
/>
|
||||
</div>
|
||||
</GraphCard>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import { keys, values } from 'ramda';
|
||||
|
||||
const propTypes = {
|
||||
title: PropTypes.string,
|
||||
children: PropTypes.node,
|
||||
isBarChart: PropTypes.bool,
|
||||
stats: PropTypes.object,
|
||||
matchMedia: PropTypes.func,
|
||||
@@ -80,9 +81,9 @@ const renderGraph = (title, isBarChart, stats, matchMedia) => {
|
||||
return <Component data={generateGraphData(title, isBarChart, labels, data)} options={options} height={null} />;
|
||||
};
|
||||
|
||||
const GraphCard = ({ title, isBarChart, stats, matchMedia }) => (
|
||||
const GraphCard = ({ title, children, isBarChart, stats, matchMedia }) => (
|
||||
<Card className="mt-4">
|
||||
<CardHeader>{title}</CardHeader>
|
||||
<CardHeader className="graph-card__header">{children || title}</CardHeader>
|
||||
<CardBody>{renderGraph(title, isBarChart, stats, matchMedia)}</CardBody>
|
||||
</Card>
|
||||
);
|
||||
|
||||
@@ -7,6 +7,7 @@ import { Card } from 'reactstrap';
|
||||
import PropTypes from 'prop-types';
|
||||
import DateInput from '../common/DateInput';
|
||||
import MutedMessage from '../utils/MuttedMessage';
|
||||
import CountriesGraph from './CountriesGraph';
|
||||
import { getShortUrlVisits, shortUrlVisitsType } from './reducers/shortUrlVisits';
|
||||
import {
|
||||
processBrowserStats,
|
||||
@@ -95,7 +96,7 @@ export class ShortUrlsVisitsComponent extends React.Component {
|
||||
<GraphCard title="Browsers" stats={processBrowserStats(visits)} />
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<GraphCard title="Countries" stats={processCountriesStats(visits)} isBarChart />
|
||||
<CountriesGraph stats={processCountriesStats(visits)} />
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<GraphCard title="Referrers" stats={processReferrersStats(visits)} isBarChart />
|
||||
|
||||
Reference in New Issue
Block a user