固定位置D3尖端而不是鼠标位置

时间:2016-01-29 13:46:24

标签: javascript css d3.js graph position

我正在使用D3完成一个简单的散点图项目。我正在使用D3 tip在鼠标悬停时在图表上显示有关主题的更多信息。

目前,提示会显示主题位于图表上主题的位置。

但是,无论何时触发提示,我都希望将我的提示放在图表右下角的固定位置。

我试图在CSS中修改d3-tip类,但无论我尝试什么,它似乎被覆盖,并且提示的topleft位置总是在鼠标的任何地方碰巧是。

以下是我的项目的Codepen,您可以在其中找到主题所在位置的提示:http://codepen.io/alanbuchanan/pen/RryBVQ

如何确保我的小费显示在图表右下角的固定位置?

使用Javascript:

var w = 600;
var h = 700;
var margin = {top: 70, bottom: 90, left: 110, right: 70};
var nameMargin = 2;
var chartWidth = w - margin.left - margin.right;
var chartHeight = h - margin.top - margin.bottom;
var url = 'https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/cyclist-data.json';

var svg = d3.select('body')
    .append('svg')
    .attr('width', w + margin.right)
    .attr('height', h)
    .style('background-color', '#eeeeee')
    .style('border-radius', '10px')
    .append('g')
    .attr('transform', `translate(${margin.left}, ${margin.top})`);

    var formatMinutes = d => {
        d -= 2210
        var mins = Math.floor(d / 60)
        var secs = d - mins * 60
        return mins + ':' + secs
    };

// Scales
var x = d3.scale.linear()
            .domain([
                2390 + 5,
                2210
            ])
            .range([0, chartWidth]);

var y = d3.scale.linear()
            .domain([1, 35 + 1])
            .range([0, chartHeight]);

// Axes
var xAxis = d3.svg.axis()
            .scale(x)
            .orient('bottom')
            .ticks(7)
            .tickFormat(formatMinutes);

var yAxis = d3.svg.axis()
            .scale(y)
            .orient('left')
            .ticks(10);

var getFlag = nat => {
    switch (nat) {
        // Deal with odd cases
        case 'GER': nat = "DE"; break;
        case 'SUI': nat = "CH"; break;
        case 'UKR': nat = "UA"; break;
        case 'POR': nat = "PT"; break;
        default: break;
    }

    return nat.substr(0, 2).toLowerCase();
};

$.getJSON(url, data => {
    console.log(data)

    var tip = d3.tip()
                .attr('class', 'd3-tip')
                .html(d => {
                    return `<h4><span class="flag-icon flag-icon-` + getFlag(d.Nationality) + `"></span> ${d.Name}</h4>
                    <h5>Time: ${d.Time} in ${d.Year}</h5>
                    <p>${d.Doping || 'No allegations'}</p>`
                });

    // Add data from JSON
    svg.selectAll('circle')
        .data(data)
        .enter()
        .append('circle')
        .attr('cx', d => x(d.Seconds))
        .attr('cy', d => y(d.Place))
        .attr('r', '2')
        .style('width', '4px')
        .style('height', '10px');

    svg.call(tip);

    var createLink = d => {
        return `window.location='${d.URL}`
    };

    var text = svg.selectAll('text')
        .data(data)
        .enter()
        .append('text')
        .attr('x', d => x(d.Seconds - nameMargin))
        .attr('y', d => y(d.Place))
        .attr("dy", ".35em")
        .text(d => d.Name)
        .attr('class', 'rider-name')
        .attr('class', d => d.Doping.length === 0 ? 'noAllegations' : 'hasAllegations')
        .on('click', (d) => location.href = d.URL)
        .on('mouseover', tip.show)
        .on('mouseout', tip.hide);

    svg.append('g')
        .attr('class', 'axis')
        .attr('transform', `translate(0, ${chartHeight})`)
        .call(xAxis);

    svg.append('g')
        .attr('class', 'axis')
        .call(yAxis);

    // Axis labels
    svg.append('text')
        .attr('class', 'label')
        .attr('text-anchor', 'middle')
        .attr('x', chartWidth / 2)
        .attr('y', chartHeight + 50)
        .text('Mins and secs behind best time');

    svg.append('text')
        .attr('class', 'label')
        .attr('text-anchor', 'middle')
        .attr('y', 0 - margin.left)
        .attr('x', 0 - (chartHeight / 2))
        .attr('dy', '3.9em')
        .attr('transform', 'rotate(-90)')
        .text('Place');

    // Title
    var title = svg.append('text')
        .attr('class', 'title')
        .attr('x', chartWidth / 2)
        .attr('y', 0 - (margin.top / 2))
        .attr('text-anchor', 'middle')
        .text('Doping in Professional Bicycle Racing: 35 Fastest times up Alpe d\'Huez')
        .style('font-size', '16px')
        .style('font-weight', 'bold');
});

CSS:

@import url(https://fonts.googleapis.com/css?family=Raleway:400,100);
$font: 'Raleway', sans-serif;
$font-light: 100;
$font-med: 400;
$green: #416600;
$red: #b40000;

body {
    background-color: #DADADA;
    position: relative;
    font-family: $font;
}

.axis path,
.axis line {
    fill: none;
    stroke: gray;
    shape-rendering: crispEdges;
}

.d3-tip {
    width: 200px;
}

svg {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, 10%);
    border: 1px solid $red;
    box-shadow: 3px 3px 15px #888888;
}

h4, h5 {
    margin: 0;
}

text {
    cursor: pointer;
}

.noAllegations {
    fill: $green;
}

.hasAllegations {
    fill: $red;
}

.title {
    cursor: initial;
    fill: $red;
}

.noAllegations, .hasAllegations {
    text-transform: uppercase;
    font-weight: $font-med;
    font-size: 12px;
}

circle {
    fill: black;
}

.label {
    cursor: initial;
}

0 个答案:

没有答案