gpt4 book ai didi

javascript - 尝试使用 Circle Tooltip 创建折线图

转载 作者:行者123 更新时间:2023-11-28 14:14:36 25 4
gpt4 key购买 nike

我正在尝试创建一个带有圆形工具提示的交互式折线图,如下所示 https://bl.ocks.org/alandunning/cfb7dcd7951826b9eacd54f0647f48d3 .

我的代码如下:HTML

<head>
<style>
circle {
fill: steelblue;
}

body {
font: 12px Arial;
}

path {
stroke: steelblue;
stroke-width: 2;
fill: none;
}

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

div.tooltip {
position: absolute;
text-align: center;
width: 80px;
height: 64px;
padding: 2px;
font: 14px sans-serif;
color: black;
background: lightsteelblue;
border: 0px;
border-radius: 8px;
pointer-events: none;
}

.overlay {
fill: none;
pointer-events: all;
}

.focus circle {
fill: #F1F3F3;
stroke: #6F257F;
stroke-width: 5px;
}

.hover-line {
stroke: #6F257F;
stroke-width: 2px;
stroke-dasharray: 3, 3;
}
</style>

</head>

<body>
<svg class='line-chart2'></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="./regression.js"></script>

</body>

回归.js

var gdp = [387.65, 410.32, 415.73, 452.69, 462.14,
478.96, 508.06, 599.59, 699.68, 808.90,
920.31, 1201.11, 1186.95, 1323.94, 1656.61,
1823.04, 1827.63, 1856.72, 2039.12, 2102.39,
2274.22, 2600.81
]; //y or GDP of India
var years = ['1996', '1997', '1998', '1999', '2000', '2001', '2002', '2003', '2004', '2005', '2006', '2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016', '2017'];

var data_gdp = []
for (i = 0; i < years.length; i++) {
data_gdp.push({
year: years[i],
value: gdp[i]
})
}

function drawChart_gdp(data, class_name) {
var svgWidth = 1200,
svgHeight = 400;
var margin = {
top: 60,
right: 60,
bottom: 60,
left: 60
};
var width = svgWidth - margin.left - margin.right;
var height = svgHeight - margin.top - margin.bottom;
var svg = d3.select(class_name)
.attr("width", svgWidth)
.attr("height", svgHeight);
var bisectDate = d3.bisector(function(d) {
return d.year;
}).left;
var g = svg.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")"
);
var x = d3.scaleTime().range([0, width]);
var y = d3.scaleLinear().rangeRound([height, 0]);

var line = d3.line()
.x(function(d) {
return x(new Date(parseInt(d.year), 0))
})
.y(function(d) {
return y(d.value)
})
x.domain(d3.extent(data, function(d) {
return new Date(parseInt(d.year), 0);
}));
y.domain(d3.extent(data, function(d) {
return d.value
}));

g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x))
.append("text")
.attr("fill", "#000")
.text("Year")
.attr("dy", "1.90em")
.attr("y", 5)
.attr("x", 500)
.attr("font-size", "20px")
.select(".domain")
.remove();

g.append("g")
.call(d3.axisLeft(y))
.append("text")
.attr("fill", "#000")
.attr("transform", "rotate(-90)")
.attr("y", -80)
.attr("x", -55)
.attr("dy", "1.90em")
.attr("text-anchor", "center")
.attr("font-size", "20px")
.text("GDP ($)")

g.append("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 focus = g.append("g")
.attr("class", "focus")
.style("display", "none");

focus.append("line")
.attr("class", "x-hover-line hover-line")
.attr("y1", 0)
.attr("y2", height);

focus.append("line")
.attr("class", "y-hover-line hover-line")
.attr("x1", width)
.attr("x2", width);

focus.append("circle")
.attr("r", 7.5);

focus.append("text")
.attr("x", 15)
.attr("dy", ".31em");

svg.append("rect")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.attr("class", "overlay")
.attr("width", width)
.attr("height", height)
.on("mouseover", function() {
focus.style("display", null);
})
.on("mouseout", function() {
focus.style("display", "none");
})
.on("mousemove", function() { //problem in this function
var x0 = d3.timeFormat("%Y")(x.invert(d3.mouse(this)[0])),
i = bisectDate(data, x0, 1);
d0 = data[i - 1],
d1 = data[i],
d = x0 - d0.year > d1.year - x0 ? d1 : d0;
focus.attr("transform", "translate(" + x(d.year) + "," + y(d.value) + ")");
focus.select("text").text(function() {
return d.value;
});
focus.select(".x-hover-line").attr("y2", height - y(d.value));
focus.select(".y-hover-line").attr("x2", width + width);
});

}
drawChart_gdp(data_gdp, '.line-chart2');

我怀疑示例中的数据是从 json 文件中提取的,但这里是从出现问题的数组中提取的,而且我认为数据的种类也有点不同。我的目标只是创建一个显示 y 轴值的圆形工具。

最佳答案

您现在面临的问题几乎与您在 previous question 中遇到的问题相反: 在那个问题中,问题是你正在处理日期对象,就好像它们是字符串一样。

现在,您正在处理字符串,就好像它们是日期对象一样。在您的数据中,年份 只是一个字符串,例如"1996"

所以,这个:

focus.attr("transform", "translate(" + x(d.year) + "," + y(d.value) + ")");

应该是:

focus.attr("transform", "translate(" + x(d3.timeParse("%Y")(d.year)) + "," + y(d.value) + ")"); 
//parsing to a date here----------------------^

下面是修改后的代码:

var gdp = [387.65, 410.32, 415.73, 452.69, 462.14,
478.96, 508.06, 599.59, 699.68, 808.90,
920.31, 1201.11, 1186.95, 1323.94, 1656.61,
1823.04, 1827.63, 1856.72, 2039.12, 2102.39,
2274.22, 2600.81
]; //y or GDP of India
var years = ['1996', '1997', '1998', '1999', '2000', '2001', '2002', '2003', '2004', '2005', '2006', '2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016', '2017'];

var data_gdp = []
for (i = 0; i < years.length; i++) {
data_gdp.push({
year: years[i],
value: gdp[i]
})
}

function drawChart_gdp(data, class_name) {
var svgWidth = 1200,
svgHeight = 400;
var margin = {
top: 60,
right: 60,
bottom: 60,
left: 60
};
var width = svgWidth - margin.left - margin.right;
var height = svgHeight - margin.top - margin.bottom;
var svg = d3.select(class_name)
.attr("width", svgWidth)
.attr("height", svgHeight);
var bisectDate = d3.bisector(function(d) {
return d.year;
}).left;
var g = svg.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")"
);
var x = d3.scaleTime().range([0, width]);
var y = d3.scaleLinear().rangeRound([height, 0]);

var line = d3.line()
.x(function(d) {
return x(new Date(parseInt(d.year), 0))
})
.y(function(d) {
return y(d.value)
})
x.domain(d3.extent(data, function(d) {
return new Date(parseInt(d.year), 0);
}));
y.domain(d3.extent(data, function(d) {
return d.value
}));

g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x))
.append("text")
.attr("fill", "#000")
.text("Year")
.attr("dy", "1.90em")
.attr("y", 5)
.attr("x", 500)
.attr("font-size", "20px")
.select(".domain")
.remove();

g.append("g")
.call(d3.axisLeft(y))
.append("text")
.attr("fill", "#000")
.attr("transform", "rotate(-90)")
.attr("y", -80)
.attr("x", -55)
.attr("dy", "1.90em")
.attr("text-anchor", "center")
.attr("font-size", "20px")
.text("GDP ($)")

g.append("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 focus = g.append("g")
.attr("class", "focus")
.style("display", "none");

focus.append("line")
.attr("class", "x-hover-line hover-line")
.attr("y1", 0)
.attr("y2", height);

focus.append("line")
.attr("class", "y-hover-line hover-line")
.attr("x1", width)
.attr("x2", width);

focus.append("circle")
.attr("r", 7.5);

focus.append("text")
.attr("x", 15)
.attr("dy", ".31em");

svg.append("rect")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.attr("class", "overlay")
.attr("width", width)
.attr("height", height)
.on("mouseover", function() {
focus.style("display", null);
})
.on("mouseout", function() {
focus.style("display", "none");
})
.on("mousemove", function() { //problem in this function
var x0 = d3.timeFormat("%Y")(x.invert(d3.mouse(this)[0])),
i = bisectDate(data, x0, 1);
d0 = data[i - 1],
d1 = data[i],
d = x0 - d0.year > d1.year - x0 ? d1 : d0;
focus.attr("transform", "translate(" + x(d3.timeParse("%Y")(d.year)) + "," + y(d.value) + ")");
focus.select("text").text(function() {
return d.value;
});
focus.select(".x-hover-line").attr("y2", height - y(d.value));
focus.select(".y-hover-line").attr("x2", width + width);
});

}
drawChart_gdp(data_gdp, '.line-chart2');
<head>
<style>
circle {
fill: steelblue;
}

body {
font: 12px Arial;
}

path {
stroke: steelblue;
stroke-width: 2;
fill: none;
}

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

div.tooltip {
position: absolute;
text-align: center;
width: 80px;
height: 64px;
padding: 2px;
font: 14px sans-serif;
color: black;
background: lightsteelblue;
border: 0px;
border-radius: 8px;
pointer-events: none;
}

.overlay {
fill: none;
pointer-events: all;
}

.focus circle {
fill: #F1F3F3;
stroke: #6F257F;
stroke-width: 5px;
}

.hover-line {
stroke: #6F257F;
stroke-width: 2px;
stroke-dasharray: 3, 3;
}

</style>

</head>

<body>
<svg class='line-chart2'></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
</body>

正如您现在所知道的,所有这些混淆都是因为您的数据数组中有字符串,但 x 是一个时间尺度。我的建议:解析数据数组中的字符串,创建日期对象,并在代码中保持一致,将所有数据作为日期对象处理,而不是字符串。

关于javascript - 尝试使用 Circle Tooltip 创建折线图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56051746/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com