可变动态跨度重叠

时间:2012-05-30 12:53:49

标签: php html

$lines = file("res_example.txt");

$resArr = array();
foreach ($lines as $line_num => $line) {
  $columns = explode("\t", $line);
  $raws = $columns['1'];
  $hits = $columns['2'];
  $names = $columns['0'];
  $models = $columns['3'];
  $colors = $columns['4'];
  $allModels[$models] = 1;
  $resArr[] = array(
    name => $names,
    score => $raws,
    hit => $hits,
    model => $models,
    color => $colors
  );
}


$seqArr = array('A', 'T', 'C', 'G');
$randseq = array();

for ($i = 0; $i < 1000; $i++) {
  $randseq[] = $seqArr[array_rand($seqArr)];
}

$res = "";

echo "<div id=\"coltext\" style=\"font-family:monospace;\">";

foreach ($allModels as $modName => $value) {

  echo "<input ModelName=$modName type=\"checkbox\"
  checked==\"TRUE\" onclick=\"toggle.apply(this)\" />$modName";

}

echo "<hr />";
$score = rawtransform($raw);
foreach ($randseq as $index => $nuc) {
  $index = $index + 1;
  foreach ($resArr as $hitArr) {
    $hit = $hitArr['hit'];
    $raw = $hitArr['score'];
    $model = $hitArr['model'];
    $colval = $hitArr['color'];
    $score = rawtransform($raw);

    $color = getcolor($score, $colval);

    if (($hit+3) == $index) { 
      echo "</span>";
    }
    if ($hit == $index) { 
      echo "<span class=$model Title=\"position:$index,score:$raw\"
      style=\"background:$color;\" color=\"$color\">";
      //problem when theres overlap !? 
    }

  }

  echo $nuc;

  if (($index%50)==0){
    echo"<br />";
  }
}

echo "</div>";

function rawtransform($raw) {
  return (int)($raw/50)-9;
}

function getcolor($score,$ArrayModelval)
{
switch ($score){
// working.  test each color. 
case 1: /*500-550(Raw Score)*/
        $col=$ArrayModelval;
            return"hsl( $col,100%,90%)";
    break;
case 2: //550-600
        $col=$ArrayModelval;
            return "hsl( $col,100%,85%)";
    break;
case 3: //600-650
        $col=$ArrayModelval;
            return "hsl( $col,100%,85%)";
    break;
case 4: //650-700
        $col=$ArrayModelval;
            return"hsl( $col,100%,80%)";
    break;
case 5: //700-750
        $col=$ArrayModelval;
            return"hsl( $col,100%,70%)";
    break;
case 6: //750-800
        $col=$ArrayModelval;
            return "hsl( $col,100%,60%)";
    break;
case 7: //800-850
        $col=$ArrayModelval;
            return "hsl( $col,100%,50%)";
    break;
case 8: //850-900;
        $col=$ArrayModelval;
            return "hsl( $col,100%,50%)";
    break;
case 9: //900-950
        $col=$ArrayModelval;
            return "hsl( $col,100%,40%)";
    break;
case 10: //950-1000
        $col=$ArrayModelval;
    return "hsl($col,100%,40%)";
    break;

   }
}

在大多数情况下我做了我想要的:我想为随机序列的部分着色,其中有$hit - 在外部文件上定义。我唯一的问题是当有任何重叠时,即如果两个命中在彼此的3个基底之内,那么跨度就会拉长并且就像它的一个跨度一样着色。

外部文件有一个位置,可以根据外部文件中给出的分数开始具有可变颜色的跨度。基本上如果我有3个结果,其中2个具有几乎相同的命中(+ -1)而另一个具有不同的命中,我只会看到两个部分着色,任何人都可以看到我的问题是什么?对不起,我知道我可能措辞可怕,但很难解释。感谢。

>chr1:2198584545754_genome_1000+    500 1000    Model1  0
>chr2:2198581212154_genome_1000+    510 992     Model2  180
>chr3:2115151215754_genome_1000+    520 990     Model3  330  
>chr4:2198584545754_genome_1000+    530 980     Model3  330 
>chr5:1218455145754_genome_1000+    540 970     Model2  180
>chr6:1231354645454_genome_1000+    550 960     Model1  0
>chr7:1231213211134_genome_1000+    600 950     Model3  330
>chr7:1231213211134_genome_1000+    650 940     Model3  330

的javascript:

function toggle() {
var div= document.getElementById('coltext');
var modName=this.getAttribute('ModelName');
var spans=div.getElementsByTagName('span');
var spans_l=spans.length;
while (spans_l--){
    span=spans[spans_l];
    if(span.getAttribute('class')==modName && this.checked==true){
        var color= span.getAttribute('color');

        span.style.background=color;
    }
    if(span.getAttribute('class')==modName && this.checked==false){
        span.style.background="white";
    }
}

}

1 个答案:

答案 0 :(得分:1)

尝试使用此尺寸。它通过使用FIFO堆栈$currentHits来处理命中边界。我还添加了一些辅助函数来处理颜色生成 - 如果你改变你的getcolor()函数来返回一个数组而不是一个CSS字符串,其中一个可以被删除,从而提高效率。

我无法对此进行测试,因为我没有getcolor()rawtransform()函数的源代码 - 如果您将这些添加到问题中,我确定可以进一步改进我可以正确地测试代码。此外,最好看看你的CSS Model1Model2等类是什么样的。

编辑:现在包含 getcolor() / rawtransform() 函数和(至少部分)tested

<?php

  function rawtransform ($raw) {
    return (int) ($raw / 50) - 9;
  }
  function getcolor ($score, $h) {
    switch ($score) {
      // working.  test each color. 
      case 1: /*500-550(Raw Score)*/
        $l = 90;
        break;
      case 2: case 3: //550-650
        $l = 85;
        break;
      case 4: //650-700
        $l = 80;
        break;
      case 5: //700-750
        $l = 70;
        break;
      case 6: //750-800
        $l = 60;
        break;
      case 7: case 8: //800-900;
        $l = 50;
        break;
      case 9: case 10: default: //900-1000 / out of range
        $l = 40;
        break;
    }
    return array(
      'h' => $h,
      's' => 100,
      'l' => $l
    );
  }

  function hsl_average_color () {
    // Takes an unlimited number of arguments, calculates the average HSL value and returns a CSS string
    $args = func_get_args();
    $h = $s = $l = array();
    foreach ($args as $arg) {
      $h[] = $arg['h'];
      $s[] = $arg['s'];
      $l[] = $arg['l'];
    }
    return sprintf('hsl(%d, %d%%, %d%%)', (int) round(array_sum($h) / count($h)), (int) round(array_sum($s) / count($s)), round(array_sum($l) / count($l)));
  }

  $fileName = 'res_example.txt';

  // Open the file
  if (!$fp = fopen($fileName, 'r')) {
    // Handle file read errors here
    die("Unable to open file $fileName");
  }

  // Loop the file data and build an associative array
  $resArr = array();
  while (($line = fgetcsv($fp, 0, "\t")) !== FALSE) {

    // You didn't declare $allModels as an empty array before the loop
    // Should you have?
    $allModels[$line[3]] = 1;

    // Note that I have dropped the hit key and instead keyed the outer
    // array by this value. I have added an end key to track the end of
    // a hit
    $resArr[$line[2]] = array(
      'name' => $line[0],
      'score' => $line[1],
      'end' => $line[2] + 4,
      'model' => $line[3],
      'color' => getcolor(rawtransform($line[1]), $line[4])
    );

  }

  // Close the file
  fclose($fp);

  // Generate a random sequence
  $seqArr = array('A', 'T', 'C', 'G');
  $randseq = array();
  for ($i = 0; $i < 1000; $i++) {
    $randseq[] = $seqArr[array_rand($seqArr)];
  }

  // $res appears to do nothing in you code
  // $res = "";

  // Open the <div>
  echo '<div id="coltext" style="font-family:monospace;background-color:#000000;color:#FFFFFF;">'."\n";

  // Iterate over $allModels and echo checkboxes
  foreach ($allModels as $modName => $value) {

    // ModelName is a non-standard HTML attribute, are you sure you meant to do this?
    echo '<input ModelName="'.$modName.'" type="checkbox" checked="checked" onclick="toggle.apply(this);" />'.$modName."\n";

  }

  echo "<hr />\n";

  // This line does nothing useful here
  // $score = rawtransform($raw);

  // An array to track the current hits
  $currentHits = array();

  foreach ($randseq as $index => $nuc) {

    // Increment $index
    $index++;

    // Track whether we are in a hit/reached a boundary
    $boundary = FALSE;
    $inHit = (bool) count($currentHits);

    // Check whether we are at the end of the lowest hit in the stack
    if ($inHit && $index == $currentHits[0]['end']) {
      $boundary = TRUE;
      array_shift($currentHits);    
    }

    // Check whether we are at the start of a new hit
    if (isset($resArr[$index])) {
      $boundary = TRUE;
      $currentHits[] = $resArr[$index];    
    }

    // If we reached a boundary
    if ($boundary) {

      // Close a hit    
      if ($inHit) {
        echo "</span>";
      }

      // Open a hit
      if (count($currentHits)) {

        // Get the current color value
        $colors = array();
        foreach ($currentHits as $hit) $colors[] = $hit['color'];
        $color = call_user_func_array('hsl_average_color', $colors);

        // Start a new span
        echo '<span class="'.$currentHits[0]['model'].'" title="position:'.$index.',score:'.$currentHits[0]['score'].'" style="color: '.$color.';">';

      }

    }

    // Print the character
    echo $nuc;

    // Split into 50 character chunks        
    if (!($index % 50)){
      echo"<br />\n";
    }

  }

  // Close the last span if one is still open
  if (count($currentHits)) {
    echo "</span>";
  }

  // Close the <div>        
  echo "</div>\n";