Skip to content

Commit

Permalink
Merge pull request #47 from squidit/feature/sq-66297.front.atualizar-…
Browse files Browse the repository at this point in the history
…grafico-de-crescimento-do-perfil

✨ feat: SQ-66297 [front] atualizar gráfico de crescimento do perfil
  • Loading branch information
wandersonsales-dev authored Oct 11, 2024
2 parents f05f574 + aa19c9b commit 5f54f44
Show file tree
Hide file tree
Showing 9 changed files with 630 additions and 386 deletions.
770 changes: 386 additions & 384 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@squidit/react-css",
"version": "1.1.10",
"version": "1.1.11",
"scripts": {
"format": "prettier --write --parser typescript '**/*.{ts,tsx}'",
"lint": "eslint src --ext js,ts,tsx",
Expand Down
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,4 @@ export * from './sq-tip'
export * from './sq-toggle-checkbox'
export * from './sq-toggle-checkbox-group'
export * from './sq-vertical-bar-chart'
export * from './sq-chart-line'
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react'
import SqChartLine, { Props } from '../sq-chart-line.component'

const SqChartLineExample = (props: Props) => {
return (
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
width: '100%',
margin: '0 auto',
}}
>
<SqChartLine {...props} />
</div>
)
}

export default SqChartLineExample
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Meta, StoryObj } from '@storybook/react'
import SqChartLineExample from './sq-chart-line.component.example'

const meta: Meta<typeof SqChartLineExample> = {
title: 'Components/SqChartLine',
parameters: {
docs: {
description: {
component: 'A simple ChartLine component',
},
},
},
component: SqChartLineExample,
tags: ['autodocs'],
}

export default meta
type Story = StoryObj<typeof SqChartLineExample>

// array from dates in string format
const datasets = [
{ count: 450, date: '2024-02-02T00:00:00.000Z', total: 1000 },
{ count: 500, date: '2024-02-03T00:00:00.000Z', total: 1500 },
{ count: 200, date: '2024-02-04T00:00:00.000Z', total: 1700 },
{
count: 700,
date: '2024-02-05T00:00:00.000Z',
total: 2400,
},
{ count: 300, date: '2024-02-06T00:00:00.000Z', total: 2700 },
{ count: 600, date: '2024-02-07T00:00:00.000Z', total: 3300 },
{ count: 900, date: '2024-02-08T00:00:00.000Z', total: 4200 },
{ count: 100, date: '2024-02-09T00:00:00.000Z', total: 4300 },
{ count: 800, date: '2024-02-10T00:00:00.000Z', total: 5100 },
{ count: 400, date: '2024-02-11T00:00:00.000Z', total: 5500 },
{ count: 1000, date: '2024-02-12T00:00:00.000Z', total: 6500 },
{ count: 300, date: '2024-02-13T00:00:00.000Z', total: 6800 },
{ count: 600, date: '2024-02-14T00:00:00.000Z', total: 7400 },
{ count: 200, date: '2024-02-15T00:00:00.000Z', total: 7600 },
{ count: 500, date: '2024-02-16T00:00:00.000Z', total: 8100 },
{ count: 700, date: '2024-02-17T00:00:00.000Z', total: 8800 },
{ count: 800, date: '2024-02-18T00:00:00.000Z', total: 9600 },
{ count: 1000, date: '2024-02-19T00:00:00.000Z', total: 10600 },
]

export const Default: Story = {
args: {
data: {
labels: datasets?.map((d) => new Intl.DateTimeFormat('en-us').format(new Date(d.date))),
datasets: [
{
label: 'Engajamento Diário',
data: datasets?.map((d) => d.count),
},
],
},
},
}
1 change: 1 addition & 0 deletions src/components/sq-chart-line/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as SqChartLine } from './sq-chart-line.component'
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.chart-line {
width: 100%;

canvas {
width: 100%;
height: 100%;
}
}
153 changes: 153 additions & 0 deletions src/components/sq-chart-line/sq-chart-line.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
'use client'

import React, { HTMLAttributes, useEffect, useRef, useState } from 'react'
import {
CategoryScale,
Chart,
ChartData,
ChartOptions,
LinearScale,
LineController,
LineElement,
PointElement,
Tooltip,
Filler,
} from 'chart.js'

import './sq-chart-line.component.scoped.scss'

export interface Props extends HTMLAttributes<HTMLDivElement> {
data: ChartData
options?: ChartOptions
}

Chart.register(LineController, Tooltip, PointElement, CategoryScale, LinearScale, LineElement, Filler)

export default function SqChartLine({ className = '', style = {}, id = '', data, options }: Readonly<Props>) {
const chartRef = useRef<HTMLCanvasElement>(null)
const [chart, setChart] = useState<Chart | null>(null)
const [width, setWidth] = useState(window.innerWidth)
const [height, setHeight] = useState(window.innerHeight)

useEffect(() => {
if (chartRef.current) {
const maxDataValue = Math.max(...(data.datasets[0].data as number[]))
const minDataValue = Math.min(...(data.datasets[0].data as number[]))
const addGradient = (ctx) => {
const gradient = ctx.createLinearGradient(0, 0, 0, 220)
gradient.addColorStop(0, getComputedStyle(document.documentElement).getPropertyValue('--blue-50'))
gradient.addColorStop(1, getComputedStyle(document.documentElement).getPropertyValue('--color_bg_box_neutral_primary'))
return gradient
}
const adjustRadiusBasedOnData = (ctx) => {
const v = ctx.parsed.y
return v === maxDataValue ? 5 : width < 991 ? 0 : 2
}
if (chart) {
chart.destroy()
}
const ctx = chartRef.current.getContext('2d')
const chartLine = Chart.getChart(chartRef.current)
if (chartLine) {
chartLine.destroy()
}
if (ctx) {
setChart(
new Chart(ctx, {
type: 'line',
data: {
...data,
datasets: [
...data.datasets.map((dataset) => ({
...dataset,
fill: true,
backgroundColor: addGradient(ctx),
borderColor: getComputedStyle(document.documentElement).getPropertyValue('--blue-55'),
tension: 0.4,
borderWidth: 2,
pointBackgroundColor: getComputedStyle(document.documentElement).getPropertyValue('--background_secondary'),
})),
],
},
options: {
plugins: {
legend: {
display: false,
},
filler: {
propagate: false,
},
},
scales: {
x: {
grid: {
display: false,
},
border: {
display: false,
},
},
y: {
max: maxDataValue + maxDataValue * 0.1,
min: minDataValue - minDataValue * 0.2,
display: false,
grid: {
display: false,
},
beginAtZero: true,
},
},
elements: {
point: {
radius: adjustRadiusBasedOnData,
hoverRadius: 10,
hoverBorderWidth: 2,
borderWidth: 3,
},
},
responsive: true,
...options,
},
}),
)
}
}
return () => {
if (chart) {
chart.destroy()
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [data, width, height, options])

useEffect(() => {
const updateHeight = () => {
setHeight(window?.innerHeight)
}
const updateWidth = () => {
setWidth(window?.innerWidth)
}
const beforePrintHandler = () => {
chart?.resize(600, 600)
}
const afterPrintHandler = () => {
chart?.resize()
}
window.addEventListener('resize', updateHeight)
window.addEventListener('resize', updateWidth)
window.addEventListener('beforeprint', beforePrintHandler)
window.addEventListener('afterprint', afterPrintHandler)
return () => {
window.removeEventListener('resize', updateHeight)
window.removeEventListener('resize', updateWidth)
window.removeEventListener('beforeprint', beforePrintHandler)
window.removeEventListener('afterprint', afterPrintHandler)
}
}, [])

return (
<div className={`chart-line ${className}`} style={style} id={id}>
<canvas ref={chartRef} />
</div>
)
}
3 changes: 2 additions & 1 deletion src/observables/on-lang-change.observable.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import { BehaviorSubject } from 'rxjs'
export default new BehaviorSubject<'pt' | 'en' | 'es'>('en')
export type Language = 'pt' | 'en' | 'es'
export default new BehaviorSubject<Language>('en')

0 comments on commit 5f54f44

Please sign in to comment.