You are here

function _webform_analysis_number in Webform 7.4

Same name and namespace in other branches
  1. 6.3 components/number.inc \_webform_analysis_number()
  2. 7.3 components/number.inc \_webform_analysis_number()

Implements _webform_analysis_component().

File

components/number.inc, line 425
Webform module number component.

Code

function _webform_analysis_number($component, $sids = array(), $single = FALSE, $join = NULL) {
  $advanced_stats = $single;
  $query = db_select('webform_submitted_data', 'wsd', array(
    'fetch' => PDO::FETCH_ASSOC,
  ))
    ->fields('wsd', array(
    'data',
  ))
    ->condition('wsd.nid', $component['nid'])
    ->condition('wsd.cid', $component['cid']);
  if (count($sids)) {
    $query
      ->condition('wsd.sid', $sids, 'IN');
  }
  if ($join) {
    $query
      ->innerJoin($join, 'ws2_', 'wsd.sid = ws2_.sid');
  }
  $population = array();
  $submissions = 0;
  $non_zero = 0;
  $non_empty = 0;
  $sum = 0;
  $result = $query
    ->execute();
  foreach ($result as $data) {
    $value = trim($data['data']);
    $number = (double) $value;
    $non_empty += (int) ($value !== '');
    $non_zero += (int) ($number != 0.0);
    $sum += $number;
    $population[] = $number;
    $submissions++;
  }
  sort($population, SORT_NUMERIC);

  // Average and population count.
  if ($component['extra']['excludezero']) {
    $average = $non_zero ? $sum / $non_zero : 0;
    $average_title = t('Average !mu excluding zeros/blanks', array(
      '!mu' => $advanced_stats ? '(μ)' : '',
    ));

    // Sample (sub-set of total population).
    $population_count = $non_zero - 1;
    $sigma = 'sd';
    $description = t('sample');
  }
  else {
    $average = $submissions ? $sum / $submissions : 0;
    $average_title = t('Average !mu including zeros/blanks', array(
      '!mu' => $advanced_stats ? '(μ)' : '',
    ));

    // Population.
    $population_count = $submissions;
    $sigma = 'σ';
    $description = t('population');
  }

  // Formatting.
  $average = _webform_number_format($component, $average);
  $sum = _webform_number_format($component, $sum);
  $rows[] = array(
    t('Zero/blank'),
    $submissions - $non_zero,
  );
  $rows[] = array(
    t('User entered value'),
    $non_empty,
  );
  $other[] = array(
    t('Sum') . ($advanced_stats ? ' (Σ)' : ''),
    $sum,
  );
  $other[] = array(
    $average_title,
    $average,
  );
  if (!$advanced_stats && $sum != 0) {
    $other[] = l(t('More stats »'), 'node/' . $component['nid'] . '/webform-results/analysis/' . $component['cid']);
  }

  // Normal distribution information.
  if ($advanced_stats && $population_count && $sum != 0) {

    // Standard deviation.
    $stddev = 0;
    foreach ($population as $value) {

      // Obtain the total of squared variances.
      $stddev += pow($value - $average, 2);
    }
    if ($population_count > 0) {
      $stddev = sqrt($stddev / $population_count);
    }
    else {
      $stddev = sqrt($stddev);
    }

    // Skip the rest of the distribution rows if standard deviation is 0.
    if (empty($stddev)) {
      return array(
        'table_rows' => $rows,
        'other_data' => $other,
      );
    }

    // Build normal distribution table rows.
    $count = array();
    $percent = array();
    $limit = array();
    $index = 0;
    $count[] = 0;
    $limit[] = $average - $stddev * 4;
    foreach ($population as $value) {
      while ($value >= $limit[$index]) {
        $percent[] = number_format($count[$index] / $population_count * 100, 2, '.', '');
        $limit[] = $limit[$index] + $stddev;
        $index += 1;
        if ($limit[$index] == $average) {
          $limit[$index] = $limit[$index] + $stddev;
        }
        $count[$index] = 0;
      }
      $count[$index] += 1;
    }
    $percent[] = number_format($count[$index] / $population_count * 100, 2, '.', '');

    // Format normal distribution table output.
    $stddev = _webform_number_format($component, $stddev);
    $low = _webform_number_format($component, $population[0]);
    $high = _webform_number_format($component, end($population));
    foreach ($limit as $key => $value) {
      $limit[$key] = _webform_number_format($component, $value);
    }

    // Column headings (override potential theme uppercase, for example, Seven in D7).
    $header = array(
      t('Normal Distribution'),
      array(
        'data' => '-4' . $sigma,
        'style' => 'text-transform: lowercase;',
      ),
      array(
        'data' => '-3' . $sigma,
        'style' => 'text-transform: lowercase;',
      ),
      array(
        'data' => '-2' . $sigma,
        'style' => 'text-transform: lowercase;',
      ),
      array(
        'data' => '-1' . $sigma,
        'style' => 'text-transform: lowercase;',
      ),
      array(
        'data' => '+1' . $sigma,
        'style' => 'text-transform: lowercase;',
      ),
      array(
        'data' => '+2' . $sigma,
        'style' => 'text-transform: lowercase;',
      ),
      array(
        'data' => '+3' . $sigma,
        'style' => 'text-transform: lowercase;',
      ),
      array(
        'data' => '+4' . $sigma,
        'style' => 'text-transform: lowercase;',
      ),
    );

    // Insert row labels.
    array_unshift($limit, t('Boundary'));
    array_unshift($count, t('Count'));
    array_unshift($percent, t('% of !description', array(
      '!description' => $description,
    )));
    $normal_distribution = theme('table', array(
      'header' => $header,
      'rows' => array(
        $limit,
        $count,
        $percent,
      ),
      'sticky' => FALSE,
    ));
    $other[] = array(
      t('Range'),
      t('!low to !high', array(
        '!low' => $low,
        '!high' => $high,
      )),
    );
    $other[] = array(
      t('Standard deviation (!sigma)', array(
        '!sigma' => $sigma,
      )),
      $stddev,
    );
    $other[] = $normal_distribution;
  }
  return array(
    'table_rows' => $rows,
    'other_data' => $other,
  );
}