<commit_before>import { Component, OnChanges, Input, ElementRef, SimpleChange } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromEvent';
import { select as d3select } from 'd3-selection';
import * as barChart from 'britecharts/dist/umd/bar.min';
import * as miniTooltip from 'britecharts/dist/umd/miniTooltip.min';
import * as moment from 'moment';
import { Activity, Outing } from '../outing';
import { BarChartDataItem } from '../bar-chart/bar-chart-data-item';

@Component({
  selector: 'app-activity-year-bar-chart',
  templateUrl: './activity-year-bar-chart.component.html',
  styleUrls: ['./activity-year-bar-chart.component.css']
})
export class ActivityYearBarChartComponent implements OnChanges {

  @Input() outings: Outing[];
  @Input() activity?: Activity;

  private data: BarChartDataItem[];

  private el: HTMLElement;

  constructor(elementRef: ElementRef) {
    Observable.fromEvent(window, 'resize')
      .debounceTime(250)
      .subscribe(() => this.redrawChart());
    this.el = elementRef.nativeElement;
  }

  ngOnChanges(changes: { [key: string]: SimpleChange }) {
    if (this.outings) {
      this.outingsToData();
      this.drawChart();
    }
  }

  private outingsToData() {
    const isFullYear = this.isFullYear();
    const firstOutingMoment = this.outings
      .map(outing => moment(outing.date_start))
      .sort((a, b) => a.valueOf() - b.valueOf())[0];
    const firstYear = isFullYear ?
      firstOutingMoment.year() :
      (firstOutingMoment.month() > 8 ? firstOutingMoment.year() : firstOutingMoment.year() - 1);
    const lastYear = isFullYear ? moment().year() : (moment().month() > 8 ? moment().year() : moment().year() - 1);
    const outingsPerSeason = new Map<string, number>();
    for (let y = firstYear; y <= lastYear; y++) {
      outingsPerSeason.set(isFullYear ? y.toString() : `${y.toString()}/${(y + 1).toString()}`, 0);
    }
    this.outings
      .filter(outing => outing.activities.includes(this.activity))
      .reduce((map, outing) => {
        const season = this.season(outing.date_start);
        map.set(season, map.get(season) + 1);
        return map;
      }, outingsPerSeason);
    this.data = [];
    outingsPerSeason.forEach((count, season) => {
      this.data.push({
        name: season,
        value: count
      });
    });
  }

  private isFullYear() {
    switch (this.activity) {
      case 'skitouring':<commit_msg>ensure at least a few years for outings / year charts<commit_after>import { Component, OnChanges, Input, ElementRef, SimpleChange } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromEvent';
import { select as d3select } from 'd3-selection';
import * as barChart from 'britecharts/dist/umd/bar.min';
import * as miniTooltip from 'britecharts/dist/umd/miniTooltip.min';
import * as moment from 'moment';
import { Activity, Outing } from '../outing';
import { BarChartDataItem } from '../bar-chart/bar-chart-data-item';

@Component({
  selector: 'app-activity-year-bar-chart',
  templateUrl: './activity-year-bar-chart.component.html',
  styleUrls: ['./activity-year-bar-chart.component.css']
})
export class ActivityYearBarChartComponent implements OnChanges {

  @Input() outings: Outing[];
  @Input() activity?: Activity;

  private data: BarChartDataItem[];

  private el: HTMLElement;

  constructor(elementRef: ElementRef) {
    Observable.fromEvent(window, 'resize')
      .debounceTime(250)
      .subscribe(() => this.redrawChart());
    this.el = elementRef.nativeElement;
  }

  ngOnChanges(changes: { [key: string]: SimpleChange }) {
    if (this.outings) {
      this.outingsToData();
      this.drawChart();
    }
  }

  private outingsToData() {
    const isFullYear = this.isFullYear();
    const firstOutingMoment = this.outings
      .map(outing => moment(outing.date_start))
      .sort((a, b) => a.valueOf() - b.valueOf())[0];
    // ensure at least 8 years to avoid empty graphs
    if (moment().year() - firstOutingMoment.year() < 8) {
      firstOutingMoment.year(moment().year() - 8);
    }
    const firstYear = isFullYear ?
      firstOutingMoment.year() :
      (firstOutingMoment.month() > 8 ? firstOutingMoment.year() : firstOutingMoment.year() - 1);
    const lastYear = isFullYear ? moment().year() : (moment().month() > 8 ? moment().year() : moment().year() - 1);
    const outingsPerSeason = new Map<string, number>();
    for (let y = firstYear; y <= lastYear; y++) {
      outingsPerSeason.set(isFullYear ? y.toString() : `${y.toString()}/${(y + 1).toString()}`, 0);
    }
    this.outings
      .filter(outing => outing.activities.includes(this.activity))
      .reduce((map, outing) => {
        const season = this.season(outing.date_start);
        map.set(season, map.get(season) + 1);
        return map;
      }, outingsPerSeason);
    this.data = [];
    outingsPerSeason.forEach((count, season) => {
      this.data.push({
        name: season,
        value: count
      });
    });
  }

  private isFullYear() {
    switch (this.activity) {
      case 'skitouring':
{'fraction_non_alphanumeric': 0.1591620986687549, 'fraction_numerical': 0.005677368833202819, 'mean_word_length': 3.4157303370786516, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3110190', 'n_tokens_mistral': 1654, 'n_tokens_neox': 1618, 'n_words': 347}