在Kendo UI折线图中拖动点

时间:2013-09-17 09:37:27

标签: javascript kendo-ui

我有一个简单的Kendo UI折线图,例如:

    <div id="chart"></div>      
    <script>
        $("#chart").kendoChart({
            series: [{
                type: 'line',
                data: [200, 450, 300, 125]
            }]
        });
    </script>

如何启用/实施点拖动? (即我希望用户通过鼠标拖动垂直移动点)

2 个答案:

答案 0 :(得分:2)

您需要克服几个问题 - 一个是我看到的Kendo图表上点击/拖动/悬停的默认行为。这应该很容易禁用,但这取决于你是否想要结合其中一些。

其次是刷新图表,Kendo没有提供一个“好”的方法来更新图形而不需要完全重绘。所以我们必须将SVG中的线移动作为拖动的一部分。不幸的是,它们是路径的一部分,因此更复杂。

您绝对可以将事件处理程序附加到各个圈子,您可以使用其他框架(如jQuery-UI(Draggable)来实现它。但这带来了第三个问题,您必须了解不同SVG元素的ID如何与您正在使用的实际数据相关联。在内部,它为图形上的圆和路径创建了数字ID - 您需要了解它们与数据点的关系。

如果你正在研究并且可以访问jQuery-UI,你可以尝试这样的事情(注意,SVG可拖动的帮助改编自this回答和 MarmiK 的小提琴)。

$('circle')
    .draggable({ 
        axis: "y",
        containment: $('svg') 
     })
    .bind('mousedown', function(event, ui){
        // bring target to front
        $(event.target.parentElement).append( event.target );
    })
    .bind('drag', function(event, ui){
    // update coordinates manually, since top/left style props don't work on SVG          
    event.target.setAttribute('cy', ui.position.top + 2);

    // Update the path here, then update the data: 
    // $chart.options.series[?].data[?] = new position.
});

Fiddle

遏制只需要绘图区域而不是整个SVG,您还需要更新PATH。当你放弃圆圈时,你可以欺骗并做剑道.redraw()方法 - 它不会像它那样光滑,但它会起作用。

然后要动态更新路径,你可以

var path = $('#k10014').attr('d'); // Get Path
path = path.substr(1);             // Remove M 
p_array = path.split(" ");         // Split into array
p_array[7] = ui.position.top;      // Change one value (but which one?)
path = "M"+ p_array.join(" ")      // Combine back with M
$('#k10014').attr('d', path);      // Update SVG

Fiddle

所以这非常接近 - 如果你能弄清楚如何将每个圆圈与路径中的某个点相关联(并且可能存在ID的模式),那么你几乎可以肯定这样做。

如果你想避免使用jQuery-UI,你可以手动实现所有的拖动内容 - 它并不难,因为上面已经完成了位置更新。

修改

好的,我已经考虑过这个了 - 我可以看到图形本身包含在两个内部元素中,所以我们可以使用jQuery来实现它。然后很容易找到第一条路径(这是第一条线)并找出我们拖动的哪个圆圈,我做了一个函数:

// This only works for one path ... but if you know the number of points
// then you can expand this easily ... 
function movePathForPointId(element, pos) {
   // Update pos to account for the circle radius 
   pos = pos + 2;

   // The graph is in two nested <g> elements, we can use this ... 

   // First find the position of the circle,     
   var pointIndex = $('svg g g circle').index(element); 

   // Get the first path in the graph 
   var pathElement = $('svg g g path').first();

   var path = pathElement.attr('d');     // Get Path String
   path = path.substr(1);                // Remove M 
   p_array = path.split(" ");            // Split into array
   p_array[(pointIndex * 2) + 1] = pos;  // Change one value (but which one?)
   path = "M"+ p_array.join(" ")         // Combine back with M
   pathElement.attr('d', path);          // Write new path back to SVG
   element.setAttribute('cy', pos);      // Update circle position
   return pointIndex;                    // Might be useful to update the data table
}

将此与 MarmiK 的剑道小提琴相结合不起作用 - jQuery-UI事件不会绑定到图形(在我发布的一开始就回到问题1)。所以我必须这样做以获得我可以移动的图表:

var chart = $("#chart").data("kendoChart");
var svg = chart.svg();
chart.destroy();
$("#chart").html(svg);

从那里开始我有一个工作fiddle,但这取决于你想要对数据做什么。您可能需要解决如何取消绑定Kendo事件并绑定自己的事件,或者使用上面的逻辑来重做不同的拖动实现。

但这应该让你开始......

答案 1 :(得分:0)

我已经为剑道的工作示例更新了一个小提琴..

我研究了图表中使用SVG绘制图表的部分,

我已经更新了绘制图表的临时模型,还添加了应该拖动的小代码,

图表下方的圆圈。但它没有使用kendoDraggable拖动

示例fiddle

Sample2 fiddle这适用于jQuery UI for draggable,但现在由于SVG而在图中。

这应该会给你一个良好的开端。