如何在时间轴上使用D3.js v4进行缩放

时间:2017-08-23 07:54:26

标签: javascript d3.js zoom timeline

我有一个时间轴图,其中包含指示特定事件的数据点。我试图在图表中构建一个缩放功能但已达到死胡同。我可以放大轴,但不能将数据孔重新定位到新的比例。我经历了很多d3 bl.ocks,但还没有找到解决方案。

我在jsfiddle中有一个最小版本: https://jsfiddle.net/q73ggw3e/2/

主要部分是:

缩放:

 var zoom = d3.zoom()
    .scaleExtent([1, Infinity])
    .translateExtent([[0, 0], [width, height]])
    .extent([[0, 0], [width, height]])
    .on("zoom", zoomed);

数据点:

svg.append("g")
   .selectAll("logo")
   .attr("class", "logo")
   .data(data)
   .enter()
   .append("circle")
   .attr("cy", 40)
   .attr("cx", function(d) { return x(d);})
   .attr("r", 10)
   .style("fill", "#000000")

缩放区域:

svg.append("rect")
   .attr("class", "zoom")
   .attr("width", width)
   .attr("height", height)
   .call(zoom);

缩放功能:

function zoomed() {
    svg.select(".axis--x")
       .call(xAxis.scale(d3.event.transform.rescaleX(x)));
    var new_x = d3.event.transform.rescaleX(x);
        svg.selectAll(".logo")
           .attr("cx", function(d) { return new_x(d);});
     };

我也应该将(.logo)圆类绑定到缩放事件,但由于某种原因,只有轴缩放...

我哪里错了?或者是否有其他完全相同的方式......

如果重要,数据点也会有拖放,鼠标悬停和点击功能。这些工作目前工作正常,但缩放rect阻止指针事件。但这是在缩放工作后进行排序......

1 个答案:

答案 0 :(得分:-1)

你制作的奇怪图表

ContextMenu
<TreeView x:Name="TreeViewProtocolsAndEquipments" AllowDrop="True"
                  ItemsSource="{Binding ModuleParams}">
    <TreeView.Resources>
        <!-- CONTEXT MENU -->
        <!-- Protocol -->
        <ContextMenu x:Key="ContextMenuProtocol">
            <MenuItem Header="Add new equipment"
                              Command="{Binding PlacementTarget.Tag.DataContext.AddNewEquipmentCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}" 
                              CommandParameter="{Binding}">
                <MenuItem.Icon>
                    <Image Source="Images/Add.png" />
                </MenuItem.Icon>
            </MenuItem>
            <Separator />
        </ContextMenu>

        <!-- MODULE XXX -->
        <!-- ModuleParam > xxx -->
        <HierarchicalDataTemplate DataType="{x:Type xxx:ModuleParamXXXViewModel}" ItemsSource="{Binding ModuleItems}">
            <TextBlock Text="XXX" Foreground="Green"
                               Tag="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}"
                               ContextMenu="{StaticResource ContextMenuProtocol}"/>
        </HierarchicalDataTemplate>
    </TreeView.Resources>
</TreeView>
            var margin = {
                top: 30,
                right: 20,
                bottom: 30,
                left: 120
              },
              width = 800 - margin.left - margin.right,
              height = 210 - margin.top - margin.bottom;


            var svg = d3.select(".zoom")
              .append("svg")
              .attr("width", width + margin.left + margin.right)
              .attr("height", height + margin.top + margin.bottom)
              .append("g")
              .attr("transform",
                "translate(" + margin.left + "," + margin.top + ")");

            var y = d3.scaleLinear()
              .rangeRound([height, 0]);

            var x = d3.scaleTime()
              .rangeRound([0, width]);

            var xAxis = d3.axisTop(x)

            var zoom = d3.zoom()
                .scaleExtent([1, Infinity])
                .translateExtent([[0, 0], [width, height]])
                .extent([[0, 0], [width, height]])
                .on("zoom", zoomed);

            var parseTime = d3.timeParse("%Y-%m-%d");

            var lanes = ["A", "B", "C"]
            var lanesLength = lanes.length

            var a = ["2010-02-12", "2013-08-15", "2015-01-23", "2017-01-22"]
            var data = [];
            a.forEach(function (d){
                data.push(parseTime(d));
            });

            var today = new Date();
            x.domain([d3.min(data, function(d) { return d;}), today]);
            y.domain([0, lanesLength]);

            svg.append("g")
              .attr("class", "axis axis--x")
              .style("stroke-width", 2)
              .attr("transform", "translate(0)")
              .call(xAxis);


            svg.append("g")
              .selectAll(".lanetext")
              .data(lanes)
              .enter()
              .append("text")
              .text(function(d) { return d;})
              .attr("x", -margin.right)
              .attr("y", function(d, i) { return y(i + .5);})
              .attr("dy", ".5ex")
              .attr("text-anchor", "end")
              .attr("class", "lanetext")

            svg.append("g")
              
              .attr("class", "logomu")
              .selectAll("logomu")
              .data(data)
              .enter()
              .append("circle")
              .attr("cy", 40)
              .attr("class", "logo")
              .attr("cx", function(d) { return x(d);})
             .attr("r", 10)
             .style("fill", "#000000")

            svg.append("rect")
              .attr("class", "zoom")
              .attr("width", width)
              .attr("height", height)
              .call(zoom);

            function zoomed() {
                svg.select(".axis--x")
                    .call(xAxis.scale(d3.event.transform.rescaleX(x)));
                var new_x = d3.event.transform.rescaleX(x);
                svg.selectAll(".logo")
                    .attr("cx", function(d) { return new_x(d);});
            };

  

我应该将(.logo)圆类绑定到缩放事件   也是,但由于某种原因,只有轴缩放...

如果有类名徽标?检查html确保你正确追加

  

我哪里错了?还是有一些完全不同的做法   此...

你没有检查你画的是什么。是的,只需要经验