Question

I'm building a graph displaying events happening over time. Each of my event is an horizontal bar that is created using a <div> as shown below:

<div class="aaaa" style="margin-left: 0.00%; width:100.00%;">aaaa</div>
<div class="aaaa" style="margin-left: 5.00%; width: 20.00%;">bbbb</div>
<div class="aaaa" style="margin-left:25.00%; width: 50.00%;">cccc</div>
<div class="aaaa" style="margin-left:55.00%; width: 45.00%;">dddd</div>

At the top of this graph, I have a "ruler" which is a draggable and resizable <div>

<div id="draggable2" class="draggable ui-widget-content">
    <p>Ruler</p>
</div>

My intention is to drag this ruler horizontally and to use it to select all bars of my graphs that are below the ruler. When bars are selected, the background color should change.

So far I manage to drag and to resize my ruler as I want with the following code:

$(function () {
    $("#draggable2").draggable({
        axis: "x"
    });
});

$(function () {
    $("#draggable2").resizable({
        helper: "ui-resizable-helper",
        handles: "se, sw, e, w"
    });
});

I also manage to select the bars I want using the following code:

$(".fake").selectable({
    filter: "div"
});

You can see on the fiddle referenced below that when you do a "lasso selection", my bars become pink.

However, I would like to combine my ruler with this "lasso selection", or in other words, I would like that once my ruler is dragged, all <div> that are below become selected.

I've created a fiddle to illustrate my problem: http://jsfiddle.net/Lge93/

As I'm new to Javascript and Jquery, I would really appreciate any solution or suggestion.

Thanks for your time

Edit post answers: My final solution based on the code provided by Jtromans is available here: http://jsfiddle.net/Lge93/5/

Was it helpful?

Solution 2

If I understand your question correctly, it sounds like you could solve the problem in the following way.

Upon interacting with the ruler, you will be able to calculate the new width, x- and y-coordinates. This is pretty straight forward and requires only a few lines of jQuery code in the callback after any form of interaction with your ruler.

You could then check for each item in your (gant?) chart to see whether it occupies any of the same area that the ruler does. This would be relative to the parent container.

The devil is in the detail for how you would like to handle whether the ruler is 'in' the Gant chart div item. And below is some code to get your started on working out whether the Ruler occupies the some of the same location as the other divs:

function checkOverlays (x, width, y, height) {
    $(".aaaa").each (function (i,e) {
        var thisWidth = $(this).width();
        var thisHeight = $(this).height();
        var offsetTop = $(this).offset().top - $(this).parent().offset().top;
        var offsetLeft = $(this).offset().left - $(this).parent().offset().left;
        console.log('x coverage: ' + offsetLeft + " to " + parseFloat(thisWidth + offsetLeft));
        console.log('y coverage: ' + offsetTop + " to " + parseFloat(thisHeight + offsetTop));

        if (offsetLeft > x && offsetLeft < parseFloat(x + width) ) {
            console.log("I'm in the same x space");
            $(this).css('background-color', 'red');
        }

        if (offsetTop > y && offsetTop < parseFloat(y + height) ) {
            console.log("I'm in the same y space");
            $(this).css('background-color', 'red');
        }
    })
}



$("#draggable2").on("resize drag", function () {
    var thisWidth = $(this).width();
    var thisHeight = $(this).height();
    var offsetTop = $(this).offset().top - $(this).parent().offset().top;
    var offsetLeft = $(this).offset().left - $(this).parent().offset().left;
    console.log('x coverage: ' + offsetLeft + " to " + parseFloat(thisWidth + offsetLeft));
    console.log('y coverage: ' + offsetTop + " to " + parseFloat(thisHeight + offsetTop));

    checkOverlays (offsetLeft, thisWidth, offsetTop, thisHeight)
});

OTHER TIPS

Here's my solution:

$(function() {
  $( "#draggable2" ).draggable({ 
    axis: "x",
    drag: function(e) {
        var selectableElements = $(".fake").data().uiSelectable.selectees;
        var ruler = $(e.target);

        $.each(selectableElements, function(i, v) {
            if(ruler.offset().left >= $(v).offset().left) {
                $(v).addClass("ui-selected");
              }else {
                 $(v).hasClass("ui-selected") && $(v).removeClass("ui-selected");                    
            }
           });
        }

    });
});

$(function() {
  $( "#draggable2" ).resizable({
    helper: "ui-resizable-helper",
    handles: "se, sw, e, w"
  });
});

$(".fake").selectable({filter:"div"});

http://jsfiddle.net/Lge93/3/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top