2013-11-25 2 views
-1

Я пытаюсь нарисовать связанные линии, используя холст из данных в таблице MySql. Таблица (gene_dna_segments) содержит длину каждого сегмента линии и название сегмента.Canvas and PHP - Рисование связанных сегментов линии

Желаемый выход представляет собой непрерывную прямую горизонтальную линию, состоящую из каждого из сегментов. Каждый сегмент также должен иметь имя сегмента, показывающую выше соответствующего сегмента, как показано на рисунке ниже:

enter image description here

+----------------------+--------------------+------------------+--------------------+ 
| gene_dna_segments_pk | gene_expression_fk | dna_segment_name | dna_segment_length | 
+----------------------+--------------------+------------------+--------------------+ 
|     1 |     11 | Exon 1   |     50 | 
|     2 |     11 | Intron 1   |     75 | 
|     3 |     11 | Exon 2   |     20 | 
|     4 |     11 | Intron 2   |     90 | 
+----------------------+--------------------+------------------+--------------------+ 

Запрос (старинке не PDO ...):

$query_dna = "SELECT * FROM gene_dna_segments WHERE gene_expression_fk = '11'"; 
$result_dna = mysql_query($query_dna, $connection) or die(mysql_error()); 

Дисплей:

<canvas id="canvas" width="800" height="500"></canvas> 
    <script type="text/javascript"> 
    var canvas = document.getElementById('canvas'); 
    var context = canvas.getContext('2d'); 
    <?php 
    while($row_dna = mysql_fetch_assoc($result_dna)) { 

    echo "context.beginPath();context.moveTo(100, 100);context.lineTo(" . $row_dna['dna_segment_length'] . ", 100);context.lineWidth = 12;context.strokeStyle = '#009543';context.stroke();context.font = 'bold 12pt Calibri'; 
    context.fillStyle = '#009543'; 
    context.fillText('" . $row_dna['dna_segment_name'] . "', 180, 90);"; 
    } 
    ?> 
    </script> 

Теперь отрезки и текст, как это определено я n таблица выполнена ОК, но друг над другом, так как context.moveTo(100, 100) одинакова для каждой строки, которая выводится во время цикла while. Как это следует обрабатывать так, чтобы сегменты рисовались как сплошная линия?

Возможно, проще всего добавить столбец начальной точки в таблицу и рассчитать начальные точки для каждого сегмента на основании длиной предыдущего сегмента ... Я открыл отдельный вопрос о такой возможности Calculating new array values based on another numeric array

Обратите внимание, что «нормальный» код для рисования строк похож на следующий код, обратите внимание, что части moveto начинаются в конце предыдущей строки. Мне нужно сделать то же самое в петле ...

var canvas = document.getElementById('canvas'); 
var context = canvas.getContext('2d'); 

context.beginPath(); 
context.moveTo(100, 100); 
context.lineTo(150, 100); 
context.lineWidth = 12; 
context.strokeStyle = '#009543'; 
context.stroke(); 

context.font = 'bold 11pt Calibri'; 
context.fillStyle = '#009543'; 
context.fillText('Exon 1', 105, 90); 

context.beginPath(); 
context.moveTo(150, 100); 
context.lineTo(225, 100); 
context.lineWidth = 12; 
context.strokeStyle = '#e97300'; 
context.stroke(); 

context.font = 'bold 11pt Calibri'; 
context.fillStyle = '#e97300'; 
context.fillText('Intron 1', 165, 90); 

context.beginPath(); 
context.moveTo(225, 100); 
context.lineTo(275, 100); 
context.lineWidth = 12; 
context.strokeStyle = '#009543'; 
context.stroke(); 

context.font = 'bold 11pt Calibri'; 
context.fillStyle = '#009543'; 
context.fillText('Exon 2', 230, 90); 

context.beginPath(); 
context.moveTo(275, 100); 
context.lineTo(375, 100); 
context.lineWidth = 12; 
context.strokeStyle = '#e97300'; 
context.stroke(); 

context.font = 'bold 11pt Calibri'; 
context.fillStyle = '#e97300'; 
context.fillText('Intron 2', 300, 90); 
+0

Предупреждение !!! mysql_ * функции обесцениваются http://stackoverflow.com/q/12859942/829533 – zzlalani

+0

Я хорошо знаю об этом ... – IlludiumPu36

ответ

1

[обновляется на основе новой информации от вопрошающего]

То, что вы описываете горизонтально линейчатый-чарт

Демонстрация: http://jsfiddle.net/m1erickson/RzMWS/

Ваш бархат довольно прост.

Небольшая проблема:

Нам нужно отобразить метку имя_сегмента над каждым баром. В идеальном мире мы могли бы использовать длину сегмента для ширины полосы. Но на самом деле иногда результирующая ширина бара будет слишком узкой, чтобы соответствовать надписи выше.

Поэтому мы должны предварительно обработать данные и определить соответствующий масштабный коэффициент для баров. Путем пропорционального масштабирования баров каждый стержень будет пропорционален их длине сегмента и также будет достаточно широким, чтобы соответствовать метке segment_name.

Здесь прокомментированный код.

Конечно, вы будете читать из своей выборки базы данных вместо чтения тестовых данных в массиве rows [].

<!doctype html> 
<html> 
<head> 
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css --> 
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script> 

<style> 
    body{ background-color: ivory; } 
    #canvas{border:1px solid red;} 
</style> 

<script> 
$(function(){ 

    // get references to the canvas 

    var canvas=document.getElementById("canvas"); 
    var ctx=canvas.getContext("2d"); 
    ctx.font = 'bold 11pt Calibri'; 


    // define the color of the bar for each segment_name 

    var colorCodes={ 
     Exon1:"green", 
     Intron1:"orange", 
     Exon2:"green", 
     Intron2:"orange" 
    }; 


    // create some test data 

    var rows=[]; 
    rows.push({dna_segment_name:"Exon 1",dna_segment_length:50}); 
    rows.push({dna_segment_name:"Intron 1",dna_segment_length:75}); 
    rows.push({dna_segment_name:"Exon 2",dna_segment_length:20}); 
    rows.push({dna_segment_name:"Intron 2",dna_segment_length:90}); 

    // some variables 
    // segments[]: pre-processed data will be saved into segments[] 
    // scaleFactor: scales every bar if any text label fails to fit 
    // padding: allow minimum padding between text labels 

    var segments=[]; 
    var scaleFactor=1; 
    var padding=5; 

    // pre-process 

    // Of course, you will be reading from your database Fetch 
    // instead of this test data in rows[] 

    for(var i=0;i<rows.length;i++){ 

     var $row_dna=rows[i]; 

     // make variables for the segment_name & segment_length 
     // being read from the data fetch 

     var name=$row_dna['dna_segment_name']; 
     var length=$row_dna['dna_segment_length']; 

     // lookup the color for this segment_name 

     var color=colorCodes[name.replace(/\s+/g, '')]; 

     // rescale the bars if any text won't fit 

     var textWidth=ctx.measureText(name).width+padding; 
     var textRatio=textWidth/length; 
     if (textRatio>scaleFactor){ scaleFactor=textRatio; } 

     // save the pre-processed info in a javascript object 
     // for later processing 

     segments.push({ 
      name:name, 
      length:length*scaleFactor, 
      color:color 
     }); 

    } 

    // draw the stacked bar-chart 
    // based on the preprocessed JS objects in segments[] 

    var accumLength=0; 
    var y=100; // the Y-coordinate of the barchart 

    for(var i=0;i<segments.length;i++){ 

     // load the object for the current bar 

     var segment=segments[i]; 

     // set the bar color 

     ctx.fillStyle=segment.color; 

     // draw the bar 

     ctx.fillRect(accumLength,y,segment.length,12); 

     // draw the text label 

     ctx.fillText(segment.name,accumLength,y-10); 

     // accumulate where the next bar will begin 

     accumLength+=segment.length; 
    } 


}); // end $(function(){}); 
</script> 

</head> 

<body> 
    <canvas id="canvas" width=400 height=300></canvas> 
</body> 
</html> 
+0

Линия горизонтальная, поэтому приращение должно происходить на оси x? В любом случае linePosition как отправная точка (moveto) всегда будет одинаковой с вышеуказанным кодом. См. Альтернативный вопрос по адресу http://stackoverflow.com/questions/20186913/php-calculating-start-point-of-line-segments-based-on-previous-segments-length – IlludiumPu36

+0

Думаю, теперь я понимаю ваш вопрос: как для компоновки сетки данных с заголовками + данными + сетками. Если нет, дайте мне знать, и я вернусь завтра. – markE

+0

Я не уверен, что вы все еще понимаете вопрос (хотя я ценю вашу помощь!). Я редактировал OP и прикреплял изображение, показывающее результат, который мне нужен. Обратите внимание, что длины в базе данных относятся к длине строк, а не к тексту. – IlludiumPu36

Смежные вопросы