【问题标题】:Point dragging in Kendo UI line chartKendo UI折线图中的点拖动
【发布时间】:2013-09-20 20:54:02
【问题描述】:

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

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

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

【问题讨论】:

  • 请发布一些自己的作品或小提琴以便更好地理解,是的,这是可能的。
  • 我更新了我的问题。但关键是我不知道从哪里开始。
  • 我正在详细研究你需要从 SVG 命令开始的那部分,因为 Kendo 它自己在图表的后端使用 SVG,请参阅生成图表的来源jsfiddle.net/MarmeeK/kHp5G/1
  • 是的,我想我们可以从这个显然也使用 SVG 的 highcharts 插件中获得灵感:jsfiddle.net/highcharts/AyUbx
  • 是的,它的即用功能,但如果约束是剑道,我们有太多的工作要做。剑道支持拖放,但图表不支持。所以我们需要手动定义每个事件及其功能。

标签: javascript kendo-ui


【解决方案1】:

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

其次是刷新图表,Kendo's 不提供在不完全重绘的情况下更新图表的“好”方法。所以我们必须移动 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 的 Kendo fiddle 结合起来是行不通的——jQuery-UI 事件不会绑定到图表(回到我帖子开头的问题 1)。所以我必须这样做才能得到一个我可以移动的图表:

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

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

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

【讨论】:

  • 非常感谢您的深入回答。你的小提琴看起来很棒。如果我成功使用它,我将需要一些时间来完全理解它并肯定会验证这个答案。
  • 感谢您找到一种将 SVG 转换为 HTML(SVG) 的方法 :),这确实可以欺骗 :)
  • @SpaceDog 你知道如何将鼠标事件的 Y 坐标转换为图表值吗?
  • @fiddler,呵呵——我没有做那部分,因为我看不到一个简单的方法。您需要得到的是绘图区域的边界框——这都包含在 SVG 中的第一个内部 g 元素中,看起来 SVG 中的第二条路径也定义了网格线的框。因此,您可以获取路径字符串$(svg path).next().attr('d'),然后对其进行处理以获取 x/y 值的最小值/最大值。这给了你角落——所以你应该能够推断出相对于(((maxY - minY)/(mouseY - plotAreaTopY)) * (maxScaleY - minScaleY)) + minScaleY) 的 y 位置。我认为;)
【解决方案2】:

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

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

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

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

示例fiddle

Sample2 fiddle 这适用于可拖动的 jQuery UI,但现在由于 SVG 而出现在图形中。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-27
    相关资源
    最近更新 更多