Adding TextLabels to ZedGraph so that all values are shown - zedgraph

When adding TextLabels to the X-Axis, zedgraph seems to insist on adding the labels each 10th step (So it seems). Explaination follows.
I have an array with values, based on some calculation. The first values in the array are on the following indexes; 8, 23, 39, 69 and 100
I have the x-axis set to Text
pane.X2Axis.Type = AxisType.Text;
Now if I do this:
pane.X2Axis.Type = AxisType.Text;
pane.X2Axis.Scale.TextLabels = monthValues;
pane.X2Axis.Scale.MinorStep = 5;
pane.X2Axis.Scale.MajorStep = 15;
The x2-axis doesn't show anything, where I want it to show all the values that are in the monthValues array, according to the curve.
If I do this:
pane.X2Axis.Scale.MajorStep = 8;
The x2-axis will now show the value at index 8, and if I do this:
pane.X2Axis.Scale.MajorStep = 23;
The x2-axis will show the value at index 23 and so on.
Obviously this is not desirable, so I wanted to know If anyone has an idea of what the real problem is, and how to fix it. I really hope someone can help me out, I've spent a lot of time trying to figure this out.
Thanks a lot

Have you tried adding min and maxfor the X2Axis?
Also try ChangeAxis command

Related

AE Expression to increment slider value (on text layer) whenever a frame lands on a marker?

I am completely new to AE expressions.
Suppose that I have bunch of layer markers on a text layer, and the text is linked to a slider control:
Now, what I want is that whenever the playhead (or the current frame) lands on the next marker(s), I want the slider to increment by 1, like this:
I want an expression which I can add to the Slider to achieve the desired result. Your help would be greatly appreciated. Thank you.
I posted this question on Reddit as well, they told me to use ChatGPT. I tried using it, but it doesn't achieve the desired result after trying several different prompts and even when breaking down the problem into parts.
I finally figured it out, I got rid of the slider, added a "Numbers" effect to the text layer (which displays the counter), and added the following expression code to the "Value/..." property:
for (i = 1; i <= thisLayer.marker.numKeys; i++) {
if (thisLayer.marker.key(i).time <= time) {
value = value + 1;
}
else {
value;
}
}

Set Table Column width problems in iText7

When I want to create table in PDF, I can use the following two ways:
But the first one failed.
method 1:
float[] columnWidths = {20, 30, 50};
Table table = new Table(columnWidths);
It's failed to control columnWidths
method 2:
UnitValue[] unitValue = new UnitValue[]{
UnitValue.createPercentValue((float) 20),
UnitValue.createPercentValue((float) 30),
UnitValue.createPercentValue((float) 50)};
Table table = new Table(columnWidths);
It's success!
Why does this happen?
Yes, there is no way to scale column widths in iText 7.0.2, as Vernon said.
If you want to use directly 20, 30, and 50 points for columns despite min widths you shall use this construction:
Table table = new Table(new float[] {20, 30, 50}) // in points
.setWidth(100) //100 pt
.setFixedLayout();
If you set fixed layout you must set width as well, it is required for fixed layout.
The Release Notes for iText Core 7.0.2 include the bullet point "improved auto layout and fixed layout for tables, scaled column widths have been removed". If you need the old functionality, you'll need to go back to 7.0.1!
The online API docn for the Table constructor says Note, since 7.0.2 in case auto layout column width values less than min width will be ignored. It's not great English, but I believe it's trying to say that the supplied values will not be scaled up so the columns fill the table, but instead will be used as-is, in which case they're almost certain to be too small, so will be ignored. Overall, this change makes sense, since treating a handful of floats as a ratio is a bit arbitrary for a good API. Using values with units is much more sensible, and your example using proper percentages is a good one.

Implementing real time plot with Qt5 charts

I am new to Qt and trying to implement a real time plot using QSplineSeries with Qt 5.7. I need to scroll the x axis as new data comes in every 100ms. It seems the CPU usage reaches 100% if I do not purge the old data which was appended to the series, using graphSeriesX->remove(0). I found two ways of scrolling the x axis.
const uint8_t X_RANGE_COUNT = 50;
const uint8_t X_RANGE_MAX = X_RANGE_COUNT - 1;
qreal y = (axisX->max() - axisX->min()) / axisX->tickCount();
m_x += y;
if (m_x > axisX->max()) {
axisX->setMax(m_x);
axisX->setMin(m_x - 100);
}
if (graphSeries1->count() > X_RANGE_COUNT) {
graphSeries1->remove(0);
graphSeries2->remove(0);
graphSeries3->remove(0);
}
The problem with the above is that m_x is of type qreal and at some time if I keep the demo running continuously, it will reach it's MAX value and the axisX->setMax call will fail making the plot not work anymore. What would be the correct way to fix this use case?
qreal x = plotArea().width() / X_RANGE_MAX;
chart->scroll(x, 0)
if (graphSeries1->count() > X_RANGE_COUNT) {
graphSeries1->remove(0);
graphSeries2->remove(0);
graphSeries3->remove(0);
}
However it's not clear to me how can I use the graphSeriesX->remove(0) call in this scenario. The graph will keep getting wiped out since once the series get appended with X_RANGE_COUNT values, the if block will always be true removing 0th value but the scroll somehow does not work the way manually setting maximum for x axis works and after a while I have no graph. scroll works if I do not call remove but then my CPU usage reaches 100%.
Can someone point me in the right direction on how to use scroll while using remove to keep the CPU usage low?
It seems like the best way to update data for a QChart is through void QXYSeries::replace(QVector<QPointF> points). From the documentation, it's much faster than clearing all the data (and don't forget to use a vector instead of a list). The audio example from the documentation does exactly that. Updating the axes with setMin, setMax and setRange all seem to use a lot of CPU. I'll try to see if there's a way around that.
What do you mean by "does not work the way manually setting maximum for x axis works"? The Second method you have shown works if you define x-axis range to be between 0 and X_RANGE_MAX. Is this not what you are after?
Something like: chart->axisX()->setRange(0, X_RANGE_MAX);

How to add points in order along a stream reach in ArcGIS?

I have a stream network in ArcGIS - i.e. a series of polylines, and along each stream part I have added points. For each of the points I have extracted the height and flow from underlying rasters and I have also extracted data from the intersecting polylines including minimum, mean and max height of the polyline, the HydroID and the nextdownID. The points also have their own ID but I have noticed these are not in order.
What I would like is to add stepID to each of the points, where at the beginning of each river reach (each polyline) the first point is step 1 and this increments upwards until the end of the reach. So if there were 10 points along a polyline, the first point would have a stepID value of 1 and the last point would have a stepID value of 10.
This sounds quite easy but not sure how to do it. Any help would be great.
You can construct points along the line at specific intervals using the construct points tool/function.
Click the Edit tool Edit Tool on the Editor toolbar.
Click the line feature along which you want to generate points.
Click the Editor menu and click Construct Points.
http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//001t00000029000000.htm
To automate the numbering, you might look into flipping the lines so all the tails point in one direction - up or downstream. Double click on a line, then right click to see the "flip" command. If you use the points set up from the method above, it might order from tail to head.
Another option is to create your own field for the stepID. Create a attribute join to the stream segment, and give each joined record a unique number. Go through your records selecting each group of ten, then sort by FID (check these are in order) then calculate value for stepID = FID - x
where x = the lowest FID in the stream segment's stepID. This thought might help you figure out how to coax the numbers out correctly.
I had this problem before and solved it this way. It is NOT a pretty solution. Would love to hear if there is a more elegant way of doing this
.
For clarity I'll call the pointdataset you mention the 'inputpoints'.
Step 1: getting the points in the right order
If your inputpoints are sometimes far away from the lines, first project them to your lines.
Give your lines a unique line number and join it to the closest inputpoint features
Generate points along lines: use your polylines and genarate a lot of points on them. I'll call this dataset the helperpoints. Fill in a distance that is smaller then the smallest distance between two of your inputpoints.
Make sure your polylines have the right 'direction'. You can check it by using a symbology with arrows, and if needed correct it with the flip editing tool.
Add an IDfield to your helperpoints, type float or double, and create sequential idnumbers in it (https://support.esri.com/en/technical-article/000011137).
Spatial join: the inputpoints are your target, the helperpoints the join features. Keep all the target features. You only need to join the IDfield from the helperpoints. Right click the IDfield in the field map, and make the merge rule 'Mean'. Set the Match option to 'within a distance', and make the search radius 1.5 x the distance that you used in the generate points along line step.
Use the sort tool and sort your spatial join output on the IDfield you just added, then on the lineID you you added on step one. If you have the advanced licence you can do it at once.
Step 2: Generating the StepID
Add a new field to your sort output, and call it StepID
Use the field calculator to fill it. I used this code to make the numbering restart every time there is a new line.
rec=0
oldid = -1
def autoIncrement(lineid):
global rec
global oldid
pStart = 1
pInterval = 1
if rec == 0 or lineid!= oldid :
rec = pStart
else:
rec += pInterval
oldid = lineid
return int(rec)
Expression: autoIncrement( !lineID! )
Expression type: Python
It might still mess up if you have lines very close to each other, or have weird curls on the end. But for the rest this should work!

Random letters instead of numbers in dynamic text AS 2.0

So I'm trying to program a game using flash, and it's my very first time and I can't get something to work.
In the game, a ball will float across the screen and if you click on it you get 2 points. Except when I test it, the first time I click on the ball I get the letters 'eoceeeo' and if I click the ball again I get the letters 'eeoS'. The dynamic text is on a layer with the first frame having the AS of
var _root.score = 0;
gameScore.text = _root.score;
The dynamic text has a varible of _root.score and a name of gameScore
The floating ball has the AS of
on(release) { _root.score+=2; _root.gameScore.text = _root.score; }
If you click on your gameScore dynamic text field, you can scroll down to its Variable property and set that as _root.score. That way, you do not have to call gameScore.text = _root.score every time the score changes - it will simply update automatically.
Also, if you remove the var from in front of _root.score = 0, it will be easier for ActionScript to handle. Perhaps, you are casting the score variable as an integer, and the dynamic text field is having trouble displaying it as a string of characters. This can also be solved with String(_root.score) and score.toString().
That should make your code a bit less complex, and help for you to identity your random letters problem, which can't be solved specifically with the information you have here. Hope that helps!