diff --git a/README.md b/README.md index c8685a2..aeb56b7 100644 --- a/README.md +++ b/README.md @@ -75,12 +75,12 @@ O projeto foi guiado por referências visuais profissionais que definiram nossos - ✅ Análise de custos de construção - ✅ Interface profissional -### 🏡 **V3 - Smart Home Complexo** -**Porta: 8053** | **Foco: ML & Análise Avançada** -- ✅ **4 Visualizações**: Sunburst + Mapa + Scatter + ML -- ✅ **Machine Learning**: Análise preditiva de economia de energia -- ✅ **Mapas Geográficos**: Coordenadas reais dos EUA -- ✅ **Design Moderno**: Cards responsivos com styling avançado +### ⚖️ **V4 - Painel Jurídico** +**Porta: 8054** | **Foco: Análise de Custos Jurídicos** +- ✅ Hierarquia de Casos: Tipo de Caso → Área de Atuação → Serviço +- ✅ Filtros dinâmicos para análise detalhada +- ✅ Visualização de honorários e horas estimadas +- ✅ Interface limpa e profissional para uso jurídico --- @@ -107,6 +107,10 @@ python dashboards/v2_construction/V2_script.py # V3 - Smart Home Complexo python dashboards/v3_smart_home/Plan_V3_funcional.py # Acesse: http://localhost:8053 + +# V4 - Painel Jurídico +python dashboards/v4_juridical/V4_juridical_dashboard.py +# Acesse: http://localhost:8054 ``` --- @@ -119,7 +123,8 @@ Python-Data-Driven-Visualization-Journey/ ├── 📊 dashboards/ │ ├── 🌟 v1_simple/ # Dashboard básico com Sunburst │ ├── 🏗️ v2_construction/ # Dashboard de construção com filtros -│ └── 🏡 v3_smart_home/ # Dashboard complexo com ML +│ ├── 🏡 v3_smart_home/ # Dashboard complexo com ML +│ └── ⚖️ v4_juridical/ # Dashboard jurídico com análise de custos ├── 📚 docs/ # Documentação e guias ├── 🔴 error_reports/ # Relatórios de erros e lições aprendidas ├── 🤖 ai_learning_guides/ # Instruções para futuros modelos de IA diff --git a/dashboards/v4_juridical/V4_juridical_dashboard.py b/dashboards/v4_juridical/V4_juridical_dashboard.py new file mode 100644 index 0000000..22ecf8f --- /dev/null +++ b/dashboards/v4_juridical/V4_juridical_dashboard.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- + +from dash import Dash, dcc, html +from dash.dependencies import Input, Output +import plotly.express as px +import pandas as pd + +# Simulação de dados jurídicos hierárquicos +# Hierarquia: Tipo de Caso -> Área de Atuação -> Serviço -> Tarefa -> Sub-tarefa +data = [ + # Contencioso Cível + {'tipo_caso': 'Contencioso', 'area_atuacao': 'Cível', 'servico': 'Petição Inicial', 'tarefa': 'Análise de Documentos', 'sub_tarefa': 'Análise de Provas', 'honorarios': 15000, 'horas_estimadas': 20}, + {'tipo_caso': 'Contencioso', 'area_atuacao': 'Cível', 'servico': 'Petição Inicial', 'tarefa': 'Pesquisa de Jurisprudência', 'sub_tarefa': 'Estudo de Doutrina', 'honorarios': 10000, 'horas_estimadas': 15}, + {'tipo_caso': 'Contencioso', 'area_atuacao': 'Cível', 'servico': 'Contestação', 'tarefa': 'Redação da Peça', 'sub_tarefa': 'Elaboração da Tese', 'honorarios': 20000, 'horas_estimadas': 25}, + + # Contencioso Trabalhista + {'tipo_caso': 'Contencioso', 'area_atuacao': 'Trabalhista', 'servico': 'Recurso Ordinário', 'tarefa': 'Análise do Processo', 'sub_tarefa': 'Verificação de Prazos', 'honorarios': 25000, 'horas_estimadas': 30}, + {'tipo_caso': 'Contencioso', 'area_atuacao': 'Trabalhista', 'servico': 'Recurso Ordinário', 'tarefa': 'Redação do Recurso', 'sub_tarefa': 'Fundamentação Jurídica', 'honorarios': 35000, 'horas_estimadas': 40}, + + # Consultivo Tributário + {'tipo_caso': 'Consultivo', 'area_atuacao': 'Tributário', 'servico': 'Parecer Jurídico', 'tarefa': 'Análise da Legislação', 'sub_tarefa': 'Estudo de Caso', 'honorarios': 40000, 'horas_estimadas': 50}, + {'tipo_caso': 'Consultivo', 'area_atuacao': 'Tributário', 'servico': 'Planejamento Tributário', 'tarefa': 'Reunião com Cliente', 'sub_tarefa': 'Alinhamento Estratégico', 'honorarios': 50000, 'horas_estimadas': 60}, + + # Consultivo Contratual + {'tipo_caso': 'Consultivo', 'area_atuacao': 'Contratual', 'servico': 'Elaboração de Contrato', 'tarefa': 'Definição de Cláusulas', 'sub_tarefa': 'Negociação com a Outra Parte', 'honorarios': 30000, 'horas_estimadas': 35}, + {'tipo_caso': 'Consultivo', 'area_atuacao': 'Contratual', 'servico': 'Revisão de Contrato', 'tarefa': 'Análise de Riscos', 'sub_tarefa': 'Sugestão de Alterações', 'honorarios': 22000, 'horas_estimadas': 28}, +] +df_juridico = pd.DataFrame(data) + +app = Dash(__name__) + +# Obter valores mínimos e máximos de honorários para o RangeSlider +min_honorarios = df_juridico['honorarios'].min() +max_honorarios = df_juridico['honorarios'].max() + +# Layout do Dashboard Jurídico +app.layout = html.Div(style={'fontFamily': 'Arial, sans-serif'}, children=[ + html.H1("Painel Jurídico: Análise de Custos e Casos", style={'textAlign': 'center', 'color': '#1a2c5b'}), + + html.Div(style={'display': 'flex', 'justifyContent': 'space-around', 'padding': '20px'}, children=[ + html.Div(style={'width': '30%'}, children=[ + html.Label("Selecione o Tipo de Caso:"), + dcc.Dropdown( + id='tipo-caso-dropdown', + options=[{'label': i, 'value': i} for i in df_juridico['tipo_caso'].unique()] + [{'label': 'Todos', 'value': 'Todos'}], + value='Todos' + ), + ]), + html.Div(style={'width': '30%'}, children=[ + html.Label("Selecione a Área de Atuação:"), + dcc.Dropdown( + id='area-atuacao-dropdown', + value='Todos' + ), + ]), + html.Div(style={'width': '30%'}, children=[ + html.Label("Selecione o Serviço:"), + dcc.Dropdown( + id='servico-dropdown', + value='Todos' + ), + ]), + ]), + + html.Div(style={'padding': '0 40px'}, children=[ + html.Label("Filtrar por Faixa de Honorários:"), + dcc.RangeSlider( + id='honorarios-range-slider', + min=min_honorarios, + max=max_honorarios, + value=[min_honorarios, max_honorarios], + marks={int(min_honorarios): f'R${int(min_honorarios):,}', int(max_honorarios): f'R${int(max_honorarios):,}'}, + step=5000 + ), + ]), + + dcc.Graph(id='sunburst-chart-juridico') +]) + +# Callback para atualizar o gráfico e os dropdowns dinamicamente +@app.callback( + Output('sunburst-chart-juridico', 'figure'), + Output('area-atuacao-dropdown', 'options'), + Output('servico-dropdown', 'options'), + Input('tipo-caso-dropdown', 'value'), + Input('area-atuacao-dropdown', 'value'), + Input('servico-dropdown', 'value'), + Input('honorarios-range-slider', 'value') +) +def update_juridical_dashboard(selected_tipo_caso, selected_area, selected_servico, honorarios_range): + filtered_df = df_juridico.copy() + + # Lógica para atualizar dropdowns em cascata + area_options_df = filtered_df + if selected_tipo_caso != 'Todos': + area_options_df = filtered_df[filtered_df['tipo_caso'] == selected_tipo_caso] + + servico_options_df = area_options_df + if selected_area != 'Todos' and selected_area is not None: + servico_options_df = area_options_df[area_options_df['area_atuacao'] == selected_area] + + area_options = [{'label': i, 'value': i} for i in area_options_df['area_atuacao'].unique()] + [{'label': 'Todos', 'value': 'Todos'}] + servico_options = [{'label': i, 'value': i} for i in servico_options_df['servico'].unique()] + [{'label': 'Todos', 'value': 'Todos'}] + + # Filtragem do DataFrame principal para o gráfico + if selected_tipo_caso != 'Todos': + filtered_df = filtered_df[filtered_df['tipo_caso'] == selected_tipo_caso] + if selected_area != 'Todos' and selected_area is not None: + filtered_df = filtered_df[filtered_df['area_atuacao'] == selected_area] + if selected_servico != 'Todos' and selected_servico is not None: + filtered_df = filtered_df[filtered_df['servico'] == selected_servico] + + filtered_df = filtered_df[(filtered_df['honorarios'] >= honorarios_range[0]) & (filtered_df['honorarios'] <= honorarios_range[1])] + + # Mapa de cores para os tipos de caso + custom_color_map = { + 'Contencioso': '#d62728', # Vermelho + 'Consultivo': '#1f77b4', # Azul + '(?)': '#cccccc' + } + + # Geração do gráfico Sunburst + fig = px.sunburst( + filtered_df, + path=['tipo_caso', 'area_atuacao', 'servico', 'tarefa', 'sub_tarefa'], + values='honorarios', + color='tipo_caso', + color_discrete_map=custom_color_map, + custom_data=['honorarios', 'horas_estimadas'] + ) + + # Configurações de layout e aparência do gráfico + fig.update_traces( + textinfo='label+percent parent', + hovertemplate='%{label}

' + + 'Honorários: R$ %{customdata[0]:,.2f}
' + + 'Horas Estimadas: %{customdata[1]}h
' + + 'Custo por Hora: R$ %{customdata[0]/customdata[1]:,.2f}/h
' + + '', + insidetextorientation='radial', + textfont_size=12, + marker=dict(line=dict(color='#ffffff', width=2)) + ) + + fig.update_layout( + title_text='Distribuição de Honorários por Tipo de Caso e Área de Atuação', + title_x=0.5, + font=dict(family='Arial, sans-serif', size=14, color='black'), + margin=dict(t=80, l=40, r=40, b=40) + ) + + return fig, area_options, servico_options + +# Executar a aplicação +if __name__ == '__main__': + app.run_server(debug=True, port=8054) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 87bb15f..0c9c722 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,21 +1,21 @@ # Core Dependencies -dash==2.16.1 -plotly==5.17.0 -pandas==2.1.4 -numpy==1.25.2 +dash==2.17.0 +plotly==5.22.0 +pandas==2.2.2 +numpy==1.26.4 # Machine Learning -scikit-learn==1.3.2 +scikit-learn==1.5.1 # Optional Dependencies (for development) jupyter==1.0.0 -matplotlib==3.8.2 -seaborn==0.13.0 +matplotlib==3.9.1 +seaborn==0.13.2 # Web Server -gunicorn==21.2.0 +gunicorn==22.0.0 # Development Tools (optional) -black==23.12.1 -flake8==6.1.0 -pytest==7.4.3 +black==24.4.2 +flake8==7.1.0 +pytest==8.3.2 \ No newline at end of file