gpt4 book ai didi

javascript - 使用 d3.js 上的下拉列表将圆圈添加到多线图

转载 作者:行者123 更新时间:2023-11-29 20:58:21 26 4
gpt4 key购买 nike

我正在尝试向以下折线图示例中的数据点添加圆圈:https://bl.ocks.org/ProQuestionAsker/8382f70af7f4a7355827c6dc4ee8817d

为了生成圆圈,我使用了以下内容:

svg.selectAll("dot")
.data(data)
.enter().append("circle")
.attr("r", 3)
.attr("color", "pink")
.attr("cx", function(d) { return x(d.Month); })
.attr("cy", function(d) { return y(+d.Sales); });

然而,如所见here ,每个水果的所有圆圈。根据线条,我希望只显示所选水果的圆圈。

非常感谢詹姆斯

最佳答案

您看到每个水果都有圆圈,因为您没有根据下拉选择过滤数据。

下面是一个执行数据过滤和附加点的片段:

var dataAsCsv = `Month,Sales,Fruit,Year
Jan,87,strawberry,2016
Feb,3,strawberry,2016
Mar,89,strawberry,2016
Apr,56,strawberry,2016
May,1,strawberry,2016
Jun,17,strawberry,2016
Jul,59,strawberry,2016
Aug,43,strawberry,2016
Sep,16,strawberry,2016
Oct,94,strawberry,2016
Nov,99,strawberry,2016
Dec,53,strawberry,2016
Jan,93,grape,2016
Feb,8,grape,2016
Mar,95,grape,2016
Apr,62,grape,2016
May,5,grape,2016
Jun,24,grape,2016
Jul,62,grape,2016
Aug,49,grape,2016
Sep,18,grape,2016
Oct,101,grape,2016
Nov,103,grape,2016
Dec,53,grape,2016
Jan,94,blueberry,2016
Feb,15,blueberry,2016
Mar,95,blueberry,2016
Apr,64,blueberry,2016
May,11,blueberry,2016
Jun,33,blueberry,2016
Jul,64,blueberry,2016
Aug,53,blueberry,2016
Sep,27,blueberry,2016
Oct,103,blueberry,2016
Nov,108,blueberry,2016
Dec,62,blueberry,2016
Jan,80,strawberry,2015
Feb,0,strawberry,2015
Mar,71,strawberry,2015
Apr,51,strawberry,2015
May,3,strawberry,2015
Jun,11,strawberry,2015
Jul,56,strawberry,2015
Aug,34,strawberry,2015
Sep,12,strawberry,2015
Oct,75,strawberry,2015
Nov,94,strawberry,2015
Dec,46,strawberry,2015
Jan,76,grape,2015
Feb,0,grape,2015
Mar,78,grape,2015
Apr,58,grape,2015
May,10,grape,2015
Jun,22,grape,2015
Jul,47,grape,2015
Aug,36,grape,2015
Sep,18,grape,2015
Oct,86,grape,2015
Nov,98,grape,2015
Dec,40,grape,2015
Jan,79,blueberry,2015
Feb,0,blueberry,2015
Mar,78,blueberry,2015
Apr,49,blueberry,2015
May,5,blueberry,2015
Jun,31,blueberry,2015
Jul,62,blueberry,2015
Aug,49,blueberry,2015
Sep,7,blueberry,2015
Oct,86,blueberry,2015
Nov,100,blueberry,2015
Dec,46,blueberry,2015`;


// Set the margins
var margin = {top: 60, right: 100, bottom: 20, left: 80},
width = 850 - margin.left - margin.right,
height = 370 - margin.top - margin.bottom;

// Parse the month variable
var parseMonth = d3.timeParse("%b");
var formatMonth = d3.timeFormat("%b");

var formatYear = d3.timeFormat("%Y");
var parseYear = d3.timeParse("%Y");


// Set the ranges
var x = d3.scaleTime().domain([parseMonth("Jan"), parseMonth("Dec")]).range([0, width]);
var y = d3.scaleLinear().range([height, 0]);


// Define the line
var valueLine = d3.line()
.x(function(d) { return x(d.Month); })
.y(function(d) { return y(+d.Sales); })

// Create the svg canvas in the "graph" div
var svg = d3.select("#graph")
.append("svg")
.style("width", width + margin.left + margin.right + "px")
.style("height", height + margin.top + margin.bottom + "px")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform","translate(" + margin.left + "," + margin.top + ")")
.attr("class", "svg");


var data = d3.csvParse(dataAsCsv);

// Format the data
data.forEach(function(d) {
d.Month = parseMonth(d.Month);
d.Sales = +d.Sales;
d.Fruit = d.Fruit;
d.Year = formatYear(parseYear(+d.Year));
});

var nest = d3.nest()
.key(function(d){
return d.Fruit;
})
.key(function(d){
return d.Year;
})
.entries(data)

// Scale the range of the data
x.domain(d3.extent(data, function(d) { return d.Month; }));
y.domain([0, d3.max(data, function(d) { return d.Sales; })]);

// Set up the x axis
var xaxis = svg.append("g")
.attr("transform", "translate(0," + height + ")")
.attr("class", "x axis")
.call(d3.axisBottom(x)
.ticks(d3.timeMonth)
.tickSize(0, 0)
.tickFormat(d3.timeFormat("%B"))
.tickSizeInner(0)
.tickPadding(10));

// Add the Y Axis
var yaxis = svg.append("g")
.attr("class", "y axis")
.call(d3.axisLeft(y)
.ticks(5)
.tickSizeInner(0)
.tickPadding(6)
.tickSize(0, 0));

// Add a label to the y axis
svg.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 0 - 60)
.attr("x", 0 - (height / 2))
.attr("dy", "1em")
.style("text-anchor", "middle")
.text("Monthly Sales")
.attr("class", "y axis label");

svg.append('g').classed('data-points', true);

// Create a dropdown
var fruitMenu = d3.select("#fruitDropdown")

fruitMenu
.append("select")
.selectAll("option")
.data(nest)
.enter()
.append("option")
.attr("value", function(d){
return d.key;
})
.text(function(d){
return d.key;
})



// Function to create the initial graph
var initialGraph = function(fruit){

// Filter the data to include only fruit of interest
var selectFruit = nest.filter(function(d){
return d.key == fruit;
})

var selectFruitGroups = svg.selectAll(".fruitGroups")
.data(selectFruit, function(d){
return d ? d.key : this.key;
})
.enter()
.append("g")
.attr("class", "fruitGroups")

var initialPath = selectFruitGroups.selectAll(".line")
.data(function(d) { return d.values; })
.enter()
.append("path")

initialPath
.attr("d", function(d){
return valueLine(d.values)
})
.attr("class", "line")

svg.select('g.data-points').selectAll("dot")
.data(data.filter(function(d) {
return d.Fruit === fruit;
}))
.enter().append("circle").classed('dot', true)
.attr("r", 3)
.style("fill", "pink").style('stroke', '#000')
.attr("cx", function(d) { return x(d.Month); })
.attr("cy", function(d) { return y(+d.Sales); });

}

// Create initial graph
initialGraph("strawberry")


// Update the data
var updateGraph = function(fruit){

// Filter the data to include only fruit of interest
var selectFruit = nest.filter(function(d){
return d.key == fruit;
})

// Select all of the grouped elements and update the data
var selectFruitGroups = svg.selectAll(".fruitGroups")
.data(selectFruit)

// Select all the lines and transition to new positions
selectFruitGroups.selectAll("path.line")
.data(function(d){
return (d.values);
})
.transition()
.duration(1000)
.attr("d", function(d){
return valueLine(d.values)
});

var circles = svg.select('g.data-points').selectAll(".dot")
.data(data.filter(function(d) {
return d.Fruit === fruit;
}));

circles
.enter().append("circle")
.merge(circles).classed('data-point', true)
.attr("r", 3)
.style("fill", "pink").style('stroke', '#000')
.transition().duration(1000)
.attr("cx", function(d) { return x(d.Month); })
.attr("cy", function(d) { return y(+d.Sales); });

}


// Run update function when dropdown selection changes
fruitMenu.on('change', function(){

// Find which fruit was selected from the dropdown
var selectedFruit = d3.select(this)
.select("select")
.property("value")

// Run update function with the selected fruit
updateGraph(selectedFruit)


});
.line {
fill: none;
stroke: #EF5285;
stroke-width: 2px;
}
<script src="https://d3js.org/d3.v4.js"></script>


<div id = "fruitDropdown"></div>
<div id="graph"></div>

重要的代码更改:

  1. 而不是附加 circles直接到 SVG , 我创建了一个群组 <g class="data-points"></g>拥有所有的点。

    svg.append('g').classed('data-points', true);
  2. 在两个函数中输入/更新/退出上述组中的所有点,即 initialGraphupdateGraph

    初始图:

    svg.select('g.data-points').selectAll("dot")
    .data(data.filter(function(d) {
    return d.Fruit === fruit;
    }))
    .enter().append("circle").classed('dot', true)
    .attr("r", 3)
    .style("fill", "pink").style('stroke', '#000')
    .attr("cx", function(d) { return x(d.Month); })
    .attr("cy", function(d) { return y(+d.Sales); });

    更新图表:

    var circles = svg.select('g.data-points').selectAll(".dot")
    .data(data.filter(function(d) {
    return d.Fruit === fruit;
    }));

    circles
    .enter().append("circle")
    .merge(circles).classed('data-point', true)
    .attr("r", 3)
    .style("fill", "pink").style('stroke', '#000')
    .transition().duration(1000)
    .attr("cx", function(d) { return x(d.Month); })
    .attr("cy", function(d) { return y(+d.Sales); });

观察绑定(bind)到圆圈的基于所选水果的数据过滤,并应用过渡以匹配线条的过渡。

  1. 总是使用style申请fill而不是 attr .这是一个很好的做法。添加color:pink不会改变圆圈的颜色,但 fill会。此外,我添加了一个 stroke为了使它们即使是粉红色 也可见。不过,您可以随时更改它。

我建议您每次提问时都添加一个代码片段,而不是提供链接。这对任何人来说都更容易调试和帮助修复错误。

希望这对您有所帮助。 :)

关于javascript - 使用 d3.js 上的下拉列表将圆圈添加到多线图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48036954/

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