我正在尝试将悬停工具提示添加到剪切路径[这是我第一次使用clippath ...甚至是正确的单词吗?] ...我想我真的很接近[圆圈该行应该现在显示在(0.0)处],但我似乎缺少了一些内容。我想知道是否有人有时间看看?我正在尝试改编https://blockbuilder.org/bendoesdata/2c8b315d103bbaf98264efda92d313ab
中的代码
.tooltip {
position: absolute;
text-align: left;
font-family: "Open Sans Condensed";
font-size: 12px;
width: 80px;
height: 52px;
padding: 8px;
background: white;
pointer-events: none;
background-color: white;
line-height: 0.05em;
padding: 20px;
/* border: solid;
border-width: 1px; */
}
#my_dataviz {
padding: 20px;
}
<script src="https://d3js.org/d3.v5.js"></script>
<div id="my_dataviz"></div>
headers = randint(0, 1)
with open('headers.csv', 'r') as fd:
reader = csv.reader(fd)
reader = list(reader)
driver.execute_cdp_cmd('Network.setUserAgentOverride', {
"userAgent": str(reader[headers])})
答案 0 :(得分:1)
您混淆了命名。 ser1
您多次致电str1
。这清楚地表明您的原始命名ser1
和ser2
不够逻辑!如果您现在不能遵循它,那么一年后重新访问代码又如何呢?
在使用数据之前先解析数据,而不是在使用时解析。如果您将日期作为字符串存储在原始对象中,请在对其进行处理之前 对其进行解析。否则,当您想比较,绘制,格式化或使用它时,就会遇到问题。
就是这样,我所做的大部分更改只是在需要时将formatDate
替换为parseDate
(这些是不同的东西),然后将str1/2
替换为ser1/2
在任何需要的地方。
var data3 = [
{ group: 1, ser1: "2020-01-01", ser2: 3 },
{ group: 1, ser1: "2020-01-02", ser2: 5 },
{ group: 1, ser1: "2020-01-03", ser2: 9 },
{ group: 1, ser1: "2020-01-04", ser2: 3 },
{ group: 1, ser1: "2020-01-05", ser2: 5 },
{ group: 1, ser1: "2020-01-06", ser2: 9 },
{ group: 2, ser1: "2020-01-07", ser2: 10 },
{ group: 2, ser1: "2020-01-08", ser2: 9 },
{ group: 2, ser1: "2020-01-09", ser2: 10 },
{ group: 2, ser1: "2020-01-10", ser2: 20 },
{ group: 2, ser1: "2020-01-11", ser2: 10 },
{ group: 2, ser1: "2020-01-12", ser2: 12 },
{ group: 3, ser1: "2020-01-13", ser2: 20 },
{ group: 3, ser1: "2020-01-14", ser2: 12 },
{ group: 3, ser1: "2020-01-15", ser2: 4 },
{ group: 3, ser1: "2020-01-16", ser2: 22 },
{ group: 3, ser1: "2020-01-17", ser2: 2 },
{ group: 3, ser1: "2020-01-18", ser2: 4 },
];
var parseDate = d3.timeParse("%Y-%m-%d");
// Parse the date ASAP
data3 = data3.map(function(d) {
return {
group: d.group,
ser1: parseDate(d.ser1),
ser2: d.ser2
};
});
var line = d3.line()
.x(function (d) { return x(d.ser1); })
.y(function (d) { return y(d.ser2); })
// set the dimensions and margins of the graph
var margin = { top: 10, right: 30, bottom: 30, left: 50 },
width = 1000 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
// append the svg object to the body of the page
var svg = d3.select("#my_dataviz")
.append("svg")
.attr("viewBox", `0 0 ${width + margin.left + margin.right} ${height + margin.top + margin.bottom}`)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
svg.append("defs")
.append("clipPath")
.attr("id", "chart-path")
.append("rect")
.attr("width", width - 100)
.attr("height", height)
var formatDate = d3.timeParse("%Y-%m-%d");
var bisectDate = d3.bisector(function (d) {
return d.ser1;
}).left;
// Initialize a X axis:
var x = d3.scaleTime()
.range([0, width - 100])
.domain(d3.extent(data3, function (d) { return d.ser1; }));
var xNum = d3.scaleLinear().range([0, width - 100])
var xAxis = d3.axisBottom().scale(x);
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.attr("class", "myXaxis")
// Initialize an Y axis
var y = d3.scaleLinear().range([height, 0]);
var yAxis = d3.axisLeft().scale(y);
svg.append("g")
.attr("class", "myYaxis")
// create the Y axis
y.domain([0, d3.max(data3, function (d) { return d.ser2 })]);
svg.selectAll(".myYaxis")
.transition()
.duration(1000)
.call(yAxis);
// Create a update selection: bind to the new data
var u = svg.selectAll(".lineTest")
.data([data3])
.enter()
.append("path")
.attr("class", "lineTest")
.attr("fill", "none")
.attr("stroke", "#0b6dbd")
.attr("stroke-width", 2.5)
.attr("clip-path", "url(#chart-path)")
svg.selectAll(".myXaxis")
.call(xAxis);
u.attr("d", line);
// this is where I try to implement a tooltip based on
// https://blockbuilder.org/bendoesdata/2c8b315d103bbaf98264efda92d313ab
function drawFocus() {
// Create focus object
let focus = svg.append('g')
.attr('class', 'focus')
// append circle on the line path
focus.append('circle')
.attr('r', 7.5)
// add background rectangle behind the text tooltip
focus.append('rect')
.attr('x', -30)
.attr('y', '-2em')
.attr('width', 70)
.attr('height', 20)
.style("fill", "white");
// add text annotation for tooltip
focus.append('text')
.attr('x', -30)
.attr('dy', '-1em')
.style("fill", "black")
.style("font-family", "SuisseIntl");
focus.append('div')
.attr('x', 10)
.attr('dy', '.35em')
.attr("class", "tooltip")
.style("opacity", 1)
// create an overlay rectangle to draw the above objects on top of
svg.append('rect')
.attr('class', 'overlay')
.attr('width', width - 100)
.attr('height', height)
.on('mouseover', () => focus.style('display', null))
.on('mouseout', () => focus.style('display', 'none'))
.on('mousemove', tipMove);
// make the overlay rectangle transparent,
// so it only serves the purpose of detecting mouse events
d3.select('.overlay')
.style('fill', 'none')
.style('pointer-events', 'all');
// select focus objects and set opacity
d3.selectAll('.focus')
.style('opacity', 0.9);
// select the circle and style it
d3.selectAll('.focus circle')
.style("fill", '#FDD511')
.style("opacity", 0)
// function that adds tooltip on hover
function tipMove() {
// below code finds the date by bisecting and
// stores the x and y coordinate as variables
let x0 = x.invert(d3.mouse(this)[0]);
let i = bisectDate(data3, x0, 1);
let d0 = data3[i - 1];
let d1 = data3[i];
let d = x0 - d0.ser1 > d1.ser1 - x0 ? d1 : d0;
// place the focus objects on the same path as the line
focus.attr('transform', `translate(${x(d.ser1)}, ${y(d.ser2)})`);
// position the x line
focus.select('line.x')
.attr('x1', 0)
.attr('x2', x(d.ser1))
.attr('y1', 0)
.attr('y2', 0);
// position the y line
focus.select('line.y')
.attr('x1', 0)
.attr('x2', 0)
.attr('y1', 0)
.attr('y2', height - y(d.ser2));
// position the text
focus.select('text').text(d.ser2)
.transition() // slowly fade in the tooltip
.duration(100)
.style("opacity", 1);
// show the circle on the path
focus.selectAll('.focus circle')
.style("opacity", 1)
};
}
drawFocus();
.tooltip {
position: absolute;
text-align: left;
font-family: "Open Sans Condensed";
font-size: 12px;
width: 80px;
height: 52px;
padding: 8px;
background: white;
pointer-events: none;
background-color: white;
line-height: 0.05em;
padding: 20px;
/* border: solid;
border-width: 1px; */
}
#my_dataviz {
padding: 20px;
}
<script src="https://d3js.org/d3.v5.js"></script>
<div id="my_dataviz"></div>