非透明矩形内的文本不可见

时间:2017-08-16 03:14:08

标签: d3.js svg

我的d3图表中有以下段。 我想要的是在矩形中显示一些文字。

var values = $('#<%=hdnDtArray.ClientID%>').val();
var data = JSON.parse(values);

margin = {
    top: 20,
    right: 60,
    bottom: 20,
    left: 100
};
var width = 900,
    height = 350;

var vis = d3.select("#line_chart").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom);

var parseTime = d3.time.format("%Y.%m.%d").parse;

max_y = 0;
min_y = data[0].close;
var extent = d3.extent(data.map(function(d) {
    return d.date
}));

max_x = extent[1];
min = extent[0];

for (i = 0; i < data.length; i++) {
    max_y = Math.max(max_y, data[i].close);
    min_y = Math.min(min_y, data[i].close);
}

var x = d3.time.scale()
    .rangeRound([margin.left, width]);


xScale = x.domain(d3.extent(data, function(d) {
    return parseTime(d.date);
}));

yScale = d3.scale.linear().range([height - margin.top, margin.bottom]).domain([0, max_y]),

    xAxis = d3.svg.axis()
    .scale(xScale),

    yAxis = d3.svg.axis()
    .scale(yScale)
    .orient("left")
    .innerTickSize(-width + margin.left)
    .outerTickSize(0)
    .tickPadding(10);

vis.append("svg:g")
    .attr("class", "x axis")
    .style({
        'stroke': 'Black',
        'fill': 'none',
        "stroke-width": 1,
        "font-size": "13px"
    })
    .attr("transform", "translate(0," + (height - margin.bottom) + ")")
    .call(xAxis)
    .selectAll("text")
    .attr("transform", "translate(-10,0) rotate(-40)")
    .style("text-anchor", "end");


vis.append("text")
    .attr("class", "x label")
    .attr("text-anchor", "end")
    .attr("x", width + 120)
    .attr("y", height - 10)
    .attr("font-weight", "bold");

vis.append("svg:g")
    .attr("class", "y axis")
    .style({
        'stroke': 'Black',
        'fill': 'none',
        'stroke-width': 1,
        "font-size": "13px"
    })
    .attr("transform", "translate(" + (margin.left) + ",0)")
    .call(yAxis);

vis.append("text")
    .attr("class", "y label")
    .attr("text-anchor", "end")
    .attr("x", margin.left + 5)
    .attr("y", margin.top - 2)
    .attr("font-weight", "bold");

var line = d3.svg.line()
    .x(function(d) {
        return xScale(parseTime(d.date));
    })
    .y(function(d) {
        return yScale(d.close);
    })
    .interpolate("basis");

vis.append('svg:path')
    .datum(data)
    .attr("fill", "none")
    .attr("stroke", "steelblue")
    .attr("stroke-linejoin", "round")
    .attr("stroke-linecap", "round")
    .attr("stroke-width", 1.5)
    .attr("d", line);

var hoverLineGroup = vis.append("g")
    .attr("class", "hover-line");

var hoverLine = hoverLineGroup.append("line")
    .attr("stroke", "#000000")
    .attr("stroke-width", "1px")
    .attr("x1", 10).attr("x2", 10)
    .attr("y1", 20).attr("y2", height - 20);

var hoverTT = hoverLineGroup.append('text')
    .attr("class", "hover-tex capo")
    .attr('dy', "0.35em");

var cle = hoverLineGroup.append("circle")
    .attr("r", 4.5);

var hoverTT2 = hoverLineGroup.append('text')
    .attr("class", "hover-text capo")
    .attr('dy', "0.55em");

hoverLineGroup.style("opacity", 1e-6);

var rectHover = vis.append("rect")
    .data(data)
    .attr("fill", "none")
    .attr("width", width)
    .attr("height", height);

var hoverCircle = hoverLineGroup.append("circle");
var hoverRect = hoverLineGroup
    .append("rect");



vis.on("mouseout", hoverMouseOff)
    .on("mousemove", hoverMouseOn);

var bisectDate = d3.bisector(function(d) {
    return parseTime(d.date);
}).left;

function hoverMouseOn() {

    var mouse_x = d3.mouse(this)[0];
    var mouse_y = d3.mouse(this)[1];
    var graph_y = yScale.invert(mouse_y);
    var graph_x = xScale.invert(mouse_x);

    var mouseDate = xScale.invert(mouse_x);
    var i = bisectDate(data, mouseDate);

    var d0 = data[i - 1]
    var d1 = data[i];

    var d = mouseDate - d0[0] > d1[0] - mouseDate ? d1 : d0;

    hoverRect.attr("class", "y")
        .style("fill", "none")
        .style("stroke", "black")
        .attr('x', mouse_x + 8)
        .attr('y', yScale(d.close) - 20)
        .attr("width", 200)
        .attr("height", 50);


    hoverTT.text("Test Text")
        .attr("opacity", "1");


    hoverTT.attr('x', mouse_x + 23);
    hoverTT.attr('y', yScale(d.close));




    /*
    hoverTT.text("Date: " + d.date);
    hoverTT.attr('x', mouse_x + 23);
    hoverTT.attr('y', yScale(d.close));

    hoverTT2.text("Portfolio Value: " + Math.round(d.close * 100) / 100)
            .attr('x', mouse_x + 23)
            .attr('y', yScale(d.close) + 10);
    */

    hoverLine.attr("x1", mouse_x).attr("x2", mouse_x)
    hoverLineGroup.style({
        'font-weight': 'bold',
        'opacity': 1
    });

    hoverCircle.attr("class", "y")
        .style("fill", "blue")
        .style("stroke", "blue")
        .attr("r", 4)
        .attr('cx', mouse_x)
        .attr('cy', yScale(d.close));


}

function hoverMouseOff() {
    hoverLineGroup.style("opacity", 1e-6);
}

现在看不到文字了。但是,如果我设置&#34;填充&#34;属性为&#34;无&#34;,然后文本变为可见。

我想要的是不透明的背景,这就是为什么我把它变成白色的原因。 我仍然希望文本可见。

1 个答案:

答案 0 :(得分:2)

您的代码存在的问题是选择的顺序

在SVG中,就像真正的画家在真实画布中使用墨水一样,后来绘制的仍然位于顶部。因此,如果您希望文本位于矩形的顶部(使用您想要的任何fill),请在选择矩形后设置文本的选择。

因此,在您的情况下,这......

var hoverTT = hoverLineGroup.append('text')
    .attr("class", "hover-tex capo")
    .attr('dy', "0.35em");

...必须之后

var hoverRect = hoverLineGroup
    .append("rect");

这是一个演示,矩形有一个纯白色填充。看看选择的顺序:

var svg = d3.select("svg");
var hoverRect = svg.append("rect")
	.attr("fill", "white")
  .attr("stroke", "firebrick")
  .attr("width", 40)
  .attr("height", 30)
  .attr("opacity", 0);
var hoverText = svg.append("text")
  .text("foo")
svg.on("mousemove", function() {
  var coords = d3.mouse(this);
  hoverRect.attr("x", coords[0] + 15)
    .attr("y", coords[1])
    .attr("opacity", 1)
  hoverText.attr("x", coords[0] + 25)
    .attr("y", coords[1] + 20)
})
svg {
  border: 1px solid gray;
  background-color: gainsboro;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>