访问多维JavaScript对象中的子键 [英] Access subkeys in multi-dimensional javascript object

查看:132
本文介绍了访问多维JavaScript对象中的子键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这真的是一个javascript问题,因为它涉及迭代多维js对象 的元素,并解释如何使用firefox控制台对该对象的表示



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



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



此循环:

  lineChart.on('renderlet',function(lineChart){
var allDots = lineChart.selectAll ('circle.dot');
allDots.on('click',function(d){
var dot2find = dx;
for(var key in allDots){// < === THIS LOOP
//现在,我只是骑自行车通过图表1找到自己的日期
if(allDots.hasOwnProperty(key)){
console.log(allDots [键]);
// if(this_x_val == dot2find)alert('Found It');
}
}
}

>

  [circle.dot,circle.dot,circle.dot,(etc,所有600多个数据元素]] 



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





当我在Firefox控制台中打开第一个 __ data __ 元素我需要访问:x(日期)值:





因此,在上面的for循环中,如何访问 x (date)



代码示例:



  var startDate = new Date(2011-11-14T16:17:54Z ); var curDDate = 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 ).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 ).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' )+ .x +\ n \\\
+Y轴(值)+X轴(日期) dy); //如何为图2和图3添加相应的y轴数据点值? };;}); d3.selectAll(circle.dot)。on(mouseover,function(){var thisDatum = d3.select(this).datum(); d3.selectAll(circle.dot ).filter(d => dx == thisDatum.x&& dy == 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 ().domain([startDate,currDate])); dc.renderAll();},1000);} function AddData(){var q = Math.floor(Math.random 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 =stylesheet/> < script src =http://cdnjs.cloudflare.com/ajax/libs/moment.js/2.7.0/moment.min.js>< / script>< div class =msg> ;点击图表1中的数据点:< / div>< div id =line-chart1>< / div>< div id =line-chart2>< / div> div id =line-chart3>< / div>< div class =msg>点击图表1中的数据点 - 警报消息框应弹出corresp。 < / div>  



要获取与clicked元素相关联的属性,只需使用:

p>

  d3.select(this).datum()

在你的情况下,如果你想要 x 属性:

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

这里是一个演示,告诉你如何做。在这个演示中,我使用相同的数据绘制两个SVG。当您将鼠标悬停在一个圆上时,它会绘制具有相同 x y 属性的SVG的圆:



  var data = [{x:20,y:30} x:40,y:60},{x:20,y:40},{x:10,y:90},{x:70,y:20} 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([ 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); circle.attr(r,10).attr(fill,teal).attr(cx,d => xScale(dx)).attr(cy,d => yScale dy)); var xAxis = d3.axisBottom(xScale); var yAxis = d3.axisLeft(yScale); svg.append(g)。attr(transform,translate(0,220) class,xAxis).call(xAxis); svg.append(g).attr(transform,translate(30,0)).attr(class,yAxis)。 (yAxis);} d3.selectAll(circle)。on(mouseover,function(){var thisDatum = d3.select(this).datum(); d3.selectAll(circle)。 => dx == thisDatum.x&& dy == 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>  


This is really a javascript question, as it involves iterating through the elements of a multidimensional js object and interpreting how to use the firefox console's representation of that object.

Using d3.js/dc.js, I have two line charts. When the user clicks on a dot point in one chart, I need to identify the same point on its companion chart. Both charts use a similar X axis, a date series. The dates will correspond exactly, so the nth datapoint on chart 1 will correspond to the nth datapoint on chart2 - so when the user clicks on chart 1, I have the data from the data point they just clicked on and I want to grab the "y" data from the same datapoint on chart 2 (identifiable by having the identical "x" datapoint on the x-axis).

I am attempting to iterate through the multidimensional javascript object (representing the datapoints on the d3.js line chart #2) and I am unsure how to access the value I need.

This loop:

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');
        }
    }
}

results in:

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

When I look inside one of those circle objects, I see this (in Firefox console):

When I open that first __data__ object in Firefox console, I see the elements I need to access: the x (date) value:

So, in my for loop above, how do I access the x (date) value and the y (numeric) value in each of those circle.dot objects?

Code Example:

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>

解决方案

You don't need any kind of loop.

To get the properties associated with the clicked element, just use:

d3.select(this).datum()

In your case, if you want the x property:

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

Here is a demo to show you how to do it. In this demo, I'm drawing two SVGs with the same data. When you hover over one circle, it paints the circle at the other SVG which has the same x and y properties:

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对象中的子键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆