gpt4 book ai didi

javascript - D3 似乎更新了错误的 SVG 元素

转载 作者:行者123 更新时间:2023-11-30 15:27:13 25 4
gpt4 key购买 nike

我有一个 d3 布局,旨在生成 3 个图表:

  1. 带过渡的自定义项目布局
  2. 按类别划分的销售额饼图(在某些点上有过渡)
  3. 带转换的前 5 个表现项目的条形图。

1 & 2 工作正常,但是当我添加第三个图表时,我看到一些奇怪的行为。目的是创建一个条形图,其中每个条形的宽度与前 N 个项目的销售指标相关联,如下所示:

data = data.filter(function(d){ return d.date === someDate});

var cf = crossfilter(data);
var salesDimension = cf.dimension(function(d){ return d.sales; });

topData = salesDimension.top(5);

问题是我的代码没有绘制条形图,而是以某种方式覆盖了图表 1 中 5 个项目的位置并将它们移回原点。如果我将上面的 5 更改为 10,则将覆盖 10 个项目,依此类推。

我仔细检查了变量的范围,甚至尝试更改 drawTopItems() 中所有内容的名称,但没有任何区别。我怀疑在选择 svg 元素或将类应用于我想修改的 svg 组元素时我做错了什么,但我终究无法看到什么。谁能告诉我我可能做错了什么?

这是我的 fiddle 问题:https://jsfiddle.net/Sledge/4eggpd5e/12/ .

这是我的javascript代码:

var item_width = 40, item_height = 60;
var margin = {top: 50, right: 50, bottom: 75, left: 40},
width = 700 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scaleLinear().range([0, width]);
var y = d3.scaleLinear().range([0, height]);
var colorScale = d3.scaleLinear().domain([500,3000]).range(["white","#4169e1"]);

// Pie Chart parameters
var pieWidth = 300, pieHeight = 300;
var outerRadius = Math.min(pieWidth, pieHeight) / 2,
innerRadius = outerRadius * .50;
var pieColor = d3.scaleOrdinal(['#42b9f4','#3791f2','#374ff1','#25b22e','#107222']); // custom color scale
var legendRectSize = 18; // NEW
var legendSpacing = 4; // NEW

// Top Item Parameters
var topItemMargin = {top:25, right:25, bottom: 25, left: 25};
var topItemWidth = 300 - topItemMargin.left - topItemMargin.right,
topItemHeight = 300 - topItemMargin.top - topItemMargin.bottom;
var topItemXScale = d3.scaleLinear().range([0, topItemWidth]);
var barHeight = 20, barSpacing = 5;


/* SVG */
var svgItemLayout = d3.select("#item_layout")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var svgPieChart = d3.select("#pie_chart")
.append("svg")
.attr("width", pieWidth)
.attr("height", pieHeight)
.append("g")
.attr("transform", "translate(" + outerRadius + "," + outerRadius + ")") ;

var svgTopItems = d3.select("#top_items")
.append("svg")
.attr("width", topItemWidth)
.attr("height", topItemHeight)
.append("g")
.attr("transform", "translate(" + topItemMargin.left + "," + topItemMargin.top + ")");


/* DRAW FUNCTIONS */
// a single function to draw
function drawItemLayout(data, someDate){

data.forEach(function(d) {
d.x_pos = +d.x_pos;
d.y_pos = +d.y_pos;
d.sales = +d.sales;
});

// pre-filter data
data = data.filter(function(d){ return d.date === someDate});

var x_offset = 5, y_offset = 5;

x.domain(d3.extent(data, function(d) { return d.x_pos; })); // set the x domain
y.domain(d3.extent(data, function(d) { return d.y_pos; })); // set the y domain

// create an update selection with a key function
var g_sel = svgItemLayout.selectAll("g")
.data(data, function(d){
return d.item_name;
});

// get rid of those leaving the update
g_sel.exit().remove();

// our entering g
var g_ent = g_sel.enter()
.append("g");

// add our rects to our g
g_ent.append("rect")
.attr("class", "dot") // wonder if I really need this class?
.attr("width", item_width)
.attr("height", item_height)
.attr("rx", 3)
.attr("ry", 3)
.style("fill", function(d){ return colorScale(d.sales); }) // color factor variable
.style("fill-opacity", 0.5);

// add our text to our g
g_ent.append("text")
.attr("font-size", 10)
.attr("text-anchor", "middle")
.attr("fill", "black")
.attr("dx", item_width/2)
.attr("dy", item_height/2)
.text(function(d){ return d.item_name; });

// UPDATE + ENTER selection
g_sel = g_ent.merge(g_sel);

// move them into position with transition
g_sel
.transition()
.duration(1200)
.delay(function(d, i) { return i *40; })
.attr("transform", function(d){
return "translate(" + (x(d.x_pos) + x_offset) + "," + (y(d.y_pos) + y_offset) + ")";
});

}

function drawPieChart(data, someDate) {

data.forEach(function(d) {
d.x_pos = +d.x_pos;
d.y_pos = +d.y_pos;
d.sales = +d.sales;
});

// pre-filter data
data = data.filter(function(d){ return d.date === someDate});

var cf = crossfilter(data);
var salesDimension = cf.dimension(function(d){ return d.sales; });
var categoryDimension = cf.dimension(function(d){ return d.category; });
var categoryGroup = categoryDimension.group();

function reduceInitial(p, v) {
return {
sales : 0,
count : 0
};
}

function reduceAdd(p, v) {
p.sales = p.sales + v.sales;
p.count = p.count + 1;
return p;
}

function reduceRemove(p, v) {
p.sales = p.sales - v.sales;
p.count = p.count - 1;
return p;
}

categoryAggregated = categoryGroup.reduce(reduceAdd, reduceRemove, reduceInitial).all();

var arc = d3.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius);

var pie = d3.pie()
.value(function(d) { return d.value.sales; })
.sort(null);

var path = svgPieChart.selectAll('path')
.data(pie(categoryAggregated))
.enter()
.append('path')
.attr('d', arc)
.attr('fill', function(d, i) { return pieColor(i);});

// Add a legend:
var legend = svgPieChart.selectAll('.legend')
.data(pieColor.domain())
.enter()
.append('g')
.attr('class', 'legend')
.attr('transform', function(d, i) {
var height = legendRectSize + legendSpacing;
var offset = height * pieColor.domain().length / 2;
var horz = -3 * legendRectSize;
var vert = i * height - offset;
return 'translate(' + horz + ',' + vert + ')';
});

legend.append('rect')
.attr('width', legendRectSize)
.attr('height', legendRectSize)
.style('fill', pieColor)
.style('stroke', pieColor);

legend.append('text')
.attr('x', legendRectSize + legendSpacing)
.attr('y', legendRectSize - legendSpacing)
.text(function(d) { return categoryAggregated[d].key; }); // returns text based on data index

}

function drawTopItems (data, someDate) {

data.forEach(function(d) {
d.x_pos = +d.x_pos;
d.y_pos = +d.y_pos;
d.sales = +d.sales;
});

// pre-filter data
data = data.filter(function(d){ return d.date === someDate});

var cf = crossfilter(data);
var salesDimension = cf.dimension(function(d){ return d.sales; });

topData = salesDimension.top(5);

topItemXScale.domain(d3.extent(topData, function(d) { return d.sales; })); // set the x domain

var f_sel = svgTopItems.selectAll("g")
.data(topData,function(d){ return d.item_name; }).enter();

f_sel.exit().remove();

var f_ent = f_sel.enter().append("g");

f_ent.append("rect")
.attr("class", "dot") // wonder if I really need this class?
.attr("width", function(d){ return d.sales })
.attr("height", barHeight)
.style("fill","#351eff") // color factor variable
.style("fill-opacity", 0.75);

// add our text to our g
f_ent.append("text")
.attr("font-size", 10)
.attr("text-anchor", "left")
.attr("fill", "black")
.attr("dx", item_width/2)
.attr("dy", item_height/2)
.text(function(d){ return d.item_name});

// UPDATE + ENTER selection
f_sel = f_ent.merge(f_sel);

f_sel.transition()
.duration(1200)
.delay(function(d, i) { return i *40; })
.attr("transform", function(d, i){
return "translate( 0, "+ i*25 +")" + ")";
});

}

/* MAIN */
var data = d3.csvParse( d3.select("pre#data").text());
drawItemLayout(data, '1-20-2017');
drawPieChart(data, '1-20-2017');
drawTopItems(data, '1-20-2017');

/* UPDATE DATA */
function updateData(date) {

//d3.csv("http://localhost:8080/udacity_test_vis_1/output_fixture_data.csv", function(data) {
var data = d3.csvParse( d3.select("pre#data").text());
drawItemLayout (data, date);
drawPieChart(data, date);
drawTopItems(data, date);

}

/* GET SELECTION */
$("#select_params").change(function(){
var date = $("#select_params :selected").val();
console.log(date);
updateData(date);
})

最佳答案

只有三个问题:

  1. 您正在重复 enter() 函数:

    var f_sel = svgTopItems.selectAll("g")
    .data(topData,function(d){ return d.item_name; }).enter();
    //this is an enter selection...

    var f_ent = f_sel.enter().append("g");
    //and you have enter() again here

    因此,删除第一个 enter:f_sel 应该只是数据绑定(bind)选择。

  2. 在附加矩形之前将合并的选择移动到

  3. 您的翻译有一个额外的括号:

    return "translate( 0, "+ i*25 +")" + ")";

解决了这些问题后,这是您更新的 fiddle :https://jsfiddle.net/utf5hva2/

关于javascript - D3 似乎更新了错误的 SVG 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42773299/

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