What javascript array, nested array, object is most suitable for searching - javascript

I'm trying to build a colors structure that has 3 data per item. For example, red has x and y, blue has x and y, etc. So the 3 pieces of data are color, x, y
What structure do I need to make it easy to read the x and y based on the color. I usually do push(color, x, y) but that wouldn't work here, because I need to search quickly by the color without needing to loop. What structure do I need here, and how do I set it and get it.

What about a simple object (hash) ?
// Initial creation
var colors = {
blue: { x: 897, y: 98 },
red: { x: 43, y: 1334 },
yellow: { y: 12 }
}
// Adding new element to existing object
colors['green'] = { x: 19 };
// Accessing them
console.log(colors.blue.x);
console.log(colors.yellow.y);
// Accessing them with name in var
var needed = 'green';
console.log(colors[needed].x);
console.log(colors[needed]['x']);
Or did I understand you wrong?

Are you looking for something like a dictionary?!?
var colorArray = {};
colorArray["red"] = {
x: 100,
y: 200
};
colorArray["blue"] = {
x: 222,
y: 200
};
alert(colorArray["red"].x);​

var colors = {
red : { x : 42, y : 7 },
blue : { x : .., y : .. },
...
};
alert(colors.red.x);

Or if you need the color also in the array
var colors = {
blue: { color:"blue", x: 100, y: 200 },
red: { color:"red", x: 50, y: 300 },
yellow: { color:"yellow", x: 30 y: 700 }
}
You also could use string "constants":
var RED = "red";
var colors = {};
colors[RED] = { color: RED, x: 100, y: 200 };
...

var colors = [
{color: 'blue', x: 897, y: 98 },
{color: 'red', x: 25, y: 1334 },
{color: 'yellow', x: 50, y: 12 }
]
for(var i in colors) {
console.log(colors[i].color);
console.log(colors[i].x);
console.log(colors[i].y);
}
// To insert into colors
colors.push({color: 'pink', x: 150, y: 200});
or if you have structure like this
var colors = [
['red', 837, 98],
['blue', 25, 144],
['yellow', 50, 12]
];
then
for(var i in colors) {
console.log(colors[i][0]); // output: red, yellow ...
console.log(colors[i][1]); // output: 837, 25 ..
console.log(colors[i][2]); // output: 98, 144 ..
}
and to insert into colors for this structure
colors.push(['pink', 150, 200])
or
var colors = {
blue: { x: 58, y: 100 },
red: { x: 43, y: 1334 },
yellow: {x: 254, y: 12 }
}
then
for(var i in colors) {
console.log(colors[i].blue.x);
console.log(colors[i].blue.y);
// or
console.log(colors[i]['blue'].x);
// or like
console.log(colors[i]['blue']['x']);
}
// and to insert for this sturcture
colors.pink= {x: 150, y: 200};

Related

How to check if the the difference of and number and a value from my object in my array is smaller than 100?

I need to access an object and it's property and check if the the value of the property smaller than 100 is.
My code would look like following:
let myArr = [{
id: 1,
x: 120,
y: 150,
}, {
id: 2,
x: 170,
y: 420,
}, {
id: 3,
x: 160,
y: 220,
}, {
id: 4,
x: 140,
y: 170,
}];
if(nearestEnemy.x - /*go throught all of my "x"-properties*/ && nearestEnemy.y - /*go throught all of my "y"-properties*/ < 100){
}
You don't need to matter about the other code, just look at my comments.
I want to check if the x axis and the y axis is almost the same as of one of my properties from my object in my array.
I guess you'd need something like a loop for this but I can't think of anything!
I don't know if you can understand me because I cant really explain what I mean.
Thanks for you help anyway.
You can achieve this by filtering out the objects by using Array.filter() method.
let myArr = [{
id: 1,
x: 120,
y: 150
}, {
id: 2,
x: 170,
y: 420
}, {
id: 3,
x: 160,
y: 220
}, {
id: 4,
x: 140,
y: 170
}];
function difference(a, b) {
return Math.abs(a - b);
}
const filtered = myArr.filter(({x, y}) => difference(x, y) < 100);
console.log(filtered);
It sounds to me like you have an array of points and want to find an element which is the nearest to the given point. If this is the case, you can proceed like this:
write a function that computes distance (https://en.wikipedia.org/wiki/Euclidean_distance) between two points
write a loop that minimizes distance
Example:
let myArr = [
{
id: 1,
x: 120,
y: 150,
}, {
id: 2,
x: 170,
y: 420,
}, {
id: 3,
x: 160,
y: 220,
}, {
id: 4,
x: 140,
y: 170,
}];
function distance(p1, p2) {
return Math.sqrt(
(p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2,
)
}
function nearestPoint(points, somePoint) {
let min = +Infinity,
minPt = null;
for (let p of points) {
let d = distance(p, somePoint);
if (d < min) {
min = d;
minPt = p;
}
}
return minPt;
}
console.log(nearestPoint(myArr, {x: 190, y: 130}))
This is not very efficient, but should be fine for < 10,000 points. If you have more, you'll need some kind of spatial indexing.

How to add more than one array to kendo chart

I have more than one array, I want to add them to Kendo chart, I did the search could not get the solution, it will be helpful if you help me.
see the example here
Suppose I want to add one more array like this
[{
x: 33, y: 50,
}, {
x: 15, y: 26
} ]
to the xyData object, How can I do? I have applied directly like
var xyData = [[{
x: 10, y: 20,
}, {
x: 100, y: 200
} ], [{
x: 33, y: 50,
}, {
x: 15, y: 26
} ]];
this but it did not work, How to do? please help me.
You can use Array.concat() to create one new array:
var xyData = [{
x: 10, y: 20,
}, {
x: 100, y: 200
} ];
var xyData2 = [{
x: 33, y: 50,
}, {
x: 15, y: 26
} ];
var xyTotal = xyData.concat(xyData2);
DEMO

How to add fill color in highcharts data series

I need to fill the color of data series dynamically based on the variable ( left , right , center ) from my code.
I have attached my code and expected output:
$(document).ready(function() {
var left = [
[4, 7],
[9, 2]
];
var right = [
[2, 2],
[9, 9]
];
var center = [
[4,5.5],
[10,5.5]
];
Highcharts.chart('container', {
chart: {
events: {
load: function () {
const xAxis = this.xAxis[0]
const yAxis = this.yAxis[0]
const leftBottom = {
x: xAxis.toPixels(right[0][0]),
y: yAxis.toPixels(right[0][1])
}
const leftTop = {
x: xAxis.toPixels(left[0][0]),
y: yAxis.toPixels(left[0][1])
}
const rightBottom = {
x: xAxis.toPixels(left[1][0]),
y: yAxis.toPixels(left[1][1])
}
const rightTop = {
x: xAxis.toPixels(right[1][0]),
y: yAxis.toPixels(right[1][1])
}
const leftMiddle = {
x: xAxis.toPixels(4),
y: yAxis.toPixels(5.5)
}
const rightMiddle = {
x: xAxis.toPixels(10),
y: yAxis.toPixels(5.5)
}
const leftTopMiddle = {
x: xAxis.toPixels(3.7),
y: yAxis.toPixels(6.5)
}
const leftBottomMiddle = {
x: xAxis.toPixels(2.1),
y: yAxis.toPixels(4)
}
const rightTopMiddle = {
x: xAxis.toPixels(9.8),
y: yAxis.toPixels(8)
}
const rightBottomMiddle = {
x: xAxis.toPixels(9.8),
y: yAxis.toPixels(3)
}
const curveTopLeft = this.curveTopLeft = this.renderer.path().attr({
d: `M ${leftMiddle.x} ${leftMiddle.y} Q ${leftTopMiddle.x} ${leftTopMiddle.y} ${leftTop.x} ${leftTop.y}`,
'stroke-width': 2,
stroke: 'red',
zIndex: 99
}).add()
const curveBottomLeft = this.curveBottomLeft = this.renderer.path().attr({
d: `M ${leftMiddle.x} ${leftMiddle.y} Q ${leftBottomMiddle.x} ${leftBottomMiddle.y} ${leftBottom.x} ${leftBottom.y}`,
'stroke-width': 2,
stroke: 'red',
zIndex: 99
}).add()
const curveTopRight = this.curveTopRight = this.renderer.path().attr({
d: `M ${rightMiddle.x} ${rightMiddle.y} Q ${rightTopMiddle.x} ${rightTopMiddle.y} ${rightTop.x} ${rightTop.y}`,
'stroke-width': 2,
stroke: 'red',
zIndex: 99
}).add()
const curveBottomRight = this.curveBottomRight = this.renderer.path().attr({
d: `M ${rightMiddle.x} ${rightMiddle.y} Q ${rightBottomMiddle.x} ${rightBottomMiddle.y} ${rightBottom.x} ${rightBottom.y}`,
'stroke-width': 2,
stroke: 'red',
zIndex: 99
}).add()
}
}
},
title: {
text: ''
},
tooltip: {
enabled: false
},
exporting: {
enabled: false
},
credits: {
enabled: false
},
plotOptions: {
series: {
pointStart: 1
}
},
xAxis: {
max: 10,
min: 1,
tickInterval: 1
},
yAxis: {
max: 11,
min: 0,
tickInterval: 1,
},
series: [{
showInLegend: false,
data: left
}, {
showInLegend: false,
data: right
},
{
showInLegend: false,
marker: {
enabled: true
},
data: center
}],
});
});
And my expected output should look like below,
You need to create a new path with no stroke but fill. The new path should be combined from the points you already defined.
const d = `M ${leftBottom.x} ${leftBottom.y}
Q ${leftBottomMiddle.x} ${leftBottomMiddle.y} ${leftMiddle.x} ${leftMiddle.y}
Q ${leftTopMiddle.x} ${leftTopMiddle.y} ${leftTop.x} ${leftTop.y}
L ${rightBottom.x} ${rightBottom.y}
Q ${rightBottomMiddle.x} ${rightBottomMiddle.y} ${rightMiddle.x} ${rightMiddle.y}
Q ${rightTopMiddle.x} ${rightTopMiddle.y} ${rightTop.x} ${rightTop.y}
Z`
const fillPath = this.renderer.path().attr({
d: d,
'stroke-width': 0,
fill: '#b19cd9',
zIndex: 1
}).add()
example: http://jsfiddle.net/r0j46wn6/24/
You can make use of the .css() method of your this.renderer.path() to set the fill style.
For example, Let's take the case of curveTopRight for what you can add that css as,
const curveTopRight = this.curveTopRight = this.renderer.path().css({
color: '#c8bfe7',
fill: '#c8bfe7'
}).attr({
d: `M ${rightMiddle.x} ${rightMiddle.y} Q ${rightTopMiddle.x} ${rightTopMiddle.y} ${rightTop.x} ${rightTop.y}`,
'stroke-width': 2,
stroke: 'red',
zIndex: 99
}).add()
However it is working only for the curved elements and not for the area's which are between the lines that you have drawn.
Here is a partially working example:
http://jsfiddle.net/r0j46wn6/23/
Hope this helps!

Dectect click in irregular shapes inside HTML5 canvas

I am new using canvas and I created a simple script to draw irregular polygons in a canvas knowing the coord. Now I need to detect if an user clicks on one of those shapes and wich one (each object has an ID). You can see my script working here.
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext("2d");
var objetos = [];
// First Shape
objetos.push( {
id:'First',
coordinates: {
p1: {
x: 30,
y: 10
},
p2: {
x: 50,
y: 50
},
p3: {
x: 90,
y: 90
},
p4: {
x: 50,
y: 90
},
}
});
// Second Shape
objetos.push( {
id:'Two',
coordinates: {
p1: {
x: 150,
y: 20
},
p2: {
x: 90,
y: 50
},
p3: {
x: 90,
y: 30
},
}
});
// 3th Shape
objetos.push( {
id:'Shape',
coordinates: {
p1: {
x: 150,
y: 120
},
p2: {
x: 160,
y: 120
},
p3: {
x: 160,
y: 50
},
p4: {
x: 150,
y: 50
},
}
});
// Read each object
for (var i in objetos){
// Draw rhe shapes
ctx.beginPath();
var num = 0;
for (var j in objetos[i].coordinates){
if(num==0){
ctx.moveTo(objetos[i].coordinates[j]['x'], objetos[i].coordinates[j]['y']);
}else{
ctx.lineTo(objetos[i].coordinates[j]['x'], objetos[i].coordinates[j]['y']);
}
num++;
}
ctx.closePath();
ctx.lineWidth = 2;
ctx.fillStyle = '#8ED6FF';
ctx.fill();
ctx.strokeStyle = 'blue';
ctx.stroke();
}
NOTE: A cursor pointer on hover would be appreciated. =)
EDIT: Note I am using irregular shapes with no predefined number of points. Some scripts (like those on pages linked as "Possible duplication") using circles or regular polygons (certain number of sides with the same lengh do not solve my issue).

How to create a datapoint object with a loop in JS?

I would like to create this output in a JS while loop:
dataPoints: [
{ x: 10, y: 10 },
{ x: 20, y: 11 },
{ x: 30, y: 14 },
{ x: 40, y: 16 },
{ x: 50, y: 19 },
{ x: 60, y: 15 },
{ x: 70, y: 12 },
{ x: 80, y: 10 }
]
When I put this
sdata[i] = accumulated;
Into my loop, it adds the entries like that:
Object {
1: 1500,
2: 3005,
3: 4515.016666666666,
4: 6030.066722222222,
5: 7550.166944629629
}
What do I have to put into the loop to create the output like at the beginning?
Thanks for your help!
You're probably trying to push (x, y) points in an array. This is is how it should be done.
var sdata = []; // an array;
assuming that accumulated is a point it should have a structure like below
accumulated = { x: 10, y: 20};
Next is just create the points and push it to the array.
while(/*loop-condition-*/) {
var accumulated = {
x: xCurrent,
y: yCurrent
};
sdata.push(accmulated);
}
//that's it.
sdata now has the output as desired

Categories

Resources