gpt4 book ai didi

javascript - 访问多维 JavaScript 对象中的子键

转载 作者:行者123 更新时间:2023-11-29 23:53:51 26 4
gpt4 key购买 nike

这实际上是一个 JavaScript 问题,因为它涉及遍历多维 js 对象的元素并解释如何使用 Firefox 控制台对该对象的表示。

使用 d3.js/dc.js,我有两个折线图。当用户单击一个图表中的点时,我需要在其配套图表上识别相同的点。两个图表都使用类似的 X 轴,即日期系列。日期将完全对应,因此图表 1 上的第 n 个数据点将对应于图表 2 上的第 n 个数据点 - 因此当用户点击图表 1 时,我有他们刚刚点击的数据点的数据,我想获取“y”数据来自图表 2 上的同一数据点(可通过在 x 轴上具有相同的“x”数据点来识别)。

我正在尝试遍历多维 JavaScript 对象(代表 d3.js 折线图 #2 上的数据点),但我不确定如何访问我需要的值。

这个循环:

lineChart.on('renderlet', function(lineChart) {
var allDots = lineChart.selectAll('circle.dot');
allDots.on('click', function(d) {
var dot2find = d.x;
for (var key in allDots) { //<=== THIS LOOP
//at the moment, I am just cycling through chart 1 to find its own date
if (allDots.hasOwnProperty(key)) {
console.log(allDots[key]);
//if (this_x_val == dot2find) alert('Found It');
}
}
}

结果:

[circle.dot, circle.dot, circle.dot, (etc, all the 600+ data elements)]

Array of circle.dot chart objects

当我查看其中一个圆形对象时,我看到了这个(在 Firefox 控制台中):

Inside one circle.dot object, in the Firefox console

当我在 Firefox 控制台中打开第一个 __data__ 对象时,我看到了我需要访问的元素:x(日期)值:

I need the x and y values from the line chart, revealed here

因此,在上面的 for 循环中,我如何访问每个 circle.dot 对象中的 x(日期)值和 y(数字)值?

代码示例:

var startDate = new Date("2011-11-14T16:17:54Z");
var currDate = moment(startDate);
var cf = crossfilter([{date: startDate, quantity: 1}]);
AddData();

var timeDimension = cf.dimension(function(d){ return d.date; });
var totalGroup = timeDimension.group().reduceSum(function(d){ return d.quantity; });

var lineChart1 = dc.lineChart("#line-chart1")
.brushOn(false)
.width(800)
.height(200)
.elasticY(true)
.x(d3.time.scale().domain([startDate, currDate]))
.dimension(timeDimension)
.group(totalGroup);
var lineChart2 = dc.lineChart("#line-chart2")
.brushOn(false)
.width(800)
.height(200)
.elasticY(true)
.x(d3.time.scale().domain([startDate, currDate]))
.dimension(timeDimension)
.group(totalGroup);
var lineChart3 = dc.lineChart("#line-chart3")
.brushOn(false)
.width(800)
.height(200)
.elasticY(true)
.x(d3.time.scale().domain([startDate, currDate]))
.dimension(timeDimension)
.group(totalGroup);

dc.renderAll();

lineChart1.on('renderlet', function(lineChart1) {
lineChart1.selectAll('circle.dot').on('click', function(d) {
alert('Chart One: X-axis (Date): ' +d.x+"\n\n"+ "Y-axis (Value): "+d.y);
//How would I add the corresponding y-axis datapoint values for charts 2 and 3?
});
});

d3.selectAll("circle.dot").on("mouseover", function(){
var thisDatum = d3.select(this).datum();
d3.selectAll("circle.dot").filter(d=>d.x == thisDatum.x && d.y == thisDatum.y).attr("fill", "firebrick");
}).on("mouseout", function(){
d3.selectAll("circle.dot").attr("fill", "teal")
})

for (var nn=1;nn<6;nn++){
setTimeout(function(){
AddData();
lineChart1.x(d3.time.scale().domain([startDate, currDate]));
lineChart2.x(d3.time.scale().domain([startDate, currDate]));
lineChart3.x(d3.time.scale().domain([startDate, currDate]));
dc.renderAll();
},1000);
}

function AddData(){
var q = Math.floor(Math.random() * 6) + 1;
currDate = currDate.add('month', 1);
cf.add( [{date: currDate.clone().toDate(), quantity: q}]);
}
#line-chart3{margin-bottom:10px;}
.msg{font-family:Arial,Helvetica;font-size:1.2rem;color:brown;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.3/d3.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.1/crossfilter.min.js"></script>
<script src="http://dc-js.github.io/dc.js/js/dc.js"></script>
<link href="http://dc-js.github.io/dc.js/css/dc.css" rel="stylesheet"/>
<script src="http://cdnjs.cloudflare.com/ajax/libs/moment.js/2.7.0/moment.min.js"></script>

<div class="msg">Click a data point in chart 1:</div>
<div id="line-chart1"></div>
<div id="line-chart2"></div>
<div id="line-chart3"></div>
<div class="msg">Click on a data point in chart 1 -- an alert messagebox should pop-up with the corresp. datapoint values from all 3 line charts.</div>

最佳答案

你不需要任何类型的循环。

要获取与被点击元素关联的属性,只需使用:

d3.select(this).datum()

在你的例子中,如果你想要 x 属性:

d3.select(this).datum().x

这是一个演示,向您展示如何操作。在此演示中,我绘制了两个具有相同数据的 SVG。当您将鼠标悬停在一个圆上时,它会在另一个具有相同 xy 属性的 SVG 上绘制圆:

var data = [{x:20, y:30},
{x:40, y:60},
{x:20, y:40},
{x:10, y:90},
{x:70, y:20},
{x:60, y:90},
{x:30, y:90},
{x:90, y:10}];

draw("#svg1");
draw("#svg2");

function draw(selector){

var width = 250,
height = 250;

var svg = d3.select(selector)
.append("svg")
.attr("width", width)
.attr("height", height);

var xScale = d3.scaleLinear()
.domain([0, 100])
.range([30, width - 10]);

var yScale = d3.scaleLinear()
.domain([0,100])
.range([height - 30, 10]);

var circles = svg.selectAll("foo")
.data(data)
.enter()
.append("circle");

circles.attr("r", 10)
.attr("fill", "teal")
.attr("cx", d=>xScale(d.x))
.attr("cy", d=>yScale(d.y));

var xAxis = d3.axisBottom(xScale);
var yAxis = d3.axisLeft(yScale);

svg.append("g").attr("transform", "translate(0,220)")
.attr("class", "xAxis")
.call(xAxis);

svg.append("g")
.attr("transform", "translate(30,0)")
.attr("class", "yAxis")
.call(yAxis);

}

d3.selectAll("circle").on("mouseover", function(){
var thisDatum = d3.select(this).datum();
d3.selectAll("circle").filter(d=>d.x == thisDatum.x && d.y == thisDatum.y).attr("fill", "firebrick");
}).on("mouseout", function(){
d3.selectAll("circle").attr("fill", "teal")
})
#svg1 {
float: left;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div id="svg1"></div>
<div id="svg2"></div>

关于javascript - 访问多维 JavaScript 对象中的子键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42150936/

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