Canvas HTML5 datapoints to arrays - javascript

I hope someone can guide me on how to convert long data points into arrays as i have a long list to plot and i hope of an easier way to loop instead of typing x 50 times.
Currently, i have data points where x increment of +.25 and y is calculated from a formula below.
Example:
dataPoints: [
{ x: 0, y: 1000*(0.5/(50*0.6))* (Math.exp(-((6)/(50*0.6)*0))) }
];
Link to demo: http://jsfiddle.net/QwZuf/95/
Thank you!

You just need a simple for loop:
var dataPoints = [];
for (var x = 0; x <= 12.5; x += 0.25) {
dataPoints.push({
x: x,
y: 1000*(0.5/(50*0.6))* (Math.exp(-((6)/(50*0.6)*x)))
});
}
and then pass that array as the dataPoints parameter to the plotting function.
See http://jsfiddle.net/alnitak/xQpv7/

Related

how to plot two points on y axis for single x axis value (Maybe date) using plotly js

I have data set like the one shown below. For each date, I have one or more points to plot on the y-axis.
x axis (y axis) - 2021-07-01 (20, 30)
x axis (y axis) - 2021-07-02 (20)
x axis (y axis) - 2021-07-04 (10, 50)
x axis (y axis) - 2021-07-06 (40)
How to plot this data using Plotly js
If you have one or more y-values for each x-value (say in the form of a 2D array), you can loop through this array to flatten it, and repeat the necessary x-values from the original x-value array. The codepen for this is here.
var x = ["2021-07-01","2021-07-02","2021-07-04","2021-07-06"]
var y = [[20, 30],[20],[10,50],[40]]
var x_plot = []
var y_plot = []
for (let i=0; i<y.length; i++) {
for (let j=0; j<y[i].length; j++) {
x_plot.push(x[i])
y_plot.push(y[i][j])
}
}
var trace1 = {
x: x_plot,
y: y_plot,
type: 'scatter',
mode: 'markers'
}
var data = [trace1];
Plotly.newPlot('myDiv', data);
I got answer from code pen.
I think this may be useful for others as well.
If we have two y values for each x value we can duplicate x values to match y values like the one show below.
var data = [
{
x: ['2013-10-04', '2013-10-04', '2014-11-04'],
y: [1, 3, 6],
type: 'scatter'
}
];
Plotly.newPlot('myDiv', data);

Recale plotly js z axis on zoom

plotly.js 2D histograms and contour plots automatically generate a z-axis range that accommodates the entire range of z values in the dataset being plotted. This is fine to start, but when I click-and-drag on the plot to zoom in, I'd like the z axis range to also zoom in to accommodate only the range of z values currently on display; instead, the z axis never changes. Here's a codepen (forked from the plotly examples, thanks plotly) to play around with: http://codepen.io/anon/pen/MKGyJP
(codepen code inline:
var x = [];
var y = [];
for (var i = 0; i < 500; i ++) {
x[i] = Math.random();
y[i] = Math.random() + 1;
}
var data = [
{
x: x,
y: y,
type: 'histogram2d'
}
];
Plotly.newPlot('myDiv', data);
)
This seems like pretty conventional behavior - am I missing an option in the docs somewhere to do this?
If there's no built-in option to do this, an acceptable alternative solution would be to manually set new z limits in a zoom callback, which is easy enough to implement per this example: http://codepen.io/plotly/pen/dogexw - in which case my question becomes, is there a convenience method to get the min and max z currently on display?
Thanks in advance,
plotly.js doesn't have a zoom-specific callback at the moment(follow this issue for updates).
One alternative would be to add a mode bar button updating the colorscale range:
Plotly.newPlot('myDiv', data, {}, {
modeBarButtonsToAdd: [{
name: 'click here to update the colorscale range',
click: function(graphData) {
var xRange = graphData.layout.xaxis.range,
yRange = graphData.layout.yaxis.range;
var zMin, zMax;
// code that would compute the colorscale range
// given xRange and yRange
// for example given these values:
zMin = 10;
zMax = 20;
Plotly.restyle('myDiv', {zmin: zMin, zmax: zMax});
}
}]
});
Complete example: http://codepen.io/etpinard/pen/JGvNjV

I don't understand array statement

I am following the 2D breakout game tutorial on the Mozilla website. There is a bit of code that I do not understand.
var brickRowCount = 3;
var brickColumnCount = 5;
var brickWidth = 75;
var brickHeight = 20;
var brickPadding = 10;
var brickOffsetTop = 30;
var brickOffsetLeft = 30;
var bricks = [];
for(c = 0; c < brickColumnCount; c++) {
bricks[c] = []; // <-- here
for(r = 0; r < brickRowCount; r++) {
bricks[c][r] = { x: 0, y: 0 }; // <-- here
}
}
I understand in general what the code does, however, there are a few lines that are unclear exactly what they do. According to the website, "We will hold all our bricks in a two-dimensional array. It will contain the brick columns (c), which in turn will contain the brick rows (r), which in turn will each contain an object containing the x and y position to paint each brick on the screen."
I have put comments next to the lines of code that I specifically do not understand. Can someone please clarify exactly what these statements mean?
Thank you
it is creating a multidimensional array, or another way to call it, an array of array.
Each element of the array is another array, so to access them you need to use multiple [] for each dimension.. And just like any other array, they need to be initialized.
So here
bricks[c] = [];
it is initializing for each element of array bricks an array
bricks[c][r] = { x: 0, y: 0 };
here is storing an object in the position r in the array bricks[c] (which means the element in the position c in array bricks is an array too)
Some comments that might help
// create a new empty array, `[]`, in `bricks` at position `c`
bricks[c] = []
// create a new brick, {x:0,y:0}, in `bricks[c]` at position `r`
bricks[c][r] = { x: 0, y: 0 };
bricks[c] is an array within the bricks array.
bricks[c][r] contains the coordinates of the brick.
It's creating the array bricks, then within it, it is creating an array of c and adding values using r.
Could write it like this for you to visualize: bricks[bricks[c][r]]
It says that at position (c,r) in the array a literal object is placed containing two fields: x and y. Both these fields have the value 0
The syntax {x: 0 ,y: 0} is a shorthand for creating an object containing two fields and assigning a value to these fields at the same time.
bricks[c] = [] sets array element number c to be an empty array.
E.g. if you run the for loop without the second part:
var bricks = [];
for(c = 0; c < brickColumnCount; c++) {
bricks[c] = [];
}
bricks will be [ [ ], [ ], [ ], [ ], [ ] ]
If you run the full code, bricks will be
[
[ { x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 } ],
[ { x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 } ],
...
]
Think of that as a matrix, where c is columns, r is rows, and x is the cell at intersection cr
c\r r0 r1 r2 .. rn
c0 x00 x01 x02 .. x0n
c1 x10 x11 x12 .. x1n
.. .. .. .. .. ..
cn xn0 xn1 xn2 .. xnn
The array has to be initialized (that is what presented in your code), that every cell of the array (matrix) will be assigned with a value and probably (just my guess) the value will be changed trough the events happening during the game, or they will be checked or both.

Handling large datasets in dimple.js to render a chart

I wish to draw charts for large datasets using dimple.js. My code works absolutely fine. But the only problem is that the chart takes more than 45 seconds to come up. I am looking for some kind of an optimization in my code to reduce the time taken for the rendering of the chart. The following is the code for my area chart:
var dataset = [];
// The arrays xpoints and ypoints are populated dynamically
// with hundreds of thousands of points
var xpoints = chartData["xdata"];
var ypoints = chartData["ydata"];
var area1;
var svg = dimple.newSvg("#" + mychart, 700, 600);
var x, y;
for (var i = 0; i < xpoints.length; i++)
dataset.push({
x : xpoints[i],
y1 : parseFloat(ypoints[i])
});
var myChart = new dimple.chart(svg, dataset);
myChart.setBounds(75, 30, 480, 330);
y = myChart.addMeasureAxis("y", "y1");
x = myChart.addCategoryAxis("x", "x");
area1 = myChart.addSeries("First", dimple.plot.area, [ x, y ]);
var l = myChart.addLegend(65, 10, 510, 20, "right");
myChart.draw(1500);
Is there some way to optimize this code in either dimple.js itself or maybe using d3.js?
I'm afraid Dimple is not very performant for hundreds of thousands of points. It's drawing logic is built for flexibility and for cases like this you need to write specific d3 code (think of Dimple as a Swiss-Army Knife but here you need a scalpel). Even with raw d3 you might run into problems with a path containing that number of points. Certainly try raw d3 but you might need to write some more complex additional logic to average every n points together and then fill in detail on zoom. Also remember that even with perfect client code you will suffer a noticeable wait simply getting that volume of data from the server.
I found a solution!!. I was adamant on using dimple.js itself and not raw d3.
What I did was I aggregated the values first and then passed them to the chart.draw() function
The time taken to render the graph now is reduced from 40 seconds to 12 seconds, which is much better.
For now, my aggregation function just sums up the values for a particular category. Maybe the implementation in the draw() function is a little more complex and is therefore taking extra time. xpoints[] and ypoints[] are my arrays with lakhs of points.
Earlier, I just did this:
dataset.push({
x : xpoints[i],
y1 : parseFloat(ypoints[i])
});
Now, I first apply an aggregation as follows:
var isPresent = false;
for (var j = 0; j < unique_x.length; j++) {
if (xpoints[i] == unique_x[j]) {
y_val = parseFloat(ypoints[i]);
if (isNaN(y_val)) {
y_val = 0;
}
y_sum[j] = y_sum[j] + y_val;
isPresent = true;
break;
}
}
if (isPresent == false) {
unique_x.push(xpoints[i]);
y_sum.push(parseFloat(ypoints[i]));
}
Then, I do this:
for (var i = 0; i < unique_x.length; i++) {
dataset.push({
x : unique_x[i],
y1 : y_sum[i]
});

How to draw a exponential function y=ab^x using d3.js axis functionality

I am trying to draw an exponential function (y=ab^x) using the d3.js (javascript) library. I understand how to draw the axes themselves. I just need the magic that draws the actual line. I have seen description for the linear and quadratic equations but nothing more custom.
Any help would be appreciated.
I think that you need to construct the data yourself. For an exponential function, you can generate the data:
var data = [],
n = 100,
a = 1,
b = 2;
for (var k = 0; k < 100; k++) {
data.push({x: 0.01 * k, y: a * Math.pow(b, 0.01 * k)});
}
and then, use the standard code to generate a line graph, for instance, see http://bl.ocks.org/3883245.

Categories