$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";
}
}
}
答案 0 :(得分:1)
尝试使用此尺寸。它通过使用FIFO堆栈$currentHits
来处理命中边界。我还添加了一些辅助函数来处理颜色生成 - 如果你改变你的getcolor()
函数来返回一个数组而不是一个CSS字符串,其中一个可以被删除,从而提高效率。
我无法对此进行测试,因为我没有此外,最好看看你的CSS getcolor()
或rawtransform()
函数的源代码 - 如果您将这些添加到问题中,我确定可以进一步改进我可以正确地测试代码。Model1
,Model2
等类是什么样的。
编辑:现在包含 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";