-
Notifications
You must be signed in to change notification settings - Fork 843
feat: add documents and authors statistics #10815
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
evyncke
wants to merge
207
commits into
ietf-tools:main
Choose a base branch
from
evyncke:feat-doc-stats
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
207 commits
Select commit
Hold shift + click to select a range
ef05fce
Draft for meeting registrations
evyncke a0fd930
Add totals, + nicer JS code
evyncke 7dfa8d4
Coherent URL parameters
evyncke 25c79a5
Handle error case when per-continent stats is requested
evyncke 557291f
Remove redundant code
evyncke ebc4bdc
Dynamic get the current IETF meeting
evyncke 2e55643
Display %-age when hovering
evyncke ac4f28e
Add test for meeting statistics
evyncke 62a6784
Add test
evyncke 14780b9
Add statistics per affiliation
evyncke 90aa3ac
More code coverage for test
evyncke dd64825
Merge branch 'main' into feat-statistics
evyncke b159b48
Nicer canonical affiliation
evyncke b0d2842
Allow navigation by buttons
evyncke fa4354f
Merge branch 'main' into feat-statistics
evyncke e41a545
Also add participants count in the legend
evyncke 19233d4
Add timeline over meetings (total and per country)
evyncke c294660
Merge branch 'main' into feat-statistics
evyncke 94e00ac
Default index refers to current meeting stats by number
evyncke 8a989e0
Remove unused JS code
evyncke 0067933
Add test coverage for timeline statistics
evyncke f803986
No need to import test coverage
evyncke c8adc61
Use stacked lines of onsite/remote when displaying the total timeline
evyncke beb2424
fix a comment
evyncke 9fb3ab7
Add timeline for affiliation
evyncke 582a9b7
Expanding the test coverage to affiliation timeline
evyncke 46c0901
Remove unused botocore (unsure how it was added though)
evyncke 76f9b6a
Remove unused package
evyncke eeb28c6
Code clean-up, add pan & zoom on timelines
evyncke 1d1c209
Fix button type
evyncke 27e77d2
Very first draft
evyncke 7e964e9
Use pub_date() also for streams stats
evyncke 9018d68
Don't fill the graphics
evyncke 8585901
Merge remote-tracking branch 'upstream/main' into feat-doc-stats
evyncke 7f7c12f
Also display active 'All' button
evyncke 9d6350c
Consistent color scheme for country/affiliation
evyncke 7a1272f
Merge remote-tracking branch 'upstream/main' into feat-doc-stats
evyncke 4827450
No need for autocolor anymore
evyncke b8adc9c
More explanations about chart.js
evyncke 66ba85b
More colors to reduce collision
evyncke d2df794
Split authors/documents stats
evyncke f8d3e4d
Complete separation of docs & authors stats
evyncke acf5bb6
Polishing statistics on authors
evyncke c26b64c
More explanations about shown data
evyncke d851e59
Add RFC category and draft intended status
evyncke e942fdc
Support displaying WG stats
evyncke 3b3989d
Update since autocolor from chart.js was removed
evyncke 11d2b06
Fix typo
evyncke f4cc0c5
Tests for documents timelines
evyncke 9250bea
Authors statistics tests completed
evyncke a9f33a7
Merge branch 'main' into feat-doc-stats
evyncke 2836321
Require Alt for all pan/scroll
evyncke e510419
Working draft for totals in addition to timeline
evyncke 533f35e
JS for the total statistics
evyncke e87de05
Hide clicked on bar and rescale
evyncke 9f9b6a1
Display all bar legends even if many of them
evyncke 0ebe055
Add AffiliationMainName model + initial content
evyncke 32aff47
AffiliationMainName migration
evyncke 435cce6
Pass the "top-n" value as a query parameter
evyncke 7339d41
Less debug logging
evyncke 98bc837
More affiliations clean-up/canonicalizations
evyncke 8530e34
Force the use of Alt for all mouse moves
evyncke 961c5de
Only use the affiliation aliases from utils (and the DB)
evyncke 5f58319
No need for ordering in AffiliationMainName and more country aliases
evyncke 163db7e
Only use aliases (country & affiliation) in utils and no more hardcoded
evyncke cb96f26
Avoid overlapping labels
evyncke 5eb117c
Handle top_n for documents timeline
evyncke 6346066
ID field is automatic
evyncke 70f02df
Add Alias Main Name for API
evyncke 46eab55
Create the id field at migration time, remove the main_name is unique
evyncke 6669c24
Fix the migration (verbose_name typo and unique=True)
evyncke e9fa928
Update tests for the country/affiliation aliases
evyncke 53136b2
Use & rather than "&"
evyncke 770948a
URL contains plural meetings for the timeline graphics
evyncke 9adc330
Add top_n for meetings timeline
evyncke 41f8596
Test the authors total graphics
evyncke 15276c8
Display full country name in per meeting stat
evyncke cd48b92
Use top-n rather than minimum participants in per meeting stats
evyncke b6bf986
Fix affiliation factory
evyncke 1c9ec97
Merge branch 'main' into feat-doc-stats
evyncke 6763893
The other bin was never computed
evyncke cdc3044
Add total bars for documents
evyncke bc9b69f
Draft test for total documents
evyncke 04f9cae
More tests for documents totals
evyncke 5672ce2
Remove debugging console.log()
evyncke 7b07e5d
Use all documents even in dev mode
evyncke e09c6c7
Allow changing the number of categories to display
evyncke 1cfb6ca
Fix HTML label
evyncke ebcbfa4
Merge branch 'main' into feat-doc-stats
evyncke 98b3480
Failed (?) attempt to use a cache
evyncke 8213881
Wider input field for top_n
evyncke eb36f78
Remove cache debugging
evyncke faa1d3d
Merge branch 'main' into feat-doc-stats
evyncke a1fb7c6
Forgot one alias to remove
evyncke 0c16703
Add message to assertTrue()
evyncke ab2e237
Remove case folding code from the affiliation aliases
evyncke 471a3d9
No need to import collection
evyncke 8f2fced
Merge branch 'main' into feat-doc-stats
evyncke ddc8881
Merge branch 'main' into feat-doc-stats
evyncke ef5cba4
Merge branch 'main' into feat-doc-stats
evyncke f3e28fa
fix: country factory does not use canonical names
evyncke 817afff
fix typo in code
evyncke 37871da
fix: another country name fix for the factory
evyncke 0e7d8f6
Merge branch 'main' into feat-doc-stats
evyncke c0c3f1b
Split the large views.py in smaller views_foo.py
evyncke 5f6c4f8
Add some guidance on the chart
evyncke aa4108b
Fixing Cabo Verde canonical country name
evyncke a4d973b
Move the reviews stats in views_reviews.py
evyncke 3fabad6
fix templates to use views_reviews
evyncke d8b1228
Merge branch 'main' into feat-doc-stats
evyncke 9eeec47
Merge branch 'main' into feat-doc-stats
evyncke 1c484b1
Remove unused parameters
evyncke 3866a19
After a co-pilot review ;-)
evyncke 1ea13f6
Merge branch 'main' into feat-doc-stats
evyncke 3d2ea96
Refactoring with co-pilot
evyncke 470f0fd
Merge remote-tracking branch 'refs/remotes/origin/feat-doc-stats' int…
evyncke 0c9440c
More typing
evyncke cf0a2d2
More co-pilot reviews
evyncke d552f75
Remove redundant line
evyncke e3f734d
Add types for functions parameters
evyncke ffd1cd6
Add docstrings
evyncke 6b24aee
Merge branch 'main' into feat-doc-stats
evyncke 5cbe725
Revert .gitignore change from 163db7e04f
evyncke 112ac0f
Misc fixes after Jennifer's review (more to come)
evyncke 4a589ed
Fix typo in Migration() to match the fix in models.py
evyncke 2ba9375
Limit the choice of top_n to a pre-defined lists of values
evyncke eb7aa93
More readble comments
evyncke ecf9079
Use elif construct
evyncke 7f08570
New URLs with a total suffix
evyncke 277d7fd
Canonicalize British Virgin Islands
evyncke 4a5fdf5
Ensure only 'rfc' and 'draft' doc_type are fetched
evyncke ff35f78
Merge branch 'main' into feat-doc-stats
evyncke 7680e9e
Ensure that all documents are limited to rfc and draft typename
evyncke c20c73e
Fix for issue#11123
evyncke 5171fa3
use document__group__type_id=wg rather than name draft-ietf-*
evyncke bfd0f50
Canonicalise Pitcairn Island
evyncke 04d7b42
Fix English grammar
evyncke 770cce7
Minor code clean-up
evyncke 0e574c8
Merge branch 'main' into feat-doc-stats
evyncke e6c11e0
More affiliation alises
evyncke e0f5326
Explain how authors are counted
evyncke dc192af
Use RfcAuthor for RFC rather than DocumentAuthor
evyncke 68e20a6
Make ruff happy
evyncke c98f339
More changes in order to use RfcAuthor
evyncke 5944234
Make ruff happier
evyncke e07cb6e
Merge branch 'main' into feat-doc-stats
evyncke 7e304dc
Make ruff happier for more files
evyncke bb10e9f
Tame the UI to avoid per country stats about RFC to bypass RfcAuthor …
evyncke 1165661
Nicer identation
evyncke 0f7804c
More robust tests
evyncke 2e42be1
Select faster default statistics
evyncke 9f9fcac
Refer to faster statistics
evyncke f893689
Temporary fix for test_bash() test that appears to be TZ-sensitive
evyncke 1026ce7
Revert the temporary fix
evyncke 19fc849
Merge branch 'main' into feat-doc-stats
evyncke e35868a
Merge branch 'main' into feat-doc-stats
evyncke 7257a26
Merge branch 'main' into feat-doc-stats
evyncke d662a86
Use 'registration types' rather than 'total' for meetings
evyncke 8f8256f
And also update the test URL...
evyncke 03d0e6d
Better template for reg_type meetings timeline
evyncke aed7bbb
Slighlty better templace for registration types timeiine
evyncke b492d6b
Add CSV download for per meeting statistics
evyncke 7564dfb
Add CSV download for meetings timeline
evyncke 1cfbc6c
Ruff for long lines...
evyncke 57cc0cf
Merge branch 'main' into feat-doc-stats
evyncke c9c84d8
Ensure that "IAB" is not canonicalised in to "I"
evyncke 5d01907
add stats/usedaffiliations to display all affiliation canonicalisatio…
evyncke 759f72a
Stats static JS files are now prefixed by stats_ to avoid overwriting...
evyncke f2a7777
Merge from current main branch
evyncke 92f4ce9
Merging to main branch - bis
evyncke fe03f7b
Strict JS correctness
evyncke 5266af9
Do not import unused module
evyncke bc198fd
Add test coverage for used affiliations
evyncke edc1a3b
Add list of affiliations/countries in the main menu for LLC staff
evyncke c3c8aeb
Address the "correctness" items from RjS's Claude review
evyncke 70dc628
Removed unused import
evyncke 71709c1
Improve queries and caching performances
evyncke 90f762b
Consistent top_n checks
evyncke 5ae85ee
performance improvement per RjS' review
evyncke 83f5822
Display 'other' line only if there is date
evyncke da61f44
Redirect some old stats/meeting URL for consistency
evyncke e6506cf
Fixing RjS' review of the test
evyncke 8295d1b
Fixing the nits from RjS' review
evyncke d23beae
Reflect models.py changes
evyncke 29a1567
More update after models.py
evyncke 4bb14b6
Fix secr/telechat intermittent failure
evyncke b75d437
Fix secr/telechat intermittent failure using SPC rather than TAB
evyncke 5efe5cf
Merge branch 'ietf-tools:main' into feat-doc-stats
evyncke 4613204
Use helper functions to avoid code duplication
evyncke f9fd7be
Add types to same function calls
evyncke b09b53a
Display only valid meeting numbers in the choice
evyncke ed1b4b1
Error message rather than top_n clamping
evyncke 8b53bbb
Add more data in the cache
evyncke d5cf863
Only LLC staff can view used affiliations and known countries
evyncke 373bb44
Minor fixes
evyncke 6b57878
Query performance improvment
evyncke 404f460
Fix typos in aliases
evyncke 7a3a026
Fix MyPy very strict test for no-redef
evyncke 2f6f125
fix get_aliased_affiliations() issue with white spaces, add new alias…
evyncke a1888e7
Longuest-prefix first in affiliation main names
evyncke 3142426
Nits in templates
evyncke 6da988a
Use names rather than slugs for publication status
evyncke 5ff4e5f
Fix tests by using names rather than slug in publication status
evyncke cc610a1
Add URL redirects to 'legacy' stats URLs
evyncke 4798bb8
Minor tests improvements by using assertEqual rather than assertTrue(…
evyncke 7b9b41e
Remove duplicates of {% origin %}
evyncke 21687a7
Nit: fixing a comment
evyncke File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| // Copyright The IETF Trust 2026, All Rights Reserved | ||
| import Chart from 'chart.js/auto' | ||
| import zoomPlugin from 'chartjs-plugin-zoom' | ||
|
|
||
| document.addEventListener('DOMContentLoaded', () => { | ||
| Chart.register(zoomPlugin) // enable the zoom plugin | ||
|
|
||
| // ── Safely parse JSON data injected from Django view ── | ||
| const chartData = JSON.parse(document.getElementById('chart_data').textContent) ; | ||
| const objects = JSON.parse(document.getElementById('objects').textContent) ; | ||
| const stackedLines = false ; | ||
|
|
||
| function displayChart (id, data) { | ||
| const ctx = document.getElementById(id).getContext('2d') ; | ||
| return new Chart(ctx, { | ||
| type: 'line', | ||
| data: data, | ||
| options: { | ||
| responsive: true, | ||
| scales: { | ||
| y: { | ||
| stacked: stackedLines, | ||
| }, | ||
| x: { | ||
| title: { | ||
| display: true, | ||
| text: 'Year', | ||
| }, | ||
| }, | ||
| }, | ||
| plugins: { | ||
| legend: { | ||
| position: 'bottom', | ||
| labels: { | ||
| usePointStyle: true, | ||
| padding: 15, | ||
| font: { size: 12 }, | ||
| }, | ||
| }, | ||
| tooltip: { | ||
| backgroundColor: 'rgba(0,0,0,0.8)', | ||
| titleFont: { size: 14 }, | ||
| bodyFont: { size: 13 }, | ||
| callbacks: { | ||
| title: function(items) { | ||
| return `${items[0].label}`; | ||
| }, | ||
| label: function(context) { | ||
| return ` ${context.dataset.label}: ${context.parsed.y} ${objects}`; | ||
| } | ||
| } | ||
| }, | ||
| zoom: { | ||
| zoom: { | ||
| wheel: { | ||
| enabled: true, | ||
| modifierKey: 'alt' // Alt + scroll wheel to zoom | ||
| }, // scroll to zoom | ||
| pinch: { | ||
| enabled: true | ||
| }, // pinch on mobile | ||
| drag: { // drag to select range | ||
| enabled: true, | ||
| modifierKey: 'alt' | ||
| }, | ||
| mode: 'xy', // zoom X-axis and Y-axis | ||
| }, | ||
| pan: { | ||
| enabled: true, | ||
| modifierKey: 'alt', | ||
| mode: 'xy', // pan X-axis and Y-axis | ||
| }, | ||
| }, | ||
| } | ||
| } | ||
| }) | ||
| } | ||
|
|
||
| const documentsChart = displayChart('documentsChart', chartData) ; | ||
|
|
||
| document.addEventListener('keydown', (event) => { | ||
| if (event.key === 'Escape') { | ||
| documentsChart.resetZoom() | ||
| } | ||
| }) | ||
| document.getElementById('resetButton').addEventListener('click', () => { | ||
| documentsChart.resetZoom() | ||
| }) | ||
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| // Copyright The IETF Trust 2026, All Rights Reserved | ||
| import Chart from 'chart.js/auto' | ||
| import zoomPlugin from 'chartjs-plugin-zoom' | ||
|
|
||
| document.addEventListener('DOMContentLoaded', () => { | ||
| Chart.register(zoomPlugin) // enable the zoom plugin | ||
| const hidden = new Set(); // track suppressed categories | ||
|
|
||
| // ── Safely parse JSON data injected from Django view ── | ||
| const chartData = JSON.parse(document.getElementById('chart_data').textContent) ; | ||
| const objects = JSON.parse(document.getElementById('objects').textContent) ; | ||
|
|
||
| function refreshChart(chart) { | ||
| // On first call, snapshot the original data onto the chart instance itself | ||
| if (!chart._originalData) { | ||
| chart._originalData = { | ||
| labels: [...chart.data.labels], | ||
| values: [...chart.data.datasets[0].data], | ||
| colors: Array.isArray(chart.data.datasets[0].backgroundColor) | ||
| ? [...chart.data.datasets[0].backgroundColor] | ||
| : chart.data.labels.map(() => chart.data.datasets[0].backgroundColor), | ||
| }; | ||
| } | ||
|
|
||
| const original = chart._originalData; | ||
| const labels = [], values = [], colors = []; | ||
|
|
||
| original.labels.forEach((lbl, i) => { | ||
| if (!hidden.has(lbl)) { | ||
| labels.push(lbl); | ||
| values.push(original.values[i]); | ||
| colors.push(original.colors[i]); | ||
| } | ||
| }); | ||
|
|
||
| chart.data.labels = labels; | ||
| chart.data.datasets[0].data = values; | ||
| chart.data.datasets[0].backgroundColor = colors; | ||
| chart.update(); | ||
| } | ||
|
|
||
| function displayChart (id, data) { | ||
| const ctx = document.getElementById(id).getContext('2d') ; | ||
| let chart = new Chart(ctx, { | ||
| type: 'bar', | ||
| data: data, | ||
| options: { | ||
| indexAxis: 'y', | ||
| onClick: (event, elements) => { | ||
| if (elements.length > 0) { | ||
| const idx = elements[0].index; | ||
| const label = chart.data.labels[idx]; | ||
| hidden.add(label); | ||
| refreshChart(chart); | ||
| } | ||
| }, | ||
| responsive: true, | ||
| scales: { | ||
| x: { | ||
| title: { | ||
| display: true, | ||
| text: 'Number of ' + objects, | ||
| }, | ||
| }, | ||
| y: { | ||
| ticks: { | ||
| autoSkip: false, // Display all labels even if messy... | ||
| } | ||
| }, | ||
| }, | ||
| plugins: { | ||
| legend: { | ||
| display: false, | ||
| }, | ||
| tooltip: { | ||
| backgroundColor: 'rgba(0,0,0,0.8)', | ||
| titleFont: { size: 14 }, | ||
| bodyFont: { size: 13 }, | ||
| callbacks: { | ||
| title: function(items) { | ||
| return `${items[0].label}`; | ||
| }, | ||
| label: function(context) { | ||
| return `${context.formattedValue} ${objects}`; | ||
| } | ||
| } | ||
| }, | ||
| zoom: { | ||
| zoom: { | ||
| wheel: { | ||
| enabled: true, | ||
| modifierKey: 'alt' // Alt + scroll wheel to zoom | ||
| }, // scroll to zoom | ||
| pinch: { | ||
| enabled: true | ||
|
|
||
| }, // pinch on mobile | ||
| drag: { // drag to select range | ||
| enabled: true, | ||
| modifierKey: 'alt' | ||
| }, | ||
| mode: 'xy', // zoom X-axis and Y-axis | ||
| }, | ||
| pan: { | ||
| enabled: true, | ||
| modifierKey: 'alt', | ||
| mode: 'xy', // pan X-axis and Y-axis | ||
| }, | ||
| }, | ||
| } | ||
| } | ||
| }) ; | ||
| return chart; | ||
| } | ||
|
|
||
| displayChart('documentsChart', chartData) ; | ||
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.