(Это переформулировка вопроса, который я не задавал достаточно точно, мои извинения за это).
У меня проблема сравнения данных. У меня есть два набора данных (здесь очень упрощено):
var cat = {
continents: [
{
name:"Africa",
ab:"AF",
countries: [
{name:"Egypt",ab:"Eg"},
{name:"Niger",ab:"Ng"}
]
},
{
name:"America",
ab:"AM",
countries: [
{name:"Brasil",ab:"Br"},
{name:"Canada",ab:"Ca"},
{name:"United States",ab:"Us"},
{name:"Venezuela",ab:"Vz"}
]
},
{
name:"Asia",
ab:"AS",
countries: [...]
},
{
name:"Europe",
ab:"EU",
countries: [
{name:"France",ab:"Fr"},
{name:"Germany",ab:"Ge"},
{name:"Greece",ab:"Gr"},
{name:"Italy",ab:"It"},
{name:"United Kingdom",ab:"Uk"}
]
},
{
name:"Oceania",
ab:"OC",
countries: [...]
}
]
},
{...}
var currentNodes = [
{name:"Japan",continent:"AS",country:"Jp",x:200,y:50},
{name:"Italy",continent:"EU",country:"It",x:50,y:400},
{name:"Bologna",continent:"EU",country:"It",x:180,y:100},
{name:"Florence",continent:"EU",country:"It",x:50,y:200},
{name:"Germany",continent:"EU",country:"Ge",x:350,y:430},
{name:"Canada",continent:"AM",country:"Ca",x:180,y:400}
]
Я пытаюсь получить для каждого континента (и, на втором этапе, каждую страну) значения "ab" при условии, что они присутствуют (как "континент" и "страна") в наборе currentNodes (для того чтобы быть в состоянии их обновить).
Если я правильно понимаю, следующее возвращает все объекты в моем массиве currentNodes:
d3.select('#nav').selectAll('p').data(cat.continents).enter()
.insert('p').text(function(d) {
var filteredNodes = currentNodes.filter(function(f) {
return d.ab == f.continent;
})
return filteredNodes;})
- но я не понимаю, почему я не могу выбрать соответствующие значения:
d3.select('#nav').selectAll('p').data(cat.continents).enter()
.insert('p').text(function(d) {
var filteredNodes = currentNodes.filter(function(f) {
return d.ab == f.continent;
})
return filteredNodes.ab;})
Я был бы рад за решение, но и понять, что я здесь делаю неправильно. Большое спасибо за вашу помощь - и снисходительность!
Посмотрите на свой массив currentNodes
. В нем нет свойства, называемого ab
. Это свойство cat.continents
вместо этого.
Таким образом, если я правильно понимаю, что вы хотите, вы можете сопоставить континенты в массиве currentNodes
:
var continentList = currentNodes.map(function(d) {
return d.continent
})
И проверьте, существует ли ab
в этом новом массиве:
.text(function(d) {
return continentList.indexOf(d.ab) > -1 ? d.ab : "not in list";
})
Здесь я использую тернарный оператор и строку "не в списке" для ложного условия.
Вот демо:
var cat = {
continents: [{
name: "Africa",
ab: "AF",
countries: [{
name: "Egypt",
ab: "Eg"
}, {
name: "Niger",
ab: "Ng"
}]
}, {
name: "America",
ab: "AM",
countries: [{
name: "Brasil",
ab: "Br"
}, {
name: "Canada",
ab: "Ca"
}, {
name: "United States",
ab: "Us"
}, {
name: "Venezuela",
ab: "Vz"
}]
}, {
name: "Asia",
ab: "AS",
countries: [{
name: "Foo",
ab: "Fo"
}, {
name: "Bar",
ab: "Ba"
}]
}, {
name: "Europe",
ab: "EU",
countries: [{
name: "France",
ab: "Fr"
}, {
name: "Germany",
ab: "Ge"
}, {
name: "Greece",
ab: "Gr"
}, {
name: "Italy",
ab: "It"
}, {
name: "United Kingdom",
ab: "Uk"
}]
}, {
name: "Oceania",
ab: "OC",
countries: [{
name: "Foo",
ab: "Fo"
}, {
name: "Bar",
ab: "Ba"
}]
}]
};
var currentNodes = [{
name: "Japan",
continent: "AS",
country: "Jp",
x: 200,
y: 50
}, {
name: "Italy",
continent: "EU",
country: "It",
x: 50,
y: 400
}, {
name: "Bologna",
continent: "EU",
country: "It",
x: 180,
y: 100
}, {
name: "Florence",
continent: "EU",
country: "It",
x: 50,
y: 200
}, {
name: "Germany",
continent: "EU",
country: "Ge",
x: 350,
y: 430
}, {
name: "Canada",
continent: "AM",
country: "Ca",
x: 180,
y: 400
}];
var continentList = currentNodes.map(function(d) {
return d.continent
})
d3.select("body").selectAll(null)
.data(cat.continents)
.enter()
.append('p')
.text(function(d) {
return continentList.indexOf(d.ab) > -1 ? d.ab : "not in list";
})
<script src="//d3js.org/d3.v4.min.js"></script>
Я подозреваю, что вы не хотите показывать континенты "не в списке". В этом случае лучшая идея заключается в фильтрации массива данных перед привязкой данных к элементам (в выборе ввода).
Во втором примере вы возвращаете массив объектов, которые, как вы надеетесь, будут иметь только один элемент. Поэтому вы должны использовать
return filteredNodes[0].ab
(Конечно, вы не можете получить совпадений или несколько совпадений, если ваши наборы данных не заполнены правильно, поэтому вы можете также добавить некоторые исключения)
filteredNodes[0]
возвращает соответствующие объекты, filteredNodes[0].ab
остается неопределенным. На самом деле я чего-то не понимаю.
d3.select('body').selectAll('p').data(cat.continents.filter(function(d) { filteredNodes = currentNodes, function(f) { if (d.ab == f.continent) {return d.ab} } return filteredNodes; }))
и я не могу понять, почему это не работает.