试图使用JQuery在表数据上绘制线条

时间:2015-11-29 22:31:41

标签: jquery

当数据在特定时间段内匹配时,我试图在表格中绘制线条。像这样:
enter image description here

黑线与上一行的数字相匹配 蓝线匹配从一行到前两行的数字(ID# - 2) 红线匹配从一行到三行(ID# - 3)的数字。

如何添加JQuery以在具有此类数据的表上绘制这些行:

WebApiConfig.Register(config);

假设我有一个链接到页面的JQuery库,那么什么JQuery代码抓住该行,分析它匹配的内容,然后为这两个数字画一条线?

我发现这篇文章是关于如何使用JQuery和.js创建行,但我不知道.js足以适应我的应用程序。 http://www.monkeyandcrow.com/blog/drawing_lines_with_css3/

我的想法是,我可以改变下面代码中的div,page和&line;以适合我的实际表格和行。

<section>
        <article>
            <h3>Number Sets</h3>
            <table id="dataset">
                <thead><tr><th>ID</th><th>1st #</th><th>2nd #</th><th>3rd #</th><th>4th #</th><th>5th #</th><th>6th #</th><th>Sum of</th><th>Avg of</th></tr></thead>
                <tbody>
                <tr class="2405"><td># 2405</td><td class="v9">9</td><td class="v17">17</td><td class="v24">24</td><td class="v34">34</td><td class="v43">43</td><td class="v49">49</td><td class="v176">176</td><td class="v29.33">29.33</td></tr>
                <tr class="2404"><td># 2404</td><td class="v22">22</td><td class="v26">26</td><td class="v31">31</td><td class="v32">32</td><td class="v43">43</td><td class="v45">45</td><td class="v198">198</td><td class="v33.00">33.00</td></tr>
                <tr class="2403"><td># 2403</td><td class="v7">7</td><td class="v11">11</td><td class="v18">18</td><td class="v44">44</td><td class="v53">53</td><td class="v54">54</td><td class="v187">187</td><td class="v31.17">31.17</td></tr>
                <tr class="2402"><td># 2402</td><td class="v14">14</td><td class="v15">15</td><td class="v27">27</td><td class="v37">37</td><td class="v44">44</td><td class="v47">47</td><td class="v184">184</td><td class="v30.67">30.67</td></tr>
                <tr class="2401"><td># 2401</td><td class="v37">37</td><td class="v54">54</td><td class="v31">31</td><td class="v6">6</td><td class="v26">26</td><td class="v15">15</td><td class="v169">169</td><td class="v28.17">28.17</td></tr>
                <tr class="2400"><td># 2400</td><td class="v39">39</td><td class="v35">35</td><td class="v38">38</td><td class="v41">41</td><td class="v22">22</td><td class="v34">34</td><td class="v209">209</td><td class="v34.83">34.83</td></tr>
                <tr class="2399"><td># 2399</td><td class="v9">9</td><td class="v12">12</td><td class="v18">18</td><td class="v31">31</td><td class="v34">34</td><td class="v51">51</td><td class="v155">155</td><td class="v25.83">25.83</td></tr>
                <tr class="2398"><td># 2398</td><td class="v1">1</td><td class="v29">29</td><td class="v14">14</td><td class="v46">46</td><td class="v38">38</td><td class="v26">26</td><td class="v154">154</td><td class="v25.67">25.67</td></tr>
                <tr class="2397"><td># 2397</td><td class="v35">35</td><td class="v6">6</td><td class="v8">8</td><td class="v30">30</td><td class="v47">47</td><td class="v42">42</td><td class="v168">168</td><td class="v28.00">28.00</td></tr>
                <tr class="2396"><td># 2396</td><td class="v45">45</td><td class="v25">25</td><td class="v4">4</td><td class="v33">33</td><td class="v49">49</td><td class="v48">48</td><td class="v204">204</td><td class="v34.00">34.00</td></tr>
                <tr class="2395"><td># 2395</td><td class="v11">11</td><td class="v9">9</td><td class="v37">37</td><td class="v44">44</td><td class="v25">25</td><td class="v17">17</td><td class="v143">143</td><td class="v23.83">23.83</td></tr>
                <tr class="2394"><td># 2394</td><td class="v48">48</td><td class="v12">12</td><td class="v7">7</td><td class="v14">14</td><td class="v41">41</td><td class="v21">21</td><td class="v143">143</td><td class="v23.83">23.83</td></tr>
                <tr class="2393"><td># 2393</td><td class="v2">2</td><td class="v14">14</td><td class="v9">9</td><td class="v35">35</td><td class="v22">22</td><td class="v36">36</td><td class="v118">118</td><td class="v19.67">19.67</td></tr>
                <tr class="2392"><td># 2392</td><td class="v37">37</td><td class="v49">49</td><td class="v36">36</td><td class="v52">52</td><td class="v16">16</td><td class="v45">45</td><td class="v235">235</td><td class="v39.17">39.17</td></tr>
                <tr class="2391"><td># 2391</td><td class="v14">14</td><td class="v36">36</td><td class="v2">2</td><td class="v6">6</td><td class="v50">50</td><td class="v26">26</td><td class="v134">134</td><td class="v22.33">22.33</td></tr>              
                </tbody>
            </table>
        </article>
    </section>

来自此代码

var line = $('<div>')
.appendTo('#page')
 .addClass('line')
然而,我不确定他们在做什么。我确实为function createLine(x1,y1, x2,y2){ var length = Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)); var angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI; var transform = 'rotate('+angle+'deg)'; var line = $('<div>') .appendTo('#page') .addClass('line') .css({ 'position': 'absolute', 'transform': transform }) .width(length) .offset({left: x1, top: y1}); return line; } <tr>添加了特定于变量的类名来帮助解决这个问题。我不知道也许他们不需要。

有什么需要改变以使其自动生成表格单元格的线条?

1 个答案:

答案 0 :(得分:2)

我想我最终为你编写了代码LOL ......这是一个有趣的难题:D

this demo中,您可以修改前几行作为选项 - 定位表,表格包装,开始和放大。结束列,distance包含css类名。

一旦将所有线条添加到表格中,它看起来就像是被意大利面条怪物攻击了。所以我在底部添加了一些额外的代码,允许将鼠标悬停在匹配的行上。

CSS

article {
    position: relative;
}
table, th, td {
    border-collapsed: collapse;
    border: #000 1px solid;
    padding: 3px;
}
.line {
    transform-origin: 0 100%;
    height: 3px;
    border: 0;
}
.blue {
    background-color: blue;
}
.red {
    background-color: red;
}
.black {
    background-color: black;
}

脚本

var $table = $('table'),
    $attachLinesTo = $('#dataset-wrap'),
    startColumn = 1,
    endColumn = 6,

    // black = 1 line, blue = 2, red = 3+
    distance = [ 'black', 'blue', 'red' ],

    // adjust line position (pixels)
    xAdj = 0,
    yAdj = 0;

// don't modify anything below
var $rows = $table.children('tbody').children('tr');

function createLine(x1, y1, x2, y2, colorClass) {
    var length = Math.sqrt( ( x1 - x2 ) * ( x1 - x2 ) + ( y1 - y2 ) * ( y1 - y2 ) ),
        angle = Math.atan2( y2 - y1, x2 - x1 ) * 180 / Math.PI;
    return $( '<div>' )
        .appendTo( $attachLinesTo )
        .addClass( 'line ' + colorClass )
        .css({
            position : 'absolute',
            transform : 'rotate(' + angle + 'deg)'
        })
        .width( length )
        .offset({
            left : x1,
            top : y1
        });
}

function getValues() {
    var indx, row, col,
        data = [],
        rowsLen = $rows.length;
    for ( indx = 0; indx < rowsLen; indx++ ) {
        row = [];
        for ( col = startColumn; col <= endColumn; col++ ) {
            // save cell contents for row
            row.push( parseInt( $rows.eq( indx ).children().eq( col ).text(), 10 ) );
        }
        // save row array
        data.push( row );
    }
    return data;
}
function findDuplicates() {
    var indx, row, rowArry, col, val, index,
        array = getValues(),
        len = array.length,
        xref = {};
    for ( row = 0; row < len - 1; row++ ) {
        rowArry = array[ row ];
        for ( col = 0; col < rowArry.length; col++ ) {
            val = rowArry[ col ];
            if ( $.isEmptyObject( xref[ val ] ) ) {
                // each value in the table gets a cross reference with a row & col index
                // (col starts from "startColumn" value, not zero)
                xref[ val ] = { row: [], col: [] };
            }
            for ( indx = row; indx < len; indx++ ) {
                // indexOf (array) not supported in IE8... but neither are css3 transforms
                index = array[ indx ].indexOf( val );
                if ( index > -1 ) {
                    // don't add duplicates in cross reference
                    // *** NOTE *** this will cause issues if two of the same value is in the same row
                    if ( xref[ val ].row.indexOf( indx ) < 0 ) {
                        xref[ val ].row.push( indx );
                        xref[ val ].col.push( index );
                    }
                }
            }
        }
    }
    return xref;
}
function getCoords( row, col ) {
    var $cell = $rows.eq( row ).children().eq( col ),
        width = $cell.width(),
        height = $cell.height(),
        pos = $cell.offset();
    // return x & y pixel coordinates from center of table cell
    return {
        x: pos.left + width/2 + xAdj,
        y: pos.top + height/2 + yAdj
    };
}
function draw() {
    var val, value, indx, len, pos, x, y, color,
        maxDist = distance.length - 1,
        data = findDuplicates();
    for ( val in data ) {
        if ( data[ val ].row ) {
            value = data[ val ];
            len = value.row.length - 1;
            // ignore if value is unique
            if ( len > 0 ) {
                for ( indx = 0; indx < len; indx++ ) {
                    // get line starting position
                    pos = getCoords( value.row[ indx ], value.col[ indx ] + startColumn );
                    x = pos.x;
                    y = pos.y;
                    // get line ending position
                    pos = getCoords( value.row[ indx + 1 ], value.col[ indx + 1 ] + startColumn );
                    // adjust colors... add 1 to index so distance array doesn't need to have "" at the zero index
                    color = distance[ Math.abs( value.row[ indx ] - value.row[ indx + 1 ] + 1 ) ] || distance[ maxDist ];
                    // draw line - add color + cell value for hovering code
                    createLine( x, y, pos.x, pos.y, color + ' ' + color + val );
                }
            }
        }
    }
}
// Initialize draw
draw();
var $lines = $('.line');
// hover over line to isolate it
$('#dataset-wrap').on('mouseover mouseleave', '.line', function(e){
    if ( e.type === 'mouseover' ) {
        // hide all lines except current
        $lines.not(this).hide();
        // find number in class name (e.g. get "9" from "red9")
        var number = this.className.match( /[a-z]+(\d+)/ ),
        // make regular expression to match word + number ( word could be "blue", "black" or "red" from distance value )
        // add \b at end to prevent matching "red26" when we only wanted "red2"
        regex = new RegExp( '[a-z]+' + ( number ? number[1] : '' ) + '\\b' );
        // find matching lines & show
        $lines.filter(function(){
            return regex.test( this.className );
        }).show();
    } else {
        $lines.show();
    }
});

更新:我忘了提一个问题,但我确实在代码中添加了注释,如果一行包含两次相同的数字,第二个值将被忽略....但这看起来像一个排序彩票比较,所以我不认为这是一个问题。