<commit_before>/*jslint indent: 2, onevar: false, browser: true, onevar: false, white: false  */
/*global $, cyoc */

if(popConnect === undefined) {
  var popConnect = {};
}

popConnect.DataViewer = function(element, options) {
  // Private member variables
  var data = {                    // This is where the response to the JSON request will go
    id: options.reportId,
    numerator_fields: [],
    denominator_fields: []       // These fields should match up letter-for-letter with the actual field names
  };

  var rootElement = $(element);             // Root DOM element for UI
  var dataUrl = options.dataUrl || '/data'; // Where to get data from...not restful, whatever
  var that = this;                          // Traditional javascript nonsense
  var busyness = 0;                         // Current number of jobs. Controls when loading indicator is shown. Don't change directly, use busy/notBusy
  this.onComplete = options.complete;        // Callback for when data is loaded
  this.onError = options.error;              // Callback for when data doesn't load
  this.counters = []

  // It's sort of arbitrary to split dataDefinition out this way, but I think
  // the individual unit to consider is each section.
  var dataDefinition = options.dataDefinition || {
    types: {
      demographics: {
        label: 'Demographics',
        types: {
          gender: {label: 'Gender', sort: ['Male', 'Female']},
          age: {label: 'Age', sort: ['18-34', '35-49', '50-64', '65-75', '76+']}
        },
        sort: ['gender', 'age']
      },
      treatments: {
        label: 'Treatments',
        types: {
          medications: {label: 'Medications', sort: ['Aspirin']},
          therapies: {label: 'Therapies', sort: ['Smoking Cessation']}
        },
        sort: ['medications', 'therapies']
      },
      risk_factors: {
        label: 'Risk Factors',
        types: {
          blood_pressures: {label: 'Blood Pressure', sort: ['90-119/60-79', '120-139/80-89', '140-159/90-99', '>160/>100']},
          cholesterol: {label: 'Cholesterol', sort: ['<100', '100-129', '130-159', '160-189', '>190']},
          smoking: {label: 'Smoking', sort: ['Non-smoker', 'Ex-smoker', 'Smoker']}
        },
        sort: ['blood_pressures', 'cholesterol', 'smoking']
      },
      disease_conditions: {
        label: 'Disease & Conditions',
        types: {
          diabetes: {label: 'Diabetes', sort: ['Yes', 'No']},
          hypertension: {label: 'Hypertension', sort: ['Yes', 'No']}
        },
        sort: ['diabetes', 'hypertension']
      }
    },
    sort: ['demographics', 'risk_factors', 'disease_conditions', 'treatments']
  };

  var irregularLabels = {
    diabetes: {'Yes': 'Diabetes', 'No': 'Without Diabetes'},
    hypertension: {'Yes': 'Hypertension', 'No': 'Without Hypertension'},
  }

  // Public functions

  // ........ are there any ??? ..........

  // Priviledged functions
  // Can access both public and private variables and methods

  // This probably shouldn't be used...but I'm adding it just in case
  this.getData = function() {
    return data;
  };

  this.selectReport = function(id) {
    busy();
    that.reload({id: id}, 'GET');
  }

  this.newReport = function() {
    busy();
    data = {
      numerator_fields: [],
      denominator_fields: []       // These fields should match up letter-for-letter with the actual field names
    };
    that.reload(buildTailoredData(), 'POST')
  }

  // Reload DOM elements from data
  this.refresh = function() {
    // Assumes the markup is already there and domNode properties have been set correctly
    // ie don't call this if the DOM element is missing! Call buildInitialDom...

    // clear any previous counters a counting (happens when users are trigger happy)
    while(this.counters.length>0){
      clearInterval(this.counters.pop());
    }

    if(data.title) {
      dataDefinition.reportTitle.text(data.title).removeClass('disabled');
      dataDefinition.changedReportTitle.val(data.title);
    } else {
      dataDefinition.reportTitle.text('click to name report').addClass('disabled');
      dataDefinition.changedReportTitle.val('Type report name');
    }

    // Assume the dom nodes already exist and have been set
    var percentage = 0;   // Giant percentage number
    var startpercent = 0;
    var startdenom = 0;
    var startnumer = 0;
    if(dataDefinition.masterPercentageDomNode.text()){
      startpercent = dataDefinition.masterPercentageDomNode.text().replace('%', '')
    }
    if(dataDefinition.denominatorValueDomNode.text()){
      startdenom = dataDefinition.denominatorValueDomNode.text()
    }
    if(dataDefinition.numeratorValueDomNode.text()){
      startnumer = dataDefinition.numeratorValueDomNode.text()
    }

    // Let's run the calculations on the data...
    if(data.denominator > 0) {
      percentage = data.numerator / data.denominator * 100; // Dividing by 0 apparently doesn't work!! Who knew!?
      dataDefinition.denominatorValueDomNode.removeClass('disabled').text( addCommas(data.denominator) );
      // var dc = new popConnect.Counter(startdenom, data.denominator, dataDefinition.denominatorValueDomNode)
      // this.counters.push(dc.interval);

    } else {
      dataDefinition.denominatorValueDomNode.addClass('disabled').text(data.denominator);
    }

    if(data.numerator > 0) {
      dataDefinition.numeratorValueDomNode.removeClass('disabled').text( addCommas(data.numerator) );
      // var nc = new popConnect.Counter(startnumer, data.numerator, dataDefinition.numeratorValueDomNode)
      // this.counters.push(nc.interval);

    } else {
      dataDefinition.numeratorValueDomNode.addClass('disabled').text(data.numerator);
    }
    if(percentage == 0) {
      dataDefinition.masterPercentageDomNode.addClass('disabled').text('0').append( $('<span>').text('%') );
    } else if (percentage < 0.5) {
      dataDefinition.masterPercentageDomNode.addClass('disabled').text('<1').append( $('<span>').text('%') );
    } else {
      //dataDefinition.masterPercentageDomNode.removeClass('disabled').text(Math.round(percentage) + '%');
      dataDefinition.masterPercentageDomNode.removeClass('disabled');
      var pc = new popConnect.Counter(startpercent, Math.round(percentage), dataDefinition.masterPercentageDomNode, '%')
      this.counters.push(pc.interval);
//      countNums(startpercent, Math.round(percentage), dataDefinition.masterPercentageDomNode)
    }



    dataDefinition.numeratorFieldsDomNode.empty();
    var hasNumerator = false; // There must be a better way to do that
    var key;
    for(key in data.numerator_fields) {
      if(data.numerator_fields.hasOwnProperty(key)) {
        hasNumerator = true;
        $(data.numerator_fields[key]).each(function(i, value) {
          var span = $('<span>');
          if(irregularLabels[key]) {<commit_msg>added irregularLabels for BP and Chol<commit_after>/*jslint indent: 2, onevar: false, browser: true, onevar: false, white: false  */
/*global $, cyoc */

if(popConnect === undefined) {
  var popConnect = {};
}

popConnect.DataViewer = function(element, options) {
  // Private member variables
  var data = {                    // This is where the response to the JSON request will go
    id: options.reportId,
    numerator_fields: [],
    denominator_fields: []       // These fields should match up letter-for-letter with the actual field names
  };

  var rootElement = $(element);             // Root DOM element for UI
  var dataUrl = options.dataUrl || '/data'; // Where to get data from...not restful, whatever
  var that = this;                          // Traditional javascript nonsense
  var busyness = 0;                         // Current number of jobs. Controls when loading indicator is shown. Don't change directly, use busy/notBusy
  this.onComplete = options.complete;        // Callback for when data is loaded
  this.onError = options.error;              // Callback for when data doesn't load
  this.counters = []

  // It's sort of arbitrary to split dataDefinition out this way, but I think
  // the individual unit to consider is each section.
  var dataDefinition = options.dataDefinition || {
    types: {
      demographics: {
        label: 'Demographics',
        types: {
          gender: {label: 'Gender', sort: ['Male', 'Female']},
          age: {label: 'Age', sort: ['18-34', '35-49', '50-64', '65-75', '76+']}
        },
        sort: ['gender', 'age']
      },
      treatments: {
        label: 'Treatments',
        types: {
          medications: {label: 'Medications', sort: ['Aspirin']},
          therapies: {label: 'Therapies', sort: ['Smoking Cessation']}
        },
        sort: ['medications', 'therapies']
      },
      risk_factors: {
        label: 'Risk Factors',
        types: {
          blood_pressures: {label: 'Blood Pressure', sort: ['90-119/60-79', '120-139/80-89', '140-159/90-99', '>160/>100']},
          cholesterol: {label: 'Cholesterol', sort: ['<100', '100-129', '130-159', '160-189', '>190']},
          smoking: {label: 'Smoking', sort: ['Non-smoker', 'Ex-smoker', 'Smoker']}
        },
        sort: ['blood_pressures', 'cholesterol', 'smoking']
      },
      disease_conditions: {
        label: 'Disease & Conditions',
        types: {
          diabetes: {label: 'Diabetes', sort: ['Yes', 'No']},
          hypertension: {label: 'Hypertension', sort: ['Yes', 'No']}
        },
        sort: ['diabetes', 'hypertension']
      }
    },
    sort: ['demographics', 'risk_factors', 'disease_conditions', 'treatments']
  };

  var irregularLabels = {
    diabetes: {'Yes': 'Diabetes', 'No': 'Without Diabetes'},
    hypertension: {'Yes': 'Hypertension', 'No': 'Without Hypertension'},
    blood_pressures: {'90-119/60-79': 'BP 90-119/60-79', '90-119/60-79': 'BP 90-119/60-79', '120-139/80-89': 'BP 120-139/80-89', '140-159/90-99':'BP 140-159/90-99', '>160/>100':'BP >160/>100'},
    cholesterol: {'<100': 'Chol <100', '100-129':'Chol 100-129', '130-159':'Chol 130-159', '160-189':'Chol 160-189', '>190':'Chol >190'}
  }

  // Public functions

  // ........ are there any ??? ..........

  // Priviledged functions
  // Can access both public and private variables and methods

  // This probably shouldn't be used...but I'm adding it just in case
  this.getData = function() {
    return data;
  };

  this.selectReport = function(id) {
    busy();
    that.reload({id: id}, 'GET');
  }

  this.newReport = function() {
    busy();
    data = {
      numerator_fields: [],
      denominator_fields: []       // These fields should match up letter-for-letter with the actual field names
    };
    that.reload(buildTailoredData(), 'POST')
  }

  // Reload DOM elements from data
  this.refresh = function() {
    // Assumes the markup is already there and domNode properties have been set correctly
    // ie don't call this if the DOM element is missing! Call buildInitialDom...

    // clear any previous counters a counting (happens when users are trigger happy)
    while(this.counters.length>0){
      clearInterval(this.counters.pop());
    }

    if(data.title) {
      dataDefinition.reportTitle.text(data.title).removeClass('disabled');
      dataDefinition.changedReportTitle.val(data.title);
    } else {
      dataDefinition.reportTitle.text('click to name report').addClass('disabled');
      dataDefinition.changedReportTitle.val('Type report name');
    }

    // Assume the dom nodes already exist and have been set
    var percentage = 0;   // Giant percentage number
    var startpercent = 0;
    var startdenom = 0;
    var startnumer = 0;
    if(dataDefinition.masterPercentageDomNode.text()){
      startpercent = dataDefinition.masterPercentageDomNode.text().replace('%', '')
    }
    if(dataDefinition.denominatorValueDomNode.text()){
      startdenom = dataDefinition.denominatorValueDomNode.text()
    }
    if(dataDefinition.numeratorValueDomNode.text()){
      startnumer = dataDefinition.numeratorValueDomNode.text()
    }

    // Let's run the calculations on the data...
    if(data.denominator > 0) {
      percentage = data.numerator / data.denominator * 100; // Dividing by 0 apparently doesn't work!! Who knew!?
      dataDefinition.denominatorValueDomNode.removeClass('disabled')//.text( addCommas(data.denominator) );
      var dc = new popConnect.Counter(startdenom, data.denominator, dataDefinition.denominatorValueDomNode)
      this.counters.push(dc.interval);

    } else {
      dataDefinition.denominatorValueDomNode.addClass('disabled').text(data.denominator);
    }

    if(data.numerator > 0) {
      dataDefinition.numeratorValueDomNode.removeClass('disabled')//.text( addCommas(data.numerator) );
      var nc = new popConnect.Counter(startnumer, data.numerator, dataDefinition.numeratorValueDomNode)
      this.counters.push(nc.interval);

    } else {
      dataDefinition.numeratorValueDomNode.addClass('disabled').text(data.numerator);
    }
    if(percentage == 0) {
      dataDefinition.masterPercentageDomNode.addClass('disabled').text('0').append( $('<span>').text('%') );
    } else if (percentage < 0.5) {
      dataDefinition.masterPercentageDomNode.addClass('disabled').text('<1').append( $('<span>').text('%') );
    } else {
      //dataDefinition.masterPercentageDomNode.removeClass('disabled').text(Math.round(percentage) + '%');
      dataDefinition.masterPercentageDomNode.removeClass('disabled');
      var pc = new popConnect.Counter(startpercent, Math.round(percentage), dataDefinition.masterPercentageDomNode, '%')
      this.counters.push(pc.interval);
//      countNums(startpercent, Math.round(percentage), dataDefinition.masterPercentageDomNode)
    }



    dataDefinition.numeratorFieldsDomNode.empty();
    var hasNumerator = false; // There must be a better way to do that
    var key;
    for(key in data.numerator_fields) {
      if(data.numerator_fields.hasOwnProperty(key)) {
        hasNumerator = true;
        $(data.numerator_fields[key]).each(function(i, value) {
          var span = $('<span>');
          if(irregularLabels[key]) {
{'fraction_non_alphanumeric': 0.1456241543829666, 'fraction_numerical': 0.023214412874741866, 'mean_word_length': 2.9717194570135748, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 27, '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': '5738979', 'n_tokens_mistral': 4442, 'n_tokens_neox': 4100, 'n_words': 1013}