D3通过将鼠标悬停在图例

时间:2015-09-09 19:09:14

标签: d3.js hover line legend

我制作了一个带有图例的双线图表。我想根据用户将鼠标悬停在图例圆上的颜色,将每条线的笔触宽度突出显示为4px。因此,用户将鼠标悬停在蓝色图例圆上,蓝线笔划宽度变为4px。如果他在图例上的红色圆圈上盘旋,那么红色相同。这可以基于我的代码吗?这是完整的代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>D3 Test</title>
        <script type="text/javascript" src="../d3/d3.js"></script>
        <script type="text/javascript" src="../d3/d3-tip.js"></script>
        <style type="text/css">
            body{
                font: 16px Calibri;
            }

            .line1{
                fill: none;
                stroke: steelblue;
                stroke-width: 2px;
            }

            .line1:hover{
                stroke-width: 3.5px;
            }

            .line2{
                fill: none;
                stroke: red;
                stroke-width: 2px;
            }

            .line2:hover{
                stroke-width: 3.5px;
            }

            .axis path,
            .axis line{
                fill:none;
                stroke: black;
                stroke-width: 1px;
                shape-rendering: crispEdges;
            }

            .axis text{
                font-family: sans-serif;
                font-size: 14px;
                stroke: black;
                stroke-width: 0.5px;
            }

            .legend .series {
                cursor: pointer;
            }

            .legend circle {
                stroke-width: 2px;
            }

            .legend .disabled circle {
                fill-opacity: 0;
            }


        </style>
        <!--...this code will be used on an external html file and instered-->
        <html>
<body>
        <div id="dropdown">
            <select id = "opts">
                <option value = "ds1">Atlas</option>
                <option value = "ds2">BioSQL</option>
                <option value = "ds3">Coppermine</option>
                <option value = "ds4">Ensembl</option>
                <option value = "ds5">Mediawiki</option>
                <option value = "ds6">Opencart</option>
                <option value = "ds7">PhpBB</option>
                <option value = "ds8">Typo3</option>
            </select>
        </div>
        <script type="text/javascript">
            console.log("worked");
            var ds1="../CSV/atlas/results/metrics.csv";
            var ds2="../CSV/biosql/results/metrics.csv";
            var ds3="../CSV/coppermine/results/metrics.csv";
            var ds4="../CSV/ensembl/results/metrics.csv";
            var ds5="../CSV/mediawiki/results/metrics.csv";
            var ds6="../CSV/opencart/results/metrics.csv";
            var ds7="../CSV/phpbb/results/metrics.csv";
            var ds8="../CSV/typo3/results/metrics.csv";
        </script>
</body>
</html>     <!--...............................................................-->
        <div id="area1"></div>
        <div id="area2"></div>
    </head>
    <body>
        <script type="text/javascript">



var margin = {top: 60, right: 20, bottom: 40, left: 40},
    margin2 = {top: 430, right: 20, bottom: 0, left: 50},
    width = 800 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;
    height2 = 870 - margin2.top - margin2.bottom;

var parseDate = d3.time.format("%Y").parse;

var color = d3.scale.category20()
        .range(["#1f77b4", "#d62728", "#98df8a"]);

var x = d3.scale.linear()
    .range([0, width]);

var x1 = d3.time.scale()
    .nice(d3.time.year)
    .range([0, width]);

var y = d3.scale.linear()
    .range([height, 0]);

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom")
    .ticks(5);

var x1Axis = d3.svg.axis()
    .scale(x1)
    .orient("bottom")
    .ticks(5);

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left");


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



var line1 = d3.svg.line()
        .x(function(d) { return x(d.trID);})
        .y(function (d) {return y(d.newT);})
        .interpolate("basis");

var line2 = d3.svg.line()
        .x(function(d) { return x1(d.time);})
        .y(function (d) {return y(d.newT);})
        .interpolate("basis");

var dsv = d3.dsv(";", "text/plain");    //setting the delimiter
var dataset = []                        //defining the data array
var datapath="../CSV/atlas/results/metrics.csv";
    dsv(datapath, function(data){   //------------select the file to load the csv------------

        var label = document.getElementById('opts')[document.getElementById('opts').selectedIndex].innerHTML;//takes the name of the f
        console.log(label);

        dataset= data.map(function(d){      //parse
            return {                        //insert parsed data in the array
                trID: +d["trID"],
                newT: +d["#newT"],
                time: +d["time"]            
            };
        });


        dataset.forEach(function(d){
            d.time = new Date(d.time*1000);
        });

        console.log(dataset);
        x.domain(d3.extent(dataset, function(d) { return d.trID; }));
        x1.domain(d3.extent(dataset, function(d) { return d.time; }));
//      y.domain([0, d3.max(dataset.map( function(d) {return d.newT}))]);
        y.domain(d3.extent(dataset, function(d) { return d.newT; }));

//------------------creating the lines---------------------

        svg1.append("path")
            .datum(dataset)
            .attr("class", "line1")
            .attr("d", line1);

        svg1.append("path")
            .datum(dataset)
            .attr("class", "line2")
//          .style("stroke-dasharray",("5,5"))
            .attr("d", line2);

//----------------appending Legend--------------------------
        var legend = svg1.selectAll(".legend")
            .data((["Duration/Time","Duration/ID"]).slice().reverse())
            .enter().append("g")
            .attr("class", "legend")
            .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });


        legend.append("circle")
            .attr("r", 7)
            .attr("cx", 45)
            .attr("cy", 10)
            .style("fill", color);

        legend.append("text")
            .attr("x", 54)
            .attr("y", 9)
            .attr("dy", ".35em")
            .style("text-anchor", "begin")
            .style("font-family", "Calibri")
            .text(function(d) { return d; });           
//-----------------------------------------------------------       
        svg1.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + height + ")")
            .call(xAxis)
            .append("text")
            .attr("class", "label")
            .attr("x", width)
            .attr("y", -6)
            .style("text-anchor", "end")
            .text("trID");

        svg1.append("g")
            .attr("class", "x1 axis")
            .attr("transform", "translate(0," + height2  + ")")
            .call(x1Axis)
            .append("text")
            .attr("class", "label")
            .attr("x", width)
            .attr("y", -6)
            .style("text-anchor", "end")
            .text("time");

        svg1.append("g")
            .attr("class", "y axis")
            .call(yAxis)
            .append("text")
            .attr("class", "label")
            .attr("transform", "rotate(-90)")
            .attr("y", 6)
            .attr("dy", ".71em")
            .style("text-anchor", "end")
            .text("num of tables");

        svg1.append("text")
            .attr("class","simpletext")
            .attr("x", (width/2))
            .attr("y", 0 - (margin.top/2))
            .attr("text-anchor", "middle")
            .style("font-size", "20px")
            .style("text-decoration", "underline")
            .text(label);
    });

    d3.select('#opts')
        .on('change', function(){
            var dataset=[]
            var datapath = eval(d3.select(this).property('value'));
            label = document.getElementById('opts')[document.getElementById('opts').selectedIndex].innerHTML;


            dsv(datapath, function(data){   //------------select the file to load the csv------------
                dataset= data.map(function(d){      //parse
                    return {                        //insert parsed data in the array
                    trID: +d["trID"],
                    newT: +d["#newT"],
                    time: +d["time"]
                    };
                });

                dataset.forEach(function(d){
                    d.time = new Date(d.time*1000);
                });

            x.domain(d3.extent(dataset, function(d) { return d.trID; }));
            x1.domain(d3.extent(dataset, function(d) { return d.time; }));
//          y.domain([0, d3.max(dataset.map( function(d) {return d.newT}))]);
            y.domain(d3.extent(dataset, function(d) { return d.newT; }));           

            d3.selectAll(".line1")
                .transition()
                .duration(1000)
                .attr("d", line1(dataset));

            d3.selectAll(".line2")
                .transition()
                .duration(1000)
                .attr("d", line2(dataset));

            //Update Axis
            //Update X axis
            svg1.select(".x.axis")
                .transition()
                .duration(1000)
                .call(xAxis);

            svg1.select(".x1.axis")
                .transition()
                .duration(1000)
                .call(x1Axis);
            //Update Y axis
            svg1.select(".y.axis")
                .transition()
                .duration(1000)
                .call(yAxis);

            svg1.selectAll("path")
                .data(dataset)
                .exit()
                .remove();
                console.log(label);

            svg1.selectAll(".simpletext")
                .transition()
                .text(label);
/*          .attr("x", (width/2))
            .attr("y", 0 - (margin.top/2))
            .attr("text-anchor", "middle")
            .style("font-size", "20px")
            .style("text-decoration", "underline")
            .text(label);*/
        });
    });
        </script>
    </body>
</html>     

我将颜色定义为:

var color = d3.scale.category20()
            .range(["#1f77b4", "#d62728", "#98df8a"]);

我的每一行都是这样的:

var line1 = d3.svg.line()
        .x(function(d) { return x(d.trID);})
        .y(function (d) {return y(d.newT);})
        .interpolate("basis");

var line2 = d3.svg.line()
        .x(function(d) { return x1(d.time);})
        .y(function (d) {return y(d.newT);})
        .interpolate("basis");

1 个答案:

答案 0 :(得分:0)

当然有可能。

首先它与line1line2无关 - 它们与行的数据有关,而不是实际的可视元素。您需要更改path元素.line1.line2的样式。

您可以在创建图例时添加事件侦听器。

//----------------appending Legend--------------------------
var legend = svg1.selectAll(".legend")
    .data((["Duration/Time","Duration/ID"]).slice().reverse())
    .enter().append("g")
    .attr("class", "legend")
    .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; })
    .on("mouseover", function(d) {
        if (d === "Duration/ID") {
            // line1's legend is hovered
            svg1.selectAll(".line1").style("stroke-width", "4px");
        }
        else if (d === "Duration/Time") {
            // line2's legend is hovered
            svg1.selectAll(".line2").style("stroke-width", "4px");
        }
    })
    .on("mouseout", function() {
        // revert the styles
        svg1.selectAll(".line1").style("stroke-width", "2px");
        svg1.selectAll(".line2").style("stroke-width", "2px");            
    });

这只是一个示范。当然,在css中定义样式并更改事件类更为一致,当你有更多/动态系列时,你可能不想硬编码图例名称。