PageSourceSearch

https://guiming.github.io/GeovizVGI/js/d3baryear.js

js guiming.github.io collected 2026-10-03 09:16:06 UTC 15,314 bytes, 393 lines download raw bytes

1// Source: http://bl.ocks.org/godds/ec089a2cf3e06a2cd5fc
2
3var brush_year_obs;
4var brush_year_stddist;
5function draw_barchart_year(data4graph, update, target){
6
7
8    // sizing information, including margins so there is space for labels, etc
9    var margin =  { top: 20, right: 20, bottom: 120, left: 50 },
10        width = 500 - margin.left - margin.right,
11        height = 300 - margin.top - margin.bottom,
12        marginOverview = { top: 230, right: margin.right, bottom: 50,  left: margin.left },
13        heightOverview = 300 - marginOverview.top - marginOverview.bottom;
14
15    // set up a date parsing function for future use
16    var parseDate = d3.time.format("%Y").parse;
17	 var parseYMD = d3.time.format("%Y-%m-%d").parse;
18    // some colours to use for the bars
19    var colour = d3.scale.ordinal()
20                        .range(["#A9A9A9", "#000000"]);
21
22    // mathematical scales for the x and y axes
23    var x = d3.time.scale()
24                    .range([0, width]);
25    var y = d3.scale.linear()
26                    .range([height, 0]);
27    var xOverview = d3.time.scale()
28                    .range([0, width]);
29    var yOverview = d3.scale.linear()
30                    .range([heightOverview, 0]);
31
32    // rendering for the x and y axes
33    var xAxis = d3.svg.axis()
34                    .scale(x)
35                    .orient("bottom")
36                    .ticks(d3.time.years)
37                    .tickSize(16, 0)
38                    .tickFormat(d3.time.format("%Y"));
39    var yAxis = d3.svg.axis()
40                    .scale(y)
41                    .orient("left");
42    var xAxisOverview = d3.svg.axis()
43                    .scale(xOverview)
44                    .orient("bottom")
45                    .ticks(d3.time.years);
46                    //.tickSize(16, 0)
47                    //.tickFormat(d3.time.format("%b %Y"));
48    var svg;
49    var main;
50    var overview;
51    var brush_year;
52
53    var svgid = "svg_bar_obs_year";
54    var brushid = "brush_bar_obs_year";
55    var divid = "d3baryearobs";
56    var ylabel = "Observations";
57    if("StdDistance"==target){
58      svgid = "svg_bar_stddist_year";
59      brushid = "brush_bar_stddist_year";
60      divid = "d3baryearstddist";
61      ylabel = "Std Distance (km)";
62    }
63    if("IDs"==target){
64      svgid = "svg_bar_ids_year";
65      brushid = "brush_bar_ids_year";
66      divid = "d3baryearids";
67      ylabel = "Identifications";
68    }
69
70    if(/*true == update*/d3.select("#"+svgid)[0][0] != null){
71        d3.select("#"+svgid).remove();
72    }
73    if(data4graph.length == 0){
74      return;
75    }
76    // something for us to render the chart into
77    svg = d3.select("#"+divid)
78                    .append("svg") // the overall space
79                        .attr("id", svgid)
80                        .attr("width", width + margin.left + margin.right)
81                        .attr("height", height + margin.top + margin.bottom);
82    main = svg.append("g")
83                    .attr("class", "main")
84                    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
85    overview = svg.append("g")
86                        .attr("class", "overview")
87                        .attr("transform", "translate(" + marginOverview.left + "," + marginOverview.top + ")");
88
89    // brush tool to let us zoom and pan using the overview chart
90    /*
91    brush_year = d3.svg.brush()
92                        .x(xOverview)
93                        .on("brush", brushed)
94                        .on("brushend", brushend);
95    */
96    if("StdDistance" == target){
97        brush_year_stddist = d3.svg.brush()
98                        .x(xOverview)
99                        .on("brush", brushed)
100                        .on("brushend", brushend);
101        brush_year =  brush_year_stddist;
102    }else if("IDs" == target){
103        brush_year_ids = d3.svg.brush()
104                        .x(xOverview)
105                        .on("brush", brushed)
106                        .on("brushend", brushend);
107        brush_year =  brush_year_ids;
108    }else{
109      brush_year_obs = d3.svg.brush()
110                      .x(xOverview)
111                      .on("brush", brushed)
112                      .on("brushend", brushend);
113      brush_year =  brush_year_obs;
114    }
115  // setup complete, let's get some data!
116  //d3.csv(datafile, parse_data, function(data) {
117
118       data = data4graph.map(parse_data);
119
120       //var barwidth = Math.max(Math.floor(width/((data[data.length-1].date-data[0].date)/1000/3600/24/365+1)), 2);
121	   var barwidth = Math.max(Math.floor(width/((parseYMD($("#dateend").val())-parseYMD($("#datestart").val()))/1000/3600/24/365)), 2);
122	   
123	   /*
124       if(data.length == 1){
125         barwidth = Math.floor(width/2);
126       }
127	   */
128	   
129       //console.log(data)
130      // data ranges for the x and y axes
131      //x.domain(d3.extent(data, function(d) { return d.date; }));
132     
133      x.domain([parseYMD($("#datestart").val()), parseYMD($("#dateend").val())]);
134      y.domain([0, d3.max(data, function(d) { return d.total; })]);
135      xOverview.domain(x.domain());
136      yOverview.domain(y.domain());
137
138      // data range for the bar colours
139      // (essentially maps attribute names to colour values)
140      colour.domain(d3.keys(data[0]));
141
142      // draw the axes now that they are fully set up
143      main.append("g")
144          .attr("class", "x axis")
145          .attr("transform", "translate(0," + height + ")")
146          .call(xAxis);
147      main.append("g")
148          .attr("class", "y axis")
149          .call(yAxis);
150
151      svg.append("text")
152            .attr("transform", "rotate(-90)")
153            .attr("y", -2)
154            .attr("x",-100)
155            .attr("dy", "1em")
156            .style("text-anchor", "middle")
157            .style("font-size", "12px")
158            .text(ylabel);
159
160      overview.append("g")
161          .attr("class", "x axis")
162          .attr("transform", "translate(0," + heightOverview + ")")
163          .call(xAxisOverview);
164
165      svg.selectAll(".x.axis text")  // select all the text elements for the xaxis
166                .attr("transform", function(d) {
167                    return "translate(" + this.getBBox().height*-2 + "," + this.getBBox().height + ")rotate(-45)";
168              });
169
170      // draw the bars
171      main.append("g")
172              .attr("class", "bars")
173          // a group for each stack of bars, positioned in the correct x position
174          .selectAll(".bar.stack")
175          .data(data)
176          .enter().append("g")
177              .attr("class", "bar stack")
178              .attr("transform", function(d) { return "translate(" + x(d.date) + ",0)"; })
179          // a bar for each value in the stack, positioned in the correct y positions
180          .selectAll("rect")
181          .data(function(d) { return d.counts; })
182          .enter().append("rect")
183              .attr("class", "bar")
184              .attr("width", barwidth)
185              .attr("y", function(d) { return y(d.y1); })
186              .attr("height", function(d) { return y(d.y0) - y(d.y1); })
187              .style("fill", function(d) { return colour(d.name); });
188
189      overview.append("g")
190                  .attr("class", "obars")
191          .selectAll(".bar")
192          .data(data)
193          .enter().append("rect")
194              .attr("class", "bar")
195              .attr("x", function(d) { return xOverview(d.date) - 3; })
196              .attr("width", barwidth)
197              .attr("y", function(d) { return yOverview(d.total); })
198              .attr("height", function(d) { return heightOverview - yOverview(d.total); });
199
200      // add the brush target area on the overview chart
201      overview.append("g")
202                  .attr("class", "x brush")
203                  .attr("id", brushid)
204                  .call(brush_year)
205                  .selectAll("rect")
206                      // -6 is magic number to offset positions for styling/interaction to feel right
207                      .attr("y", -6)
208                      // need to manually set the height because the brush has
209                      // no y scale, i.e. we should see the extent being marked
210                      // over the full height of the overview chart
211                      .attr("height", heightOverview + 7);  // +7 is magic number for styling
212
213      // by habit, cleaning/parsing the data and return a new object to ensure/clarify data object structure
214      function parse_data(d) {
215          //var value = { date: parseDate(d.date) }; // turn the date string into a date object
216          var value = { date: parseDate(""+d.date) }; // turn the date string into a date object
217
218          // adding calculated data to each count in preparation for stacking
219          var y0 = 0; // keeps track of where the "previous" value "ended"
220          var variables = ["count_obs", "count_obscured"];
221          if(target == "StdDistance"){
222            variables = ["std_dist_km"];
223          }
224          if(target == "IDs"){
225            variables = ["count_ids"];
226          }
227          value.counts = variables.map(function(name) { //, "count2", "count3"
228            j = { name: name,
229              y0: y0,
230              // add this count on to the previous "end" to create a range, and update the "previous end" for the next iteration
231              y1: y0 += +d[name]
232            };  
233            if(isNaN(j.y0)){
234              j.y0 = 0;
235            }
236            if(isNaN(j.y1)){
237              j.y1 = 0;
238            }
239            return j;
240          });
241          // quick way to get the total from the previous calculations
242          value.total = value.counts[value.counts.length - 1].y1;
243          if(isNaN(value.total)){
244            value.total = 0;
245          }
246          //console.log(value);
247          return value;
248      }
249
250      // zooming/panning behaviour for overview chart
251      function brushed() {
252          //console.log("yearly bar brush() triggered");
253          // update the main chart's x axis data range
254          x.domain(brush_year.empty() ? xOverview.domain() : brush_year.extent());
255          // redraw the bars on the main chart
256          main.selectAll(".bar.stack")
257                  .attr("transform", function(d) { return "translate(" + x(d.date) + ",0)"; })
258          // redraw the x axis of the main chart
259          main.select(".x.axis").call(xAxis);
260
261          svg.selectAll(".x.axis text")  // select all the text elements for the xaxis
262                    .attr("transform", function(d) {
263                        return "translate(" + this.getBBox().height*-2 + "," + this.getBBox().height + ")rotate(-45)";
264                  });
265          if(brush_year.extent()[1] - brush_year.extent()[0] > 0){
266            var N = (brush_year.extent()[1] - brush_year.extent()[0])/1000/3600/24/365+1;
267            //console.log(width, N, Math.floor(width/N));
268            main.selectAll(".bar").attr('width', Math.max(2, Math.floor(width/N)));
269          }
270          else{
271            var barwidth = Math.max(Math.floor(width/Math.ceil((data[data.length-1].date-data[0].date)/1000/3600/24/365+1)), 2);
272            if(data.length == 1){
273              barwidth = Math.floor(width/2);
274            }
275            main.selectAll(".bar").attr('width', Math.max(2, barwidth));
276          }
277
278
279      }
280
281      function brushend(){
282
283        //console.log("yearly bar brushend() triggered");
284
285        var ext = brush_year.extent();
286        var d1 = ext[0];
287        var d2 = ext[1];
288
289        if(d2 - d1 == 0){
290          //console.log("zero extent");
291          main.selectAll(".bar").attr('width', barwidth);
292        }
293
294        /* snapping to edges of year
295        var y1 = d1.getFullYear();
296        var y2 = d2.getFullYear();
297
298        var ext_snapped = [new Date(y1, 0, 01), new Date(y2, 11, 31)]
299        */
300        var ext_snapped = [d1, d2];
301
302        d3.select("brush_year").call((brush_year.empty()) ? brush_year.clear() :brush_year.extent(ext_snapped));
303
304        //*
305        drawBrushMonth();
306
307        function drawBrushMonth() {
308          // our year will this.innerText
309          //console.log(this.innerText)
310
311          /*
312          var brush_xx = brush_month_obs;
313          var brush = d3.select("#brush_bar_obs_month.brush");
314          if("StdDistance" == target){
315            brush_xx = brush_month_stddist;
316            brush = d3.select("#brush_bar_stddist_month.brush");
317          }
318          */
319
320          var brush_xxs = [brush_month_obs, brush_month_stddist, brush_month_ids];
321          var brushs = [d3.select("#brush_bar_obs_month.brush"), d3.select("#brush_bar_stddist_month.brush"), d3.select("#brush_bar_ids_month.brush")];
322
323          for(var i in brush_xxs){
324
325            brush_xx = brush_xxs[i];
326            brush = brushs[i];
327
328            var diff_d1 = brush_xx.extent()[0] - ext_snapped[0];
329            var diff_d2 = brush_xx.extent()[1] - ext_snapped[1];
330
331            if(diff_d1 == 0 && diff_d2 == 0){
332              continue;
333            }
334
335            // define our brush extent to be begin and end of the year
336            brush_xx.extent(jQuery.extend(true, [], ext_snapped));
337
338            // now draw the brush to match our extent
339            // use transition to slow it down so we can see what is happening
340            // remove transition so just d3.select(".brush") to just draw
341            brush_xx(brush.transition());
342            //brush_xx(brush);
343
344            // now fire the brushstart, brushmove, and brushend events
345            // remove transition so just d3.select(".brush") to just draw
346            brush_xx.event(brush.transition().delay(0));
347            //brush_xx.event(brush);
348          }
349        }
350        //*/
351
352
353        /*
354        var dt_start = brush_year.extent()[0];
355        var dt_end = brush_year.extent()[1];
356        if(dt_start.toString() != dt_end.toString()){
357          $("#datestart_tmp").val(dt_start.toJSON().split("T")[0]);
358          $("#dateend_tmp").val(dt_end.toJSON().split("T")[0]);
359          $(".datetemp").show();
360
361          $("#datestart").prop( "disabled", true );
362          $("#dateend").prop( "disabled", true );
363          $("#obscured").prop( "disabled", true );
364          $("#captivecultivated").prop( "disabled", true );
365          $("#userid").prop( "disabled", true );
366          $("#submit").prop( "disabled", true );
367
368          d3.select("#query").selectAll("label").style("color","gray");
369          d3.selectAll(".datetemp").selectAll("label").style("color","black");
370
371          tmpMode = true;
372
373          $("#dateend_tmp").trigger("change");
374
375
376        }else{
377          $(".datetemp").hide();
378          $("#datestart").prop( "disabled", false );
379          $("#dateend").prop( "disabled", false );
380          $("#obscured").prop( "disabled", false );
381          $("#captivecultivated").prop( "disabled", false );
382          $("#userid").prop( "disabled", false );
383          $("#submit").prop( "disabled", false );
384
385          d3.select("#query").selectAll("label").style("color","black");
386          tmpMode = false;
387
388          $("#submit").trigger("click");
389        }
390        */
391      }
392
393}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.