<commit_before>import {
  Component, OnDestroy, OnInit, OnChanges, EventEmitter, ElementRef, Input,
  Output, NgModule
} from '@angular/core';

declare var Chart:any;

@Component({
  selector: 'base-chart',
  template: `<canvas style="width: 100%; height: 100%;"></canvas>`,
  styles: [`:host { display: block; }`]
})
export class BaseChartComponent implements OnDestroy, OnChanges, OnInit {
  public static defaultColors:Array<number[]> = [
    [255, 99, 132],
    [54, 162, 235],
    [255, 206, 86],
    [231, 233, 237],
    [75, 192, 192],
    [151, 187, 205],
    [220, 220, 220],
    [247, 70, 74],
    [70, 191, 189],
    [253, 180, 92],
    [148, 159, 177],
    [77, 83, 96]
  ];

  @Input() public data:number[] | Array<number[]>;
  @Input() public datasets:any[];
  @Input() public labels:Array<any> = [];
  @Input() public options:any = {responsive: true};
  @Input() public chartType:string;
  @Input() public colors:Array<any>;
  @Input() public legend:boolean;

  @Output() public chartClick:EventEmitter<any> = new EventEmitter();
  @Output() public chartHover:EventEmitter<any> = new EventEmitter();

  private ctx:any;
  private cvs:any;
  private parent:any;
  private chart:any;
  private initFlag:boolean = false;

  private element:ElementRef;

  public constructor(element:ElementRef) {
    this.element = element;
  }

  public ngOnInit():any {
    this.ctx = this.element.nativeElement.children[0].getContext('2d');
    this.cvs = this.element.nativeElement.children[0];
    this.parent = this.element.nativeElement;
    this.initFlag = true;
    if (this.data || this.datasets) {
      this.refresh();
    }
  }

  public ngOnChanges():any {
    if (this.initFlag) {
      this.refresh();
    }
  }

  public ngOnDestroy():any {
    if (this.chart) {
      this.chart.destroy();
      this.chart = void 0;
    }
  }

  public getChartBuilder(ctx:any/*, data:Array<any>, options:any*/):any {
    let datasets:any = void 0;

    // in case if datasets is not provided, but data is present
    if (!this.datasets || !this.datasets.length && (this.data && this.data.length)) {
      if (Array.isArray(this.data[0])) {
        datasets = (this.data as Array<number[]>).map((data:number[], index:number) => {
          return {data, label: this.labels[index] || `Label ${index}`};
        });
      } else {
        datasets = [{data: this.data, label: `Label 0`}];
      }
    }

    if (this.datasets && this.datasets.length ||
      (datasets && datasets.length)) {
      datasets = (this.datasets || datasets)
        .map((elm:number, index:number) => {
          let newElm:any = Object.assign({}, elm);
          if (this.colors && this.colors.length) {
            Object.assign(newElm, this.colors[index]);
          } else {
            Object.assign(newElm, getColors(this.chartType, index, newElm.data.length));
          }
          return newElm;
        });
    }

    if (!datasets) {
      throw new Error(`ng-charts configuration error, 
      data or datasets field are required to render char ${this.chartType}`);
    }

    let options:any = Object.assign({}, this.options);
    if (this.legend === false) {
      options.legend = {display: false};
    }
    // hock for onHover and onClick events
    options.hover = options.hover || {};
    if (!options.hover.onHover) {
      options.hover.onHover = (active:Array<any>) => {
        if (active && !active.length) {
          return;
        }
        this.chartHover.emit({active});
      };
    }

    if (!options.onClick) {
      options.onClick = (event:any, active:Array<any>) => {
        this.chartClick.emit({event, active});
      };
    }

    let opts = {
      type: this.chartType,
      data: {
        labels: this.labels,
        datasets: datasets
      },
      options: options
    };

    if (typeof Chart === 'undefined') {
      throw new Error('ng2-charts configuration issue: Embedding Chart.js lib is mandatory');
    }

    return new Chart(ctx, opts);
  }

  private refresh():any {
    if (this.options && this.options.responsive && this.parent.clientHeight === 0) {
      return setTimeout(() => this.refresh(), 50);
    }

    // todo: remove this line, it is producing flickering
    this.ngOnDestroy();
    this.chart = this.getChartBuilder(this.ctx/*, data, this.options*/);
  }
}

// private helper functions
export interface Color {
  backgroundColor?:string | string[];
  borderWidth?:number | number[];
  borderColor?:string | string[];
  borderCapStyle?:string;
  borderDash?:number[];
  borderDashOffset?:number;
  borderJoinStyle?:string;

  pointBorderColor?:string | string[];
  pointBackgroundColor?:string | string[];
  pointBorderWidth?:number | number[];

  pointRadius?:number | number[];
  pointHoverRadius?:number | number[];
  pointHitRadius?:number | number[];

  pointHoverBackgroundColor?:string | string[];
  pointHoverBorderColor?:string | string[];
  pointHoverBorderWidth?:number | number[];
  pointStyle?:string | string[];

  hoverBackgroundColor?:string | string[];
  hoverBorderColor?:string | string[];
  hoverBorderWidth?:number;
}

// pie | doughnut
export interface Colors extends Color {
  data?:number[];
  label?:string;
}

function rgba(colour:Array<number>, alpha:number):string {
  return 'rgba(' + colour.concat(alpha).join(',') + ')';
}

function getRandomInt(min:number, max:number):number {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

function formatLineColor(colors:Array<number>):Color {
  return {
    backgroundColor: rgba(colors, 0.4),
    borderColor: rgba(colors, 1),
    pointBackgroundColor: rgba(colors, 1),
    pointBorderColor: '#fff',
    pointHoverBackgroundColor: '#fff',
    pointHoverBorderColor: rgba(colors, 0.8)
  };
}

function formatBarColor(colors:Array<number>):Color {
  return {
    backgroundColor: rgba(colors, 0.6),
    borderColor: rgba(colors, 1),
    hoverBackgroundColor: rgba(colors, 0.8),
    hoverBorderColor: rgba(colors, 1)
  };
}

function formatPieColors(colors:Array<number[]>):Colors {
  return {
    backgroundColor: colors.map((color:number[]) => rgba(color, 0.6)),
    borderColor: colors.map(() => '#fff'),
    pointBackgroundColor: colors.map((color:number[]) => rgba(color, 1)),
    pointBorderColor: colors.map(() => '#fff'),
    pointHoverBackgroundColor: colors.map((color:number[]) => rgba(color, 1)),
    pointHoverBorderColor: colors.map((color:number[]) => rgba(color, 1))
  };
}

function formatPolarAreaColors(colors:Array<number[]>):Color {
  return {
    backgroundColor: colors.map((color:number[]) => rgba(color, 0.6)),
    borderColor: colors.map((color:number[]) => rgba(color, 1)),
    hoverBackgroundColor: colors.map((color:number[]) => rgba(color, 0.8)),
    hoverBorderColor: colors.map((color:number[]) => rgba(color, 1))
  };
}

function getRandomColor():number[] {
  return [getRandomInt(0, 255), getRandomInt(0, 255), getRandomInt(0, 255)];
}

/**
 * Generate colors for line|bar charts
 * @param index
 * @returns {number[]|Color}
 */
function generateColor(index:number):number[] {
  return BaseChartComponent.defaultColors[index] || getRandomColor();
}

/**
 * Generate colors for pie|doughnut charts
 * @param count
 * @returns {Colors}
 */
function generateColors(count:number):Array<number[]> {
  let colorsArr:Array<number[]> = new Array(count);
  for (let i = 0; i < count; i++) {
    colorsArr[i] = BaseChartComponent.defaultColors[i] || getRandomColor();
  }
  return colorsArr;
}

/**
 * Generate colors by chart type
 * @param chartType
 * @param index
 * @param count
 * @returns {Color}
 */
function getColors(chartType:string, index:number, count:number):Color {
  if (chartType === 'pie' || chartType === 'doughnut') {
    return formatPieColors(generateColors(count));
  }

  if (chartType === 'polarArea') {
    return formatPolarAreaColors(generateColors(count));
  }

  if (chartType === 'line' || chartType === 'radar') {
    return formatLineColor(generateColor(index));
  }

  if (chartType === 'bar') {
    return formatBarColor(generateColor(index));
  }
  return generateColor(index);
}

@NgModule({
  declarations: [
    BaseChartComponent
  ],
  exports: [
    BaseChartComponent
  ],
  imports: []
})
export class ChartsModule {
}
<commit_msg>fix(options): to have colors on horizontalBar graphs (#394)<commit_after>import {
  Component, OnDestroy, OnInit, OnChanges, EventEmitter, ElementRef, Input,
  Output, NgModule
} from '@angular/core';

declare var Chart: any;

@Component({
  selector: 'base-chart',
  template: `<canvas style="width: 100%; height: 100%;"></canvas>`,
  styles: [`:host { display: block; }`]
})
export class BaseChartComponent implements OnDestroy, OnChanges, OnInit {
  public static defaultColors: Array<number[]> = [
    [255, 99, 132],
    [54, 162, 235],
    [255, 206, 86],
    [231, 233, 237],
    [75, 192, 192],
    [151, 187, 205],
    [220, 220, 220],
    [247, 70, 74],
    [70, 191, 189],
    [253, 180, 92],
    [148, 159, 177],
    [77, 83, 96]
  ];

  @Input() public data: number[] | Array<number[]>;
  @Input() public datasets: any[];
  @Input() public labels: Array<any> = [];
  @Input() public options: any = { responsive: true };
  @Input() public chartType: string;
  @Input() public colors: Array<any>;
  @Input() public legend: boolean;

  @Output() public chartClick: EventEmitter<any> = new EventEmitter();
  @Output() public chartHover: EventEmitter<any> = new EventEmitter();

  private ctx: any;
  private cvs: any;
  private parent: any;
  private chart: any;
  private initFlag: boolean = false;

  private element: ElementRef;

  public constructor(element: ElementRef) {
    this.element = element;
  }

  public ngOnInit(): any {
    this.ctx = this.element.nativeElement.children[0].getContext('2d');
    this.cvs = this.element.nativeElement.children[0];
    this.parent = this.element.nativeElement;
    this.initFlag = true;
    if (this.data || this.datasets) {
      this.refresh();
    }
  }

  public ngOnChanges(): any {
    if (this.initFlag) {
      this.refresh();
    }
  }

  public ngOnDestroy(): any {
    if (this.chart) {
      this.chart.destroy();
      this.chart = void 0;
    }
  }

  public getChartBuilder(ctx: any/*, data:Array<any>, options:any*/): any {
    let datasets: any = void 0;

    // in case if datasets is not provided, but data is present
    if (!this.datasets || !this.datasets.length && (this.data && this.data.length)) {
      if (Array.isArray(this.data[0])) {
        datasets = (this.data as Array<number[]>).map((data: number[], index: number) => {
          return { data, label: this.labels[index] || `Label ${index}` };
        });
      } else {
        datasets = [{ data: this.data, label: `Label 0` }];
      }
    }

    if (this.datasets && this.datasets.length ||
      (datasets && datasets.length)) {
      datasets = (this.datasets || datasets)
        .map((elm: number, index: number) => {
          let newElm: any = Object.assign({}, elm);
          if (this.colors && this.colors.length) {
            Object.assign(newElm, this.colors[index]);
          } else {
            Object.assign(newElm, getColors(this.chartType, index, newElm.data.length));
          }
          return newElm;
        });
    }

    if (!datasets) {
      throw new Error(`ng-charts configuration error, 
      data or datasets field are required to render char ${this.chartType}`);
    }

    let options: any = Object.assign({}, this.options);
    if (this.legend === false) {
      options.legend = { display: false };
    }
    // hock for onHover and onClick events
    options.hover = options.hover || {};
    if (!options.hover.onHover) {
      options.hover.onHover = (active: Array<any>) => {
        if (active && !active.length) {
          return;
        }
        this.chartHover.emit({ active });
      };
    }

    if (!options.onClick) {
      options.onClick = (event: any, active: Array<any>) => {
        this.chartClick.emit({ event, active });
      };
    }

    let opts = {
      type: this.chartType,
      data: {
        labels: this.labels,
        datasets: datasets
      },
      options: options
    };

    if (typeof Chart === 'undefined') {
      throw new Error('ng2-charts configuration issue: Embedding Chart.js lib is mandatory');
    }

    return new Chart(ctx, opts);
  }

  private refresh(): any {
    if (this.options && this.options.responsive && this.parent.clientHeight === 0) {
      return setTimeout(() => this.refresh(), 50);
    }

    // todo: remove this line, it is producing flickering
    this.ngOnDestroy();
    this.chart = this.getChartBuilder(this.ctx/*, data, this.options*/);
  }
}

// private helper functions
export interface Color {
  backgroundColor?: string | string[];
  borderWidth?: number | number[];
  borderColor?: string | string[];
  borderCapStyle?: string;
  borderDash?: number[];
  borderDashOffset?: number;
  borderJoinStyle?: string;

  pointBorderColor?: string | string[];
  pointBackgroundColor?: string | string[];
  pointBorderWidth?: number | number[];

  pointRadius?: number | number[];
  pointHoverRadius?: number | number[];
  pointHitRadius?: number | number[];

  pointHoverBackgroundColor?: string | string[];
  pointHoverBorderColor?: string | string[];
  pointHoverBorderWidth?: number | number[];
  pointStyle?: string | string[];

  hoverBackgroundColor?: string | string[];
  hoverBorderColor?: string | string[];
  hoverBorderWidth?: number;
}

// pie | doughnut
export interface Colors extends Color {
  data?: number[];
  label?: string;
}

function rgba(colour: Array<number>, alpha: number): string {
  return 'rgba(' + colour.concat(alpha).join(',') + ')';
}

function getRandomInt(min: number, max: number): number {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

function formatLineColor(colors: Array<number>): Color {
  return {
    backgroundColor: rgba(colors, 0.4),
    borderColor: rgba(colors, 1),
    pointBackgroundColor: rgba(colors, 1),
    pointBorderColor: '#fff',
    pointHoverBackgroundColor: '#fff',
    pointHoverBorderColor: rgba(colors, 0.8)
  };
}

function formatBarColor(colors: Array<number>): Color {
  return {
    backgroundColor: rgba(colors, 0.6),
    borderColor: rgba(colors, 1),
    hoverBackgroundColor: rgba(colors, 0.8),
    hoverBorderColor: rgba(colors, 1)
  };
}

function formatPieColors(colors: Array<number[]>): Colors {
  return {
    backgroundColor: colors.map((color: number[]) => rgba(color, 0.6)),
    borderColor: colors.map(() => '#fff'),
    pointBackgroundColor: colors.map((color: number[]) => rgba(color, 1)),
    pointBorderColor: colors.map(() => '#fff'),
    pointHoverBackgroundColor: colors.map((color: number[]) => rgba(color, 1)),
    pointHoverBorderColor: colors.map((color: number[]) => rgba(color, 1))
  };
}

function formatPolarAreaColors(colors: Array<number[]>): Color {
  return {
    backgroundColor: colors.map((color: number[]) => rgba(color, 0.6)),
    borderColor: colors.map((color: number[]) => rgba(color, 1)),
    hoverBackgroundColor: colors.map((color: number[]) => rgba(color, 0.8)),
    hoverBorderColor: colors.map((color: number[]) => rgba(color, 1))
  };
}

function getRandomColor(): number[] {
  return [getRandomInt(0, 255), getRandomInt(0, 255), getRandomInt(0, 255)];
}

/**
 * Generate colors for line|bar charts
 * @param index
 * @returns {number[]|Color}
 */
function generateColor(index: number): number[] {
  return BaseChartComponent.defaultColors[index] || getRandomColor();
}

/**
 * Generate colors for pie|doughnut charts
 * @param count
 * @returns {Colors}
 */
function generateColors(count: number): Array<number[]> {
  let colorsArr: Array<number[]> = new Array(count);
  for (let i = 0; i < count; i++) {
    colorsArr[i] = BaseChartComponent.defaultColors[i] || getRandomColor();
  }
  return colorsArr;
}

/**
 * Generate colors by chart type
 * @param chartType
 * @param index
 * @param count
 * @returns {Color}
 */
function getColors(chartType: string, index: number, count: number): Color {
  if (chartType === 'pie' || chartType === 'doughnut') {
    return formatPieColors(generateColors(count));
  }

  if (chartType === 'polarArea') {
    return formatPolarAreaColors(generateColors(count));
  }

  if (chartType === 'line' || chartType === 'radar') {
    return formatLineColor(generateColor(index));
  }

  if (chartType === 'bar' || chartType === 'horizontalBar') {
    return formatBarColor(generateColor(index));
  }
  return generateColor(index);
}

@NgModule({
  declarations: [
    BaseChartComponent
  ],
  exports: [
    BaseChartComponent
  ],
  imports: []
})
export class ChartsModule {
}

{'fraction_non_alphanumeric': 0.16076687300919526, 'fraction_numerical': 0.018330428511328805, 'mean_word_length': 3.516829533116178, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 71, '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': '3279331', 'n_tokens_mistral': 5508, 'n_tokens_neox': 5208, 'n_words': 1241}