<commit_before>// https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#11-ambient-declarations
declare var exports;

import {FieldDef} from '../schema/fielddef.schema';

import {contains, extend} from '../util';
import {Model} from './Model';
import {SHARED_DOMAIN_OPS} from '../aggregate';
import {COLUMN, ROW, X, Y, SHAPE, SIZE, COLOR, TEXT, hasScale, Channel} from '../channel';
import {SOURCE, STACKED_SCALE} from '../data';
import {NOMINAL, ORDINAL, QUANTITATIVE, TEMPORAL} from '../type';
import {Mark, BAR, TEXT as TEXT_MARK} from '../mark';
import {rawDomain} from './time';
import {field} from '../fielddef';

// scale from rank to field for ordinal color scale,
// ordinal field to field mapping for binned quantitative and temporal scale with time unit
export const INVERSE_RANK = 'inverse_rank';

// scale used to get labels for binned color scales
export const COLOR_LABEL = 'color_label';

export function compileScales(channels: Channel[], model: Model) {
  return channels.filter(hasScale)
    .reduce(function(scales: any[], channel: Channel) {
      const fieldDef = model.fieldDef(channel);

      var scaleDef: any = {
        name: model.scaleName(channel),
        type: type(fieldDef, channel, model.mark()),
      };

      scaleDef.domain = domain(model, channel, scaleDef.type);
      extend(scaleDef, rangeMixins(model, channel, scaleDef.type));

      // Add optional properties
      [
        // general properties
        'reverse', 'round',
        // quantitative / time
        'clamp', 'nice',
        // quantitative
        'exponent', 'zero',
        // ordinal
        'outerPadding', 'padding', 'points'
      ].forEach(function(property) {
        // TODO include fieldDef as part of the parameters
        const value = exports[property](model, channel, scaleDef.type);
        if (value !== undefined) {
          scaleDef[property] = value;
        }
      });

      // add additional scales needed to support ordinal color scales also for legends
      if (channel === COLOR && fieldDef.legend && (fieldDef.type === ORDINAL || fieldDef.bin || fieldDef.timeUnit)) {
        scales.push({
          name: INVERSE_RANK,
          type: ORDINAL,
          domain: {
            data: model.dataTable(),
            // use rank_<field> for ordinal type, for bin and timeUnit use default field
            field: model.field(COLOR, (fieldDef.bin || fieldDef.timeUnit) ? {} : {prefn: 'rank_'}), sort: true
          },
          range: {data: model.dataTable(), field: model.field(COLOR), sort: true}
        });

        // bin needs an additional scale for labels because we want labels in legends
        // because we need to map bin_start to bin_range in legends
        if (fieldDef.bin) {
          scales.push({
            name: COLOR_LABEL,
            type: ORDINAL,
            domain: {
              data: model.dataTable(),
              field: model.field(COLOR,  {prefn: 'rank_'}),
              sort: true
            },
            range: {
              data: model.dataTable(),
              field: field(fieldDef, {binSuffix: '_range'}),
              sort: {
                field: model.field(channel, { binSuffix: '_start' }),
                op: 'min' // min or max doesn't matter since same _range would have the same _start
              }
            }
          });
        }
      }

      scales.push(scaleDef);<commit_msg>Improve readability of comment<commit_after>// https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#11-ambient-declarations
declare var exports;

import {FieldDef} from '../schema/fielddef.schema';

import {contains, extend} from '../util';
import {Model} from './Model';
import {SHARED_DOMAIN_OPS} from '../aggregate';
import {COLUMN, ROW, X, Y, SHAPE, SIZE, COLOR, TEXT, hasScale, Channel} from '../channel';
import {SOURCE, STACKED_SCALE} from '../data';
import {NOMINAL, ORDINAL, QUANTITATIVE, TEMPORAL} from '../type';
import {Mark, BAR, TEXT as TEXT_MARK} from '../mark';
import {rawDomain} from './time';
import {field} from '../fielddef';

// scale from rank to field for ordinal color scale,
// ordinal field to field mapping for binned quantitative and temporal scale with time unit
export const INVERSE_RANK = 'inverse_rank';

// scale used to get labels for binned color scales
export const COLOR_LABEL = 'color_label';

export function compileScales(channels: Channel[], model: Model) {
  return channels.filter(hasScale)
    .reduce(function(scales: any[], channel: Channel) {
      const fieldDef = model.fieldDef(channel);

      var scaleDef: any = {
        name: model.scaleName(channel),
        type: type(fieldDef, channel, model.mark()),
      };

      scaleDef.domain = domain(model, channel, scaleDef.type);
      extend(scaleDef, rangeMixins(model, channel, scaleDef.type));

      // Add optional properties
      [
        // general properties
        'reverse', 'round',
        // quantitative / time
        'clamp', 'nice',
        // quantitative
        'exponent', 'zero',
        // ordinal
        'outerPadding', 'padding', 'points'
      ].forEach(function(property) {
        // TODO include fieldDef as part of the parameters
        const value = exports[property](model, channel, scaleDef.type);
        if (value !== undefined) {
          scaleDef[property] = value;
        }
      });

      // add additional scales needed to support ordinal color scales also for legends
      if (channel === COLOR && fieldDef.legend && (fieldDef.type === ORDINAL || fieldDef.bin || fieldDef.timeUnit)) {
        scales.push({
          name: INVERSE_RANK,
          type: ORDINAL,
          domain: {
            data: model.dataTable(),
            // use rank_<field> for ordinal type, for bin and timeUnit use default field
            field: model.field(COLOR, (fieldDef.bin || fieldDef.timeUnit) ? {} : {prefn: 'rank_'}), sort: true
          },
          range: {data: model.dataTable(), field: model.field(COLOR), sort: true}
        });

        // bin needs an additional scale for labels because we need to map bin_start to bin_range in legends
        if (fieldDef.bin) {
          scales.push({
            name: COLOR_LABEL,
            type: ORDINAL,
            domain: {
              data: model.dataTable(),
              field: model.field(COLOR,  {prefn: 'rank_'}),
              sort: true
            },
            range: {
              data: model.dataTable(),
              field: field(fieldDef, {binSuffix: '_range'}),
              sort: {
                field: model.field(channel, { binSuffix: '_start' }),
                op: 'min' // min or max doesn't matter since same _range would have the same _start
              }
            }
          });
        }
      }

      scales.push(scaleDef);
{'fraction_non_alphanumeric': 0.12651135358301385, 'fraction_numerical': 0.0005897965202005308, 'mean_word_length': 2.3266307013241785, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 2, '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': '7017869', 'n_tokens_mistral': 1929, 'n_tokens_neox': 1880, 'n_words': 584}