@@ -338,14 +338,10 @@ nv.addGraph(function() {
338338 return chart;
339339});
340340
341-
342341// ////////////////////////////////////
343342// Submissions over time
344- // stacked graph of correct, runtime-error, wrong-answer, compiler-error, timelimit, etc
345- // x-axis is contest time
346- // y axis is # of submissions
347343
348- var submission_stats = [
344+ const submission_stats = [
349345 {% for result in [' correct' , ' wrong-answer' , ' timelimit' , ' run-error' , ' compiler-error' , ' no-output' ] %}
350346 {
351347 key: " {{result}}" ,
@@ -354,8 +350,8 @@ var submission_stats = [
354350 },
355351 {% endfor %}
356352];
357-
358353const contest_start_time = {{ current_contest .starttime }};
354+ const contest_duration_seconds = {{ (current_contest .endtime - current_contest .starttime ) | round(0 , ' ceil' ) }};
359355const submissions = [
360356 {% for submission in submissions %}
361357 {
@@ -364,98 +360,7 @@ const submissions = [
364360 }{{ loop .last ? ' ' : ' ,' }}
365361 {% endfor %}
366362];
367-
368- const min_bucket_count = 30 ;
369- const max_bucket_count = 301 ;
370- const units = [
371- {' name' : ' seconds' , ' convert' : 1 , ' step' : 60 },
372- {' name' : ' minutes' , ' convert' : 60 , ' step' : 15 },
373- {' name' : ' hours' , ' convert' : 60 * 60 , ' step' : 6 },
374- {' name' : ' days' , ' convert' : 60 * 60 * 24 , ' step' : 7 },
375- {' name' : ' weeks' , ' convert' : 60 * 60 * 24 * 7 , ' step' : 1 },
376- {' name' : ' years' , ' convert' : 60 * 60 * 24 * 365 , ' step' : 1 }
377- ];
378- let unit = units[0 ];
379-
380- let contest_duration = {{ (current_contest .endtime - current_contest .starttime ) | round(0 , ' ceil' ) }};
381- for (let u of units) {
382- const new_duration = Math .ceil (contest_duration / u .convert );
383- if (new_duration > min_bucket_count) {
384- unit = u;
385- } else {
386- break ;
387- }
388- }
389- contest_duration = Math .ceil (contest_duration / unit .convert );
390- const bucket_count = Math .min (contest_duration + 1 , max_bucket_count);
391- // Make sure buckets have whole unit
392- const seconds_per_bucket = Math .ceil (contest_duration / (bucket_count - 1 )) * unit .convert ;
393-
394- submission_stats .forEach (stat => {
395- stat .values = Array .from ({ length: bucket_count }, (_ , i ) => [i * seconds_per_bucket / unit .convert , 0 ]);
396- });
397-
398- const statMap = submission_stats .reduce ((map , stat ) => {
399- map[stat .key ] = stat;
400- return map;
401- }, {});
402-
403- submissions .forEach (submission => {
404- const submission_bucket = Math .floor ((submission .submittime - contest_start_time) / seconds_per_bucket);
405- const stat = statMap[submission .result ];
406- if (stat && submission_bucket >= 0 && submission_bucket < bucket_count) {
407- stat .values [submission_bucket][1 ]++ ;
408- }
409- });
410-
411- let max_submissions_per_bucket = 1
412- for (let bucket = 0 ; bucket < bucket_count; bucket++ ) {
413- let sum = 0 ;
414- submission_stats .forEach (stat => {
415- sum += stat .values [bucket][1 ];
416- });
417- max_submissions_per_bucket = Math .max (max_submissions_per_bucket, sum);
418- }
419-
420- // Pick a nice round tickDelta and tickValues based on the step size of units.
421- // We want whole values in the unit, and the ticks MUST match a corresponding bucket otherwise the resulting
422- // coordinate will be NaN.
423- const convert_factor = seconds_per_bucket / unit .convert ;
424- const maxTicks = Math .min (bucket_count, contest_duration / unit .step , min_bucket_count)
425- const tickDelta = convert_factor * Math .ceil (contest_duration / (maxTicks * convert_factor));
426- const ticks = Math .floor (contest_duration / tickDelta) + 1 ;
427- const tickValues = Array .from ({ length: ticks }, (_ , i ) => i * tickDelta);
428-
429- nv .addGraph (function () {
430- var chart = nv .models .multiBarChart ()
431- // .margin({left: 100}) //Adjust chart margins to give the x-axis some breathing room.
432- // .useInteractiveGuideline(true) //We want nice looking tooltips and a guideline!
433- // .transitionDuration(350) //how fast do you want the lines to transition?
434- // .showLegend(true) //Show the legend, allowing users to turn on/off line series.
435- .showControls (false )
436- .stacked (true )
437- .x (function (d ) { return d[0 ] }) // We can modify the data accessor functions...
438- .y (function (d ) { return d[1 ] }) // ...in case your data is formatted differently.
439- .showYAxis (true ) // Show the y-axis
440- .showXAxis (true ) // Show the x-axis
441- .reduceXTicks (false )
442- ;
443- chart .xAxis // Chart x-axis settings
444- .axisLabel (` Contest Time (${ unit .name } )` )
445- .ticks (tickValues .length )
446- .tickValues (tickValues)
447- .tickFormat (d3 .format (' d' ));
448- chart .yAxis // Chart y-axis settings
449- .axisLabel (' Total Submissions' )
450- .tickFormat (d3 .format (' d' ));
451-
452- d3 .select (' #graph_submissions svg' )
453- .datum (submission_stats)
454- .call (chart);
455- nv .utils .windowResize (chart .update );
456- return chart;
457- });
458-
363+ createSubmissionGraph (submission_stats, contest_start_time, contest_duration_seconds, submissions);
459364
460365</script >
461366{% include ' jury/analysis/download_graphs.html.twig' %}
0 commit comments