mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2024-12-23 17:40:23 +03:00
Extracted PieChartLegend to its own component
This commit is contained in:
parent
d55160e8f6
commit
036c8aafcb
3 changed files with 31 additions and 39 deletions
|
@ -1,8 +1,8 @@
|
||||||
import { useRef } from 'react';
|
import { useState } from 'react';
|
||||||
import { Doughnut, Bar } from 'react-chartjs-2';
|
import { Doughnut, Bar } from 'react-chartjs-2';
|
||||||
import { keys, values } from 'ramda';
|
import { keys, values } from 'ramda';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { Chart, ChartData, ChartDataset, ChartOptions, LegendItem } from 'chart.js';
|
import { Chart, ChartData, ChartDataset, ChartOptions } from 'chart.js';
|
||||||
import { fillTheGaps } from '../../utils/helpers/visits';
|
import { fillTheGaps } from '../../utils/helpers/visits';
|
||||||
import { Stats } from '../types';
|
import { Stats } from '../types';
|
||||||
import { prettify } from '../../utils/helpers/numbers';
|
import { prettify } from '../../utils/helpers/numbers';
|
||||||
|
@ -16,7 +16,7 @@ import {
|
||||||
PRIMARY_DARK_COLOR,
|
PRIMARY_DARK_COLOR,
|
||||||
PRIMARY_LIGHT_COLOR,
|
PRIMARY_LIGHT_COLOR,
|
||||||
} from '../../utils/theme';
|
} from '../../utils/theme';
|
||||||
import './DefaultChart.scss';
|
import { PieChartLegend } from './PieChartLegend';
|
||||||
|
|
||||||
export interface DefaultChartProps {
|
export interface DefaultChartProps {
|
||||||
title: Function | string;
|
title: Function | string;
|
||||||
|
@ -79,32 +79,6 @@ const determineHeight = (isBarChart: boolean, labels: string[]): number | undefi
|
||||||
return isBarChart && labels.length > 20 ? labels.length * 8 : undefined;
|
return isBarChart && labels.length > 20 ? labels.length * 8 : undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderPieChartLegend = ({ config }: Chart): LegendItem[] => {
|
|
||||||
const { labels = [] /* , datasets = [] */ } = config.data ?? {};
|
|
||||||
// const { defaultColor } = config.options ?? {} as any;
|
|
||||||
// const [{ backgroundColor: colors }] = datasets;
|
|
||||||
|
|
||||||
return labels.map((label, datasetIndex) => ({
|
|
||||||
datasetIndex,
|
|
||||||
text: label as string,
|
|
||||||
}));
|
|
||||||
|
|
||||||
// TODO
|
|
||||||
// return (
|
|
||||||
// <ul className="default-chart__pie-chart-legend">
|
|
||||||
// {labels.map((label, index) => (
|
|
||||||
// <li key={label as string} className="default-chart__pie-chart-legend-item d-flex">
|
|
||||||
// <div
|
|
||||||
// className="default-chart__pie-chart-legend-item-color"
|
|
||||||
// style={{ backgroundColor: (colors as string[])[index] || defaultColor }}
|
|
||||||
// />
|
|
||||||
// <small className="default-chart__pie-chart-legend-item-text flex-fill">{label}</small>
|
|
||||||
// </li>
|
|
||||||
// ))}
|
|
||||||
// </ul>
|
|
||||||
// );
|
|
||||||
};
|
|
||||||
|
|
||||||
const chartElementAtEvent = (onClick?: (label: string) => void) => ([ chart ]: [{ _index: number; _chart: Chart }]) => {
|
const chartElementAtEvent = (onClick?: (label: string) => void) => ([ chart ]: [{ _index: number; _chart: Chart }]) => {
|
||||||
// TODO Check this function actually works with Chart.js 3
|
// TODO Check this function actually works with Chart.js 3
|
||||||
if (!onClick || !chart) {
|
if (!onClick || !chart) {
|
||||||
|
@ -123,7 +97,7 @@ const DefaultChart = (
|
||||||
{ title, isBarChart = false, stats, max, highlightedStats, highlightedLabel, onClick }: DefaultChartProps,
|
{ title, isBarChart = false, stats, max, highlightedStats, highlightedLabel, onClick }: DefaultChartProps,
|
||||||
) => {
|
) => {
|
||||||
const Component = isBarChart ? Bar : Doughnut;
|
const Component = isBarChart ? Bar : Doughnut;
|
||||||
const chartRef = useRef<typeof Component | undefined>();
|
const [ chartRef, setChartRef ] = useState<Chart | undefined>();
|
||||||
const labels = keys(stats).map(dropLabelIfHidden);
|
const labels = keys(stats).map(dropLabelIfHidden);
|
||||||
const data = values(
|
const data = values(
|
||||||
!statsAreDefined(highlightedStats) ? stats : keys(highlightedStats).reduce((acc, highlightedKey) => {
|
!statsAreDefined(highlightedStats) ? stats : keys(highlightedStats).reduce((acc, highlightedKey) => {
|
||||||
|
@ -138,12 +112,7 @@ const DefaultChart = (
|
||||||
|
|
||||||
const options: ChartOptions = {
|
const options: ChartOptions = {
|
||||||
plugins: {
|
plugins: {
|
||||||
legend: {
|
legend: { display: false },
|
||||||
display: false,
|
|
||||||
labels: isBarChart ? undefined : {
|
|
||||||
generateLabels: renderPieChartLegend,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
tooltip: {
|
tooltip: {
|
||||||
intersect: !isBarChart,
|
intersect: !isBarChart,
|
||||||
// Do not show tooltip on items with empty label when in a bar chart
|
// Do not show tooltip on items with empty label when in a bar chart
|
||||||
|
@ -177,7 +146,7 @@ const DefaultChart = (
|
||||||
<div className={classNames('col-sm-12', { 'col-md-7': !isBarChart })}>
|
<div className={classNames('col-sm-12', { 'col-md-7': !isBarChart })}>
|
||||||
<Component
|
<Component
|
||||||
ref={(element) => {
|
ref={(element) => {
|
||||||
chartRef.current = element ?? undefined;
|
setChartRef(element ?? undefined);
|
||||||
}}
|
}}
|
||||||
key={height}
|
key={height}
|
||||||
data={graphData}
|
data={graphData}
|
||||||
|
@ -188,8 +157,7 @@ const DefaultChart = (
|
||||||
</div>
|
</div>
|
||||||
{!isBarChart && (
|
{!isBarChart && (
|
||||||
<div className="col-sm-12 col-md-5">
|
<div className="col-sm-12 col-md-5">
|
||||||
No Legend in v3.0 unfortunately :(
|
{chartRef && <PieChartLegend chart={chartRef} />}
|
||||||
{/* {chartRef?.chartInstance.generateLegend()} */}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
24
src/visits/helpers/PieChartLegend.tsx
Normal file
24
src/visits/helpers/PieChartLegend.tsx
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
import { FC } from 'react';
|
||||||
|
import { Chart } from 'chart.js';
|
||||||
|
import './PieChartLegend.scss';
|
||||||
|
|
||||||
|
export const PieChartLegend: FC<{ chart: Chart }> = ({ chart }) => {
|
||||||
|
const { config } = chart;
|
||||||
|
const { labels = [], datasets = [] } = config.data ?? {};
|
||||||
|
const { defaultColor } = config.options ?? {} as any;
|
||||||
|
const [{ backgroundColor: colors }] = datasets;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ul className="default-chart__pie-chart-legend">
|
||||||
|
{(labels as string[]).map((label, index) => (
|
||||||
|
<li key={label} className="default-chart__pie-chart-legend-item d-flex">
|
||||||
|
<div
|
||||||
|
className="default-chart__pie-chart-legend-item-color"
|
||||||
|
style={{ backgroundColor: (colors as string[])[index] || defaultColor }}
|
||||||
|
/>
|
||||||
|
<small className="default-chart__pie-chart-legend-item-text flex-fill">{label}</small>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
);
|
||||||
|
};
|
Loading…
Reference in a new issue