Changeset 02b96c5 in OpenWorkouts-current for ow/static/js/ow.js
- Timestamp:
- Mar 12, 2019, 12:47:38 PM (5 years ago)
- Branches:
- current
- Children:
- 8ba32d9
- Parents:
- d9453fc
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
ow/static/js/ow.js
rd9453fc r02b96c5 459 459 }; 460 460 461 owjs.calendar_heatmap_chart = function(spec) { 462 463 "use strict" 464 465 var chart_selector = spec.chart_selector, 466 url = spec.url, 467 day_names_list = spec.day_names_list; 468 469 var calendar_rows = function(month) { 470 /* 471 Given a date object that "marks" the beginning of a month 472 return the number of "rows" we need to show all days in that 473 month 474 */ 475 // m will be actually the last day of the previous month 476 var m = d3.timeMonth.floor(month); 477 return d3.timeWeeks(d3.timeWeek.floor(m), 478 d3.timeMonth.offset(m,1)).length; 479 } 480 481 // defaults for the squares/"cells" we will show with the info 482 var cell_margin = 3, 483 cell_size = 25; 484 485 486 var render = function render() { 487 /* 488 Method to actually perform all the loading and rendering of 489 the chart 490 */ 491 var chart = d3.select(chart_selector); 492 493 d3.json(url, {credentials: "same-origin"}).then(function (data) { 494 495 var min_date = d3.min(data, function(d) { 496 return new Date(d.day); 497 }); 498 499 var max_date = d3.max(data, function(d) { 500 return new Date(d.day); 501 }); 502 503 // sunday-starting week: 504 // day = d3.timeFormat("%w") 505 // week = d3.timeFormat("%W") 506 // monday-starting week: 507 // day = function(d) {return d3.timeFormat("%u")(d) - 1} 508 // week = d3.timeFormat("%W") 509 var day = function(d) {return d3.timeFormat("%u")(d) - 1}, 510 week = d3.timeFormat("%W"), 511 format = d3.timeFormat("%Y-%m-%d"), 512 titleFormat = d3.utcFormat("%a, %d %b"), 513 monthName = d3.timeFormat("%B / %Y"), 514 months = d3.timeMonth.range(d3.timeMonth.floor(min_date), max_date), 515 rows = calendar_rows(max_date); 516 517 // Build the svg image where the chart will be 518 var svg = chart.selectAll("svg") 519 .data(months) 520 .enter().append("svg") 521 .attr("class", "month") 522 .attr("width", (cell_size * 7) + (cell_margin * 8)) 523 .attr("height", function(d) { 524 // we add 50 extra so the month/year label fits 525 return (cell_size * rows) + (cell_margin * (rows + 1)) + 50; 526 }) 527 .append("g"); 528 529 // This adds the month/year label above the chart 530 svg.append("text") 531 .attr("class", "month-name") 532 .attr("x", ((cell_size * 7) + (cell_margin * 8)) / 2 ) 533 .attr("y", 15) 534 .attr("text-anchor", "middle") 535 .text(function(d) { return monthName(d); }); 536 537 // Now, go through each day and add a square/cell for them 538 var rect = svg.selectAll("rect.day") 539 .data(function(d, i) { 540 return d3.timeDays( 541 d, new Date(d.getFullYear(), d.getMonth()+1, 1)); 542 }) 543 .enter().append("rect") 544 .attr("class", "day") 545 .attr("width", cell_size) 546 .attr("height", cell_size) 547 .attr("rx", 6).attr("ry", 6) // rounded corners 548 .attr("fill", '#eaeaea') // default light grey fill 549 .attr("x", function(d) { 550 return (day(d) * cell_size) + (day(d) * cell_margin) + cell_margin; 551 }) 552 .attr("y", function(d) { 553 var base_value = (week(d) - week(new Date(d.getFullYear(), d.getMonth(), 1))); 554 return (base_value * cell_size) + (base_value * cell_margin) + cell_margin + 20; 555 }) 556 .on("mouseover", function(d) { 557 d3.select(this).classed('hover', true); 558 }) 559 .on("mouseout", function(d) { 560 d3.select(this).classed('hover', false); 561 }) 562 .datum(format); 563 564 rect.append("title") 565 .text(function(d) {return titleFormat(new Date(d));}); 566 567 // Add the row with the names of the days 568 var day_names = svg.selectAll('.day-name') 569 .data(day_names_list) 570 .enter().append("text") 571 .attr("class", "day-name") 572 .attr("width", cell_size) 573 .attr("height", cell_size) 574 .attr("x", function(d) { 575 return (day_names_list.indexOf(d) * cell_size) + (day_names_list.indexOf(d) * cell_margin) + cell_margin * 2; 576 }) 577 .attr("y", function(d) { 578 return ((cell_size * rows) + (cell_margin * (rows + 1))) + 40; 579 }) 580 .text(function(d) { 581 return d; 582 }); 583 584 var find_day = function(day) { 585 var found = data.find(function(d) { 586 return d.day == day; 587 }); 588 return found; 589 } 590 591 var lookup = d3.nest() 592 .key(function(d) { 593 return d.day; 594 }) 595 .rollup(function(leaves) { 596 return leaves[0].time; 597 }) 598 .object(data); 599 600 var count = d3.nest() 601 .key(function(d) { 602 return d.day; 603 }) 604 .rollup(function(leaves) { 605 return leaves[0].time; 606 }) 607 .entries(data); 608 609 var scale = d3.scaleLinear() 610 .domain(d3.extent(count, function(d) { 611 return d.value; 612 })) 613 .range(['#f8b5be', '#f60002']); 614 615 rect.filter(function(d) { 616 return d in lookup; 617 }) 618 .style("fill", function(d) { 619 // Fill in with the proper color 620 return scale([lookup[d]]); 621 }) 622 .classed("clickable", true) 623 .on("click", function(d){ 624 if(d3.select(this).classed('focus')){ 625 d3.select(this).classed('focus', false); 626 } else { 627 d3.select(this).classed('focus', true) 628 } 629 // doSomething(); 630 }) 631 .select("title") 632 .text(function(d) { 633 // Update the title adding some more info 634 var day = find_day(d); 635 return titleFormat(new Date(d)) + ": " + day.time_formatted; }); 636 }); 637 638 }; 639 640 var that = {} 641 that.render = render; 642 return that 643 644 }; 645 461 646 462 647 owjs.map_shots = function(spec) {
Note: See TracChangeset
for help on using the changeset viewer.