66Metrics for {{ project }}
77{% endblock %}
88
9+ {% block local_js_top %}
10+ < script src ="{% static 'd3/d3.v3.min.js' %} "> </ script >
11+ < script src ="{% static 'd3/d3.tip.v0.6.3.js' %} "> </ script >
12+ {% endblock %}
13+
14+ {% block local_css %}
15+ < style >
16+ # views-chart .axis path ,
17+ # views-chart .axis line {
18+ fill : none;
19+ stroke : # 333 ;
20+ shape-rendering : crispEdges;
21+ }
22+ # views-chart .axis text {
23+ font-size : 12px ;
24+ }
25+ # views-chart .line {
26+ fill : none;
27+ stroke : steelblue;
28+ stroke-width : 2px ;
29+ }
30+ # views-chart .dot {
31+ fill : steelblue;
32+ stroke : # fff ;
33+ stroke-width : 1.5px ;
34+ }
35+ .d3-tip {
36+ line-height : 1 ;
37+ padding : 8px ;
38+ background : rgba (0 , 0 , 0 , 0.8 );
39+ color : # fff ;
40+ border-radius : 4px ;
41+ font-size : 13px ;
42+ }
43+ </ style >
44+ {% endblock %}
45+
946{% block content %}
1047< div class ="container ">
1148 < h1 > Metrics</ h1 >
1249 < p class ="text-muted "> {{ project.title }} (v{{ project.version }})</ p >
1350 < hr >
1451
15- < div class ="row ">
16- < div class ="col-md-6 ">
17- < div class ="card text-center mb-4 ">
52+ < div class ="row justify-content-center ">
53+ < div class ="col-md-8 col-lg- 6 ">
54+ < div id =" views-card " class ="card text-center mb-4 d-flex justify-content-center " style =" min-height: 250px; ">
1855 < h5 class ="card-header "> Unique Registered Project Views</ h5 >
19- < div class ="card-body ">
56+ < div class ="card-body d-flex flex-column justify-content-center ">
2057 < div class ="d-flex justify-content-around mb-2 ">
2158 < div >
2259 < h3 class ="mb-0 "> {{ project_views_count }}</ h3 >
@@ -31,6 +68,88 @@ <h3 class="mb-0">{{ all_versions_views_count }}</h3>
3168 </ div >
3269 </ div >
3370 </ div >
71+ {% if views_over_time %}
72+ < div class ="col-md-8 col-lg-6 ">
73+ < div id ="views-chart " class ="mb-4 d-flex justify-content-center "> </ div >
74+ < script >
75+ ( function ( ) {
76+ var data = { { chart_data| safe } } ;
77+ var parseDate = d3 . time . format ( '%b %Y' ) . parse ;
78+ data . forEach ( function ( d ) {
79+ d . date = parseDate ( d . month ) ;
80+ } ) ;
81+
82+ var cardHeight = document . getElementById ( 'views-card' ) . offsetHeight ;
83+ var margin = { top : 20 , right : 20 , bottom : 50 , left : 50 } ,
84+ width = document . getElementById ( 'views-chart' ) . offsetWidth - margin . left - margin . right ,
85+ height = cardHeight - margin . top - margin . bottom ;
86+
87+ var x = d3 . time . scale ( ) . range ( [ 0 , width ] ) ;
88+ var y = d3 . scale . linear ( ) . range ( [ height , 0 ] ) ;
89+
90+ var xAxis = d3 . svg . axis ( ) . scale ( x ) . orient ( 'bottom' )
91+ . tickFormat ( d3 . time . format ( '%b %Y' ) ) ;
92+ var yAxis = d3 . svg . axis ( ) . scale ( y ) . orient ( 'left' )
93+ . ticks ( 6 ) . tickFormat ( d3 . format ( 'd' ) ) ;
94+
95+ var line = d3 . svg . line ( )
96+ . x ( function ( d ) { return x ( d . date ) ; } )
97+ . y ( function ( d ) { return y ( d . count ) ; } ) ;
98+
99+ var tip = d3 . tip ( )
100+ . attr ( 'class' , 'd3-tip' )
101+ . offset ( [ - 10 , 0 ] )
102+ . html ( function ( d ) {
103+ return '<strong>' + d . month + '</strong>: ' + d . count + ' viewers' ;
104+ } ) ;
105+
106+ var svg = d3 . select ( '#views-chart' ) . append ( 'svg' )
107+ . attr ( 'width' , width + margin . left + margin . right )
108+ . attr ( 'height' , height + margin . top + margin . bottom )
109+ . append ( 'g' )
110+ . attr ( 'transform' , 'translate(' + margin . left + ',' + margin . top + ')' ) ;
111+
112+ svg . call ( tip ) ;
113+
114+ x . domain ( d3 . extent ( data , function ( d ) { return d . date ; } ) ) ;
115+ y . domain ( [ 0 , d3 . max ( data , function ( d ) { return d . count ; } ) ] ) ;
116+
117+ svg . append ( 'g' )
118+ . attr ( 'class' , 'x axis' )
119+ . attr ( 'transform' , 'translate(0,' + height + ')' )
120+ . call ( xAxis )
121+ . selectAll ( 'text' )
122+ . attr ( 'transform' , 'rotate(-45)' )
123+ . style ( 'text-anchor' , 'end' ) ;
124+
125+ svg . append ( 'g' )
126+ . attr ( 'class' , 'y axis' )
127+ . call ( yAxis )
128+ . append ( 'text' )
129+ . attr ( 'transform' , 'rotate(-90)' )
130+ . attr ( 'x' , - height / 2 )
131+ . attr ( 'y' , - margin . left + 14 )
132+ . style ( 'text-anchor' , 'middle' )
133+ . text ( 'Unique Viewers' ) ;
134+
135+ svg . append ( 'path' )
136+ . datum ( data )
137+ . attr ( 'class' , 'line' )
138+ . attr ( 'd' , line ) ;
139+
140+ svg . selectAll ( '.dot' )
141+ . data ( data )
142+ . enter ( ) . append ( 'circle' )
143+ . attr ( 'class' , 'dot' )
144+ . attr ( 'cx' , function ( d ) { return x ( d . date ) ; } )
145+ . attr ( 'cy' , function ( d ) { return y ( d . count ) ; } )
146+ . attr ( 'r' , 4 )
147+ . on ( 'mouseover' , tip . show )
148+ . on ( 'mouseout' , tip . hide ) ;
149+ } ) ( ) ;
150+ </ script >
151+ </ div >
152+ {% endif %}
34153 </ div >
35154
36155 {% if views_by_version|length > 1 %}
0 commit comments