Skip to main content

Overview

The Performance Dashboard transforms your study data into actionable insights with charts, statistics, and progress tracking. Monitor time invested, question performance, weekly trends, and subject-level analytics.
The Dashboard is the Check phase of the PDCA cycle - measure your performance here to identify areas for improvement.

Key Metrics

The dashboard displays four primary stat cards:

1. Study Time

Total accumulated time from all completed study sessions.
// Time calculation (views.js:666-667)
const totalSecs = filteredEvts.reduce((s, e) => s + (e.tempoAcumulado || 0), 0);

2. Sessions Completed

Count of events marked as estudei (studied).

3. Questions Answered

Sum of all questions from habit tracking and session registrations.
// Question counting (views.js:668-670)
const questTot = cutoffStr
  ? (state.habitos.questoes || []).filter(r => r.data >= cutoffStr).reduce((s, q) => s + (q.quantidade || 1), 0)
  : (state.habitos.questoes || []).reduce((s, q) => s + (q.quantidade || 1), 0);

4. Simulated Exams

Total number of full practice exams completed.

Time Period Filters

Filter all dashboard data by time period:
PeriodLabelDays
7 days7dLast 7 days
30 days30dLast 30 days
90 days3mLast 3 months
All timeTotalSince first event
// Period filtering (views.js:653-664)
export let dashPeriod = 7; // default

export function setDashPeriod(p) {
  dashPeriod = p;
  renderCurrentView();
}

const cutoffStr = periodDays ? cutoffDateStr(periodDays) : null;
const filteredEvts = cutoffStr
  ? state.eventos.filter(e => e.status === 'estudei' && e.data && e.data >= cutoffStr)
  : state.eventos.filter(e => e.status === 'estudei');
The period filter applies to all charts and metrics on the dashboard simultaneously.

Charts

Daily Study Hours Chart

Bar chart showing minutes studied per day:
// Daily chart rendering (views.js:751-781)
export function renderDailyChart(periodDays) {
  const numDays = periodDays ? Math.min(periodDays, 90) : 30;
  const days = [], data = [];
  
  for (let i = numDays - 1; i >= 0; i--) {
    const d = new Date();
    d.setDate(d.getDate() - i);
    const ds = d2.toISOString().split('T')[0];
    
    const secs = state.eventos
      .filter(e => e.data === ds && e.status === 'estudei')
      .reduce((s, e) => s + (e.tempoAcumulado || 0), 0);
    
    data.push(Math.round(secs / 60)); // Convert to minutes
  }
  
  new Chart(ctx, {
    type: 'bar',
    data: { labels: days, datasets: [{ label: 'Minutos', data }] }
  });
}
Features:
  • X-axis: Date labels (dd/mm format)
  • Y-axis: Minutes studied
  • Green bars with 6px border radius
  • Responsive to container size

Time by Discipline Chart

Doughnut chart showing time distribution across subjects:
// Discipline chart rendering (views.js:783-809)
export function renderDiscChart(periodDays) {
  const discTime = {};
  
  evts.forEach(e => { 
    discTime[e.discId] = (discTime[e.discId] || 0) + e.tempoAcumulado; 
  });
  
  const labels = [], data = [], colors = [];
  Object.entries(discTime).forEach(([id, secs]) => {
    const d = getDisc(id);
    labels.push(d ? d.disc.nome : id);
    data.push(Math.round(secs / 60));
    colors.push(d ? (d.disc.cor || '#10b981') : '#94a3b8');
  });
  
  new Chart(ctx, {
    type: 'doughnut',
    data: { labels, datasets: [{ data, backgroundColor: colors }] }
  });
}
Features:
  • Uses discipline colors from Editais
  • Shows legend on the right
  • Displays minutes per subject
  • Empty state message if no data

Habit Summary

Lists all habit types with counts for the selected period:
// Habit summary (views.js:811-826)
export function renderHabitSummary(periodDays) {
  const cutoffStr = periodDays ? cutoffDateStr(periodDays) : null;
  
  return HABIT_TYPES.map(h => {
    const recent = cutoffStr
      ? (state.habitos[h.key] || []).filter(r => r.data >= cutoffStr)
      : (state.habitos[h.key] || []);
    
    const count = h.key === 'questoes' 
      ? recent.reduce((s, q) => s + (q.quantidade || 1), 0) 
      : recent.length;
    
    return `<div>${h.icon} ${h.label}: ${count}</div>`;
  }).join('');
}
Habit Types:
  • ❓ Questões (Questions)
  • 🔄 Revisão (Revision)
  • 📝 Simulado (Practice Exam)
  • 📖 Leitura (Reading)
  • 📰 Informativos (News Briefs)
  • ✍️ Discursiva (Essay Practice)
  • 🎬 Vídeoaula (Video Lessons)

Discipline Progress

Progress bars showing completion percentage for each subject:
// Progress calculation (views.js:828-848)
export function renderDiscProgress() {
  const discs = getAllDisciplinas();
  
  return discs.slice(0, 8).map(({ disc, edital }) => {
    const total = disc.assuntos.length;
    const done = disc.assuntos.filter(a => a.concluido).length;
    const pct = total > 0 ? Math.round(done / total * 100) : 0;
    
    return `
      <div>
        <div>${disc.icone} ${disc.nome}</div>
        <div>${done}/${total}</div>
        <div class="progress">
          <div class="progress-bar" style="width:${pct}%;background:${disc.cor}"></div>
        </div>
      </div>
    `;
  }).join('');
}
Display:
  • Shows up to 8 disciplines
  • Icon and name from Editais
  • Fraction completed (e.g., “12/45”)
  • Colored progress bar matching discipline color

Using the Dashboard

1

Select Time Period

Click one of the period tabs (7d, 30d, 3m, Total) to filter all data. The dashboard re-renders with updated calculations.
2

Review Key Metrics

Check the four stat cards at the top to see overall performance summary.
3

Analyze Daily Trends

Examine the bar chart to identify:
  • Days with peak productivity
  • Gaps in your study schedule
  • Weekly patterns (weekdays vs weekends)
4

Balance Subject Time

Use the doughnut chart to ensure you’re not over-focusing on one discipline while neglecting others.
5

Track Habit Compliance

Review the habit summary to verify you’re completing your daily targets for questions, reading, etc.
6

Monitor Syllabus Progress

Check discipline progress bars to see which subjects need more attention.

Advanced Analytics

Performance Stats

Calculates question performance metrics:
// Performance calculation (logic.js:304-318)
export function getPerformanceStats() {
  let questionsTotal = 0;
  let questionsCorrect = 0;
  let questionsWrong = 0;

  state.eventos.forEach(ev => {
    if (ev.status === 'estudei' && ev.sessao && ev.sessao.questoes) {
      questionsTotal += ev.sessao.questoes.total || 0;
      questionsCorrect += ev.sessao.questoes.acertos || 0;
      questionsWrong += ev.sessao.questoes.erros || 0;
    }
  });

  return { questionsTotal, questionsCorrect, questionsWrong };
}

Pages Read Stats

// Pages calculation (logic.js:320-328)
export function getPagesReadStats() {
  let pagesTotal = 0;
  state.eventos.forEach(ev => {
    if (ev.status === 'estudei' && ev.sessao && ev.sessao.paginas && ev.sessao.paginas.total) {
      pagesTotal += ev.sessao.paginas.total;
    }
  });
  return pagesTotal;
}

Syllabus Progress

// Syllabus progress (logic.js:330-342)
export function getSyllabusProgress() {
  let totalAulas = 0;
  let aulasEstudadas = 0;

  state.editais.forEach(ed => {
    ed.disciplinas.forEach(d => {
      totalAulas += d.aulas ? d.aulas.length : 0;
      aulasEstudadas += d.aulas ? d.aulas.filter(a => a.estudada).length : 0;
    });
  });

  return { totalAssuntos: totalAulas, totalConcluidos: aulasEstudadas };
}
Dashboard charts use the Chart.js library. Ensure the library is loaded before rendering the dashboard to avoid errors.

Performance Optimization

Chart Cleanup

Old chart instances are destroyed before creating new ones:
// Chart cleanup (views.js:754, 786)
if (_chartDaily) { _chartDaily.destroy(); _chartDaily = null; }
if (_chartDisc) { _chartDisc.destroy(); _chartDisc = null; }

Data Caching

Filtered events are calculated once and reused:
const filteredEvts = cutoffStr
  ? state.eventos.filter(e => e.status === 'estudei' && e.data && e.data >= cutoffStr)
  : state.eventos.filter(e => e.status === 'estudei');

const totalSecs = filteredEvts.reduce((s, e) => s + (e.tempoAcumulado || 0), 0);
// ... use filteredEvts for other calculations

Empty States

Graceful handling when no data exists:
if (data.length === 0) {
  ctx.parentElement.innerHTML = `
    <div class="empty-state">
      <div class="icon">📈</div>
      <p>Sem dados no período selecionado</p>
    </div>
  `;
  return;
}

Best Practices

Check the dashboard weekly to identify trends and adjust your study plan. Look for declining performance or unbalanced subject distribution.
Use the 7-day view to set achievable weekly goals. Gradually increase targets as you build consistency.
Toggle between time periods to see if you’re improving month-over-month. Compare 30d vs 90d for long-term trends.
Don’t optimize for just one metric. Balance time studied, questions answered, and syllabus coverage.

Export and Backup

While not built into the dashboard UI, you can export data programmatically:
// Export study data
const exportData = {
  eventos: state.eventos.filter(e => e.status === 'estudei'),
  habitos: state.habitos,
  timestamp: new Date().toISOString()
};

const json = JSON.stringify(exportData, null, 2);
const blob = new Blob([json], { type: 'application/json' });
// Download blob as file

Build docs developers (and LLMs) love