I am trying to show the 9 cells of a 3x3 matrix using egui. I want a 3x3 grid that matches the entries in the matrix. So far I have this:
Where the two numbers are the (0,0) and (0, 1) entries in the matrix, but I want them side by side.
I got them with this snippet:
let (_pos, mut mat) = dual_to_components(&mesh.verts.get_mut()[0].data);
if ui.add(ne_gui::DragValue::new(&mut mat[(0,0)]).speed(0.01)).changed()
{
update_covariance(&mut mesh.verts.get_mut()[0].data.position, &mat);
}
if ui.add(ne_gui::DragValue::new(&mut mat[(0,1)]).speed(0.01)).changed()
{
mat[(1,0)] = mat[(0,1)];
update_covariance(&mut mesh.verts.get_mut()[0].data.position, &mat);
}
});
How can I get a properly formatted 3x3?
Using egui::Ui::horizontal looks like a reasonable option here?
for row in 0..3 {
ui.horizontal(|ui| {
for col in 0..3 {
ui.add(egui::DragValue::new(&mut mat[3 * row + col]).speed(0.01));
}
});
}
This code snippet gives something like this:
Related
I am trying to plot some flow diagrams using d3's sankey.js.
I am stuck at arranging nodes x positions in the diagrams.
t2_a should be in same column as t2_b as they represent quantity from same time period. However by default this is placed at the end which gives wrong interpretation.
I can arrange manually for small number of nodes but its really difficult when number of nodes increase. Any help or suggestion would be highly appreciated.
In sankey.js comment the moveSinksRight call in computeNodeBreadths:
function computeNodeBreadths() {
var remainingNodes = nodes,
nextNodes,
x = 0;
while (remainingNodes.length) {
nextNodes = [];
remainingNodes.forEach(function(node) {
node.x = x;
node.dx = nodeWidth;
node.sourceLinks.forEach(function(link) {
nextNodes.push(link.target);
});
});
remainingNodes = nextNodes;
++x;
}
//
// moveSinksRight(x); <-- comment this
scaleNodeBreadths((width - nodeWidth) / (x - 1));
}
I have a working jsfiddle that I made using JSXGraph, a graphing toolkit for mathematical functions. I'd like to port it to D3.js for personal edification, but I'm having a hard time getting started.
The jsfiddle graphs the value of -ke(-x/T) + k, where x is an independent variable and the values of k and t come from sliders.
board.create('functiongraph',
[
// y = -k * e(-x/t) + k
function(x) { return -k.Value()*Math.exp(-x/t.Value()) + k.Value(); },
0
]
);
The three things I'm most stumped on:
Actually drawing the graph and its axes - it's not clear to me which of the many parts of the D3 API I should be using, or what level of abstraction I should be operating at.
Re-rendering the graph when a slider is changed, and making the graph aware of the value of the sliders.
Zooming out the graph so that the asymptote defined by y = k is always visible and not within the top 15% of the graph. I do this now with:
function getAestheticBoundingBox() {
var kMag = k.Value();
var tMag = t.Value();
var safeMinimum = 10;
var limit = Math.max(safeMinimum, 1.15 * Math.max(k.Value(), t.Value()));
return [0, Math.ceil(limit), Math.ceil(limit), 0];
}
What's the right way for me to tackle this problem?
I threw this example together really quick, so don't ding me on the code quality. But it should give you a good starting point for how you'd do something like this in d3. I implemented everything in straight d3, even the sliders.
As #LarKotthoff says, the key is that you have to loop your function and build your data:
// define your function
var func = function(x) {
return -sliders.k() * Math.exp(-x / sliders.t()) + sliders.k();
},
// your step for looping function
step = 0.01;
drawPlot();
function drawPlot() {
// avoid first callback before both sliders are created
if (!sliders.k ||
!sliders.t) return;
// set your limits
var kMag = sliders.k();
var tMag = sliders.t();
var safeMinimum = 10;
var limit = Math.max(safeMinimum, 1.15 * Math.max(kMag, tMag));
// generate your data
var data = [];
for (var i = 0; i < limit; i += step) {
data.push({
x: i,
y: func(i)
})
}
// set our axis limits
y.domain(
[0, Math.ceil(limit)]
);
x.domain(
[0, Math.ceil(limit)]
);
// redraw axis
svg.selectAll("g.y.axis").call(yAxis);
svg.selectAll("g.x.axis").call(xAxis);
// redraw line
svg.select('.myLine')
.attr('d', lineFunc(data))
}
I am using c3.js for creating a chart and this is an issue I found out. If you have a data point with negative float x value, the tooltip rounds off this value to the nearest integer.
You can try doing this just by changing the data in this example. Just change one of the x values to a negative float value and then hover over that point and notice the value of x reported by the tooltip.
Is there any solution to this, or has anyone faced a similar problem?
In c3.js look for the following function:
Axis.prototype.getXAxisTickFormat = function getXAxisTickFormat() {
Inside this function there is a format variable that is causing the negative x-axis values to be rounded.
format = $$.isTimeSeries() ? $$.defaultAxisTimeFormat : $$.isCategorized() ? $$.categoryName : function (v) { return v < 0 ? v.toFixed(0) : v; }
The line of code above has a ternary operator that checks if the x-axis values are a 'time series' or 'categorized'. In our situation the values are neither so the format variable is set to be the following function:
function (v) { return v < 0 ? v.toFixed(0) : v; }
This function will leave any integer greater than 0 as is but it will round any negative integers to 0 decimal places and convert the integer to a string using .toFixed(0).
Replace the format line with the one I have written below and it will remove the rounding from the negative values:
format = $$.isTimeSeries() ? $$.defaultAxisTimeFormat : $$.isCategorized() ? $$.categoryName : function (v) { return v; };
I have only tested this today and although I haven't found any issues, there may be a reason why the negative numbers were converted to a string value and if so you may want leave the format line as is and just replace the 0 in .toFixed(0) with the # of decimals you desire.
[UPDATE] If you don't want to edit the c3.js source code you can also use the format options for tooltips and x/y ticks. See: http://c3js.org/samples/tooltip_format.html
This is a function I use for the y-axis values. It rounds the tick values to 3 decimal places but strips trailing zeros.
axis : {
y:{
tick: {
format: function (d) {
var df = Number( d3.format('.3f')(d) );
return df;
}
}
}
}
I got this problem. I've found contours in my picture. Approximate them and all that stuff. Now, I want to sort them by Y axis and then by X axis. Is that possible?I'm using std::sort twice for this and I always get sort for one axis only. Please answer ASAP. Thanks
bool operator()(vector<Point> c1,vector<Point>c2){
double a=boundingRect( Mat(c1)).y;
double b=boundingRect( Mat(c2)).y;
return a<b;
}
This is an example for Y axis. Using same for X axis (y=>x).
Maybe your teacher wanted you to sort them by Y first, and if the Ys are the same, sort by X. If that's the case, you should write your comparator like
bool operator()(const vector<Point>& c1, const vector<Point>& c2) {
// get bounding boxes for c1 and c2
cv::Rect bbox1 = boundingRect(cv::Mat(c1));
cv::Rect bbox2 = boundingRect(cv::Mat(c2));
// if c1's top is lower than c2's bottom, order should be c2 c1
if (c1.y > c2.y+c2.height-1) {
return false;
}
// if c2's top is lower than c1's bottom, order should be c1 c2
if (c2.y > c1.y+c1.height-1) {
return true;
}
// they have overlap in y direction, just sort them by their x
return c1.x < c2.x;
}
This could be most succinctly accomplished using std::tie, if you have access to C++11 features.
bool operator()(vector<Point> c1,vector<Point>c2)
{
double a=boundingRect( Mat(c1)).y;
double b=boundingRect( Mat(c2)).y;
return std::tie(a.y, a.x) < std::tie(b.y, b.x);
}
You then only need to call std::sort once.
I have an array, fullset(24), containing plot data for the last 24h, by the hour. This array i feed to jqPlot to create a bar graph. Works fine. But I want to show only a subset of the data, say the business hours (8-17). I do this, rather clumsily, by creating a new array containing a subset and some additional trickery with the ticks, like so:
var ticks = [];
var subset = [];
for (i = 8; i < 17; i++)
{
subset[i - 8] = fullset[i][1];
ticks.push(sprintf("%d-%d", i, i + 1));
}
But is there a better way? Is it possible to somehow tell jqPlot to show only a subset of the full set?
On the axes settings, I have set a minimum and maximum, but not sure if this will do the same as you are looking for.
axes: {
xaxis: {
min:8,
max:16,
},
},