LO Calc Basic - What is the right property name for the axis major/minor settings and how to set them correctly? - charts

Using a libreoffice basic macro for charts, we can control the maximum value of an axis and turn the automatic mode on/off:
oAxis.AutoMax = False
oAxis.Max = 12345
But what are the right property names for
Major Interval
Major Auto
Major Time
which you can set manually
???

First, I created a chart with Insert Chart > Line > Points and Lines.
Modifying the Y axis with code was fairly straightforward.
For both axes, I went into formatting and specified Positioning > Interval Marks > Minor > Outer so that the minor ticks are shown.
oCharts = ThisComponent.getSheets().getByIndex(0).getCharts()
oEmbeddedObject = oCharts.getByIndex(0).getEmbeddedObject()
oDiagram = oEmbeddedObject.getDiagram()
oYAxis = oDiagram.getYAxis()
oYAxis.StepMain = 40.0
oYAxis.StepHelpCount = 3
Here is what the Y Axis properties looked like after running the code:
AutoStepMain (and the corresponding Major interval checkbox) started out as True, but setting the StepMain value via macro changed it to False.
With the X axis, things were more complex. For the scale, there was a choice of Type, and selecting Date seemed to be the only way to control step settings.
After that, instead of StepMain (which didn't seem to be relevant in this case), there is a complex structure called ExplicitTimeIncrement that specifies the type of increment (Days or Months) along with each value. I didn't dig too far into it, but it looks like it has all of the values you were asking about.
EDIT:
I tried the following code, but none of the values were changed, and the last line throws an error stating that the property is read-only (as also shown by MRI). So perhaps the values cannot be modified via the API.
sTimeIntervalMajor = CreateUnoStruct("com.sun.star.chart.TimeInterval")
sTimeIntervalMajor.Number = 4
sTimeIntervalMajor.TimeUnit = 0
sTimeIntervalMinor = CreateUnoStruct("com.sun.star.chart.TimeInterval")
sTimeIntervalMinor.Number = 1
sTimeIntervalMinor.TimeUnit = 0
sTimeIncrement = CreateUnoStruct("com.sun.star.chart.TimeIncrement")
sTimeIncrement.MajorTimeInterval = sTimeIntervalMajor
sTimeIncrement.MinorTimeInterval = sTimeIntervalMinor
sTimeIncrement.TimeResolution = 1
oXAxis = oDiagram.getXAxis()
oXAxis.ExplicitTimeIncrement.MajorTimeInterval = sTimeIntervalMajor
oXAxis.setPropertyValue("ExplicitTimeIncrement", sTimeIncrement)
oXAxis.ExplicitTimeIncrement = sTimeIncrement
It might also be worth posting at ask.libreoffice.org or forum.openoffice.org to see if anyone there can find a way to modify the values, with a link to this question.
Of course, the UNO API isn't the only possibility. You could write a script to unzip the .ods file and modify the XML code with a parsing library such as xml.etree or regular expressions.

Related

FMU 2.0 interaction - requires parallel "container" for parameter values etc?

I work with pyfmi in Jupyter notebooks to run simulations and I like to work interactively and evaluate incremental changes in parameters etc. Long time ago I found it necessary to introduce a dictionary that work as a "container" for parameter and initial values. Now I wonder if here is a way to get rid of this "container" that after all is partly a parallel structure to "model"?
A typical workflow look like this:
create a diagram where results from different simulations below should be shown
model = load_fmu(fmu_model)
parDict['model.x_0'] = 1
parDict['model.a'] = 2
for key in parDict.keys(): model.set(key,parDict[key])
sim_res = model.simulate(10)
plot results...
model = load_fmu(fmu_model)
parDict['model.x_0'] = 3
for key in parDict.keys(): model.set(key,parDict[key])
sim_res = model.simulate(10)
plot results...
There is a function model.reset() that brings the state back to default values at compilation without loading again, but you need to do more than the following
model.reset()
parDict['model.x_0'] = 3
for key in parDict.keys(): model.set(key,parDict[key])
sim_res = model.simulate(10)
plot results...
So,  this does NOT work...
and after all parameters and initial values needs to be brought back and we still need parDict, but we may avoid the load-command though.

matlab: check which lines of a path are used - graphshortestpath

The related problem comes from the power Grid in Germany. I have a network of substations, which are connected according to the Lines. The shortest way from point A to B was calculated using the graphshortestpath function. The result is a path with the used substation ID's. I am interested in the Line ID's though, so I have written a sequential code to figure out the used Line_ID's for each path.
This algorithm uses two for loops. The first for-loop to access the path from a cell array, the second for-loop looks at each connection and searches the Line_ID from the array.
Question: Is there a better way of coding this? I am looking for the Line_ID's, graphshortestpath only returns the node ID's.
Here is the main code:
for i = i_entries
path_i = LKzuLK_path{i_entries};
if length(path_i) > 3 %If length <=3 no lines are used.
id_vb = 2:length(path_i) - 2;
for id = id_vb
node_start = path_i(id);
node_end = path_i(id+1);
idx_line = find_line_idx(newlinks_vertices, node_start, ...
node_end);
Zuordnung_LKzuLK_pathLines(ind2sub(size_path,i),idx_line) = true;
end
end
end
Note: The first and last enrty of path_i are area ID's, so they are not looked upon for the search for the Line_ID's
function idx_line = find_line_idx(newlinks_vertices, v_id_1, v_id_2)
% newlinks_vertices includes the Line_ID, and then the two connecting substations
% Mirror v_id's in newlinks_vertices:
check_links = [newlinks_vertices; newlinks_vertices(:,1), newlinks_vertices(:,3), newlinks_vertices(:,2)];
tmp_dist1 = find(check_links(:,2) == v_id_1);
tmp_dist2 = find(check_links(tmp_dist1,3) == v_id_2,1);
tmp_dist3 = tmp_dist1(tmp_dist2);
idx_line = check_links(tmp_dist3,1);
end
Note: I have already tried to shorten the first find-search routine, by indexing the links list. This step will return a short list with only relevant entries of the links looked upon. That way the algorithm is reduced of the first and most time consuming find function. The result wasn't much better, the calculation time was still at approximately 7 hours for 401*401 connections, so too long to implement.
I would look into Dijkstra's algorithm to get a faster implementation. This is what Matlab's graphshortestpath uses by default. The linked wiki page probably explains it better than I ever could and even lays it out in pseudocode!

How to add a dynamic marker to a BIRT chart

I have created a BIRT report with a chart which gets data from a oracle database.
I got the chart done properly. Now i need to add 4-5 markers to the chart.
Values for markers which could be changed are also stored in a database.
I tried the scripts mentioned in this article with some modifications http://blogs.actuate.com/birt-chart-scripting-dynamic-markers/
function beforeGeneration(chart, icsc)
{
importPackage(Packages.org.eclipse.birt.chart.model.component.impl);
importPackage(Packages.org.eclipse.birt.chart.model.data.impl);
importPackage(Packages.org.eclipse.birt.chart.model.attribute);
importPackage(Packages.org.eclipse.birt.chart.model.attribute.impl);
var chart = icsc.getChartInstance();
var yAxis = chart.getBaseAxes()[0];
var min_value = icsc.getExternalContext().getScriptable().getPersistentGlobalVariable("min_val");
var ok_value = icsc.getExternalContext().getScriptable().getPersistentGlobalVariable("ok_val");
var great_value = icsc.getExternalContext().getScriptable().getPersistentGlobalVariable("great_val");
min_ml = MarkerLineImpl.create(yAxis, NumberDataElementImpl.create(min_value));
min_ml.getLabel().getCaption().setValue("Minimum");
min_ml.getLineAttributes().getColor().set(255,0,0);
}
It generates a marker but at the wrong location.
Seems like it doesn't properly get marked according to the x axis values.
What could be the issue in this script?
I have found the issue with the script.
I tried giving a hard coded value to the min_value then it worked. After debugging i found out that the data format of the X axis was with decimals which didn't match with the integer format value taken from the database.
From the format chart window i changed the axis data format to a number with 0 decimals.Then it worked :)

Set a certain bit to a 1 matlab

I want to set a certain bit of my configuration header to a 1 (bit 3 of Byte 10) if its not already a 1. And then I want to save this new config header as my old one. I can set the bit ok, however I'm having difficulty replacing the old byte with my new to update my configuration header. I want my new configuration header to be ConfigHeader = [128;0;0;0;0;0;0;0;0;0;30];. I know it's probably a very simple solution!!
ConfigHeader = [128;0;0;0;0;0;0;0;0;0;26];
ByteTen = ConfigHeader(11);
if bitget(ByteTen,3) == 0
% Set bit 3 of byte 10 to 1
bitset(ByteTen,3);
% Replace old config header with new one (bit changed to 1)
ConfigHeader = ??????
end
You'll have to assign the modified value back to ConfigHeader, e.g. by adding this line:
ConfigHeader(11) = bitset(ByteTen,3);
This line:
bitset(ByteTen,3);
on it's own does nothing as long as you don't use its output.
I am not used to bit operations, but juding from your code the next logical step would be:
ConfigHeader(11) = ByteTen
Perhaps your entire code can even be reduced to:
bitset(ConfigHeader(11),3)
After all, a bit can only be zero or one so you don't need to test it if you always want to end with a one.

Debugging a for loop in matlab

I've been looking throught the documentation, but can't seem to find the bit I want.
I have a for loop and I would like to be able to view every value in the for loop.
for example here is a part of my code:
for d = 1 : nb
%for loop performs blade by blade averaging and produces a column vector
for cc = navg : length(atbmat);
atb2 = (sum(atbmat((cc-(navg-1):cc),d)))/navg;
atbvec2(:,cc) = atb2;
end
%assigns column vector 'atbvec2' to the correct column of the matrix 'atbmat2'
atbmat2(d,1:length(atbvec2)) = atbvec2;
end
I would like to view every value of atb2. I'm a python user(new to MATLAB) and would normally use a simple print statement to find this.
I'm sure there is a way to do it, but I can't quite find how.
Thankyou in advance.
you can use disp in Matlab to print to the screen but you might want to use sprintf first to format it nicely. However for debugging you're better off using a break point and then inspect the variable in the workspace browser graphically. To me, this is one of Matlab's best features.
Have a look at the "Examine Values" section of this article
The simplest way to view it everywhere is to change this line:
atb2 = (sum(atbmat((cc-(navg-1):cc),d)))/navg;
Into this, without semicolon:
atb2 = (sum(atbmat((cc-(navg-1):cc),d)))/navg
That being said, given the nature of your calculation, you could get the information you need as well by simply storing every value of abt2 and observing them afterwards. This may be done in atbmat2 already?
If you want to look at each value at the time it happens, consider setting a breakpoint or conditional breakpoint after the line where abt2 is assigned.