I want to extract the planned work over the time from MS Project using MPXJ.
Does anyone know how to get these figures via API?
I cannot find any appropriate method for doing this.
(Concrete scenario: I want to draw a chart with the planned work on the y-axis and the date on the x-axis)
The answer Jon gave above was correct at the time, but as of version 4.2 of MPXJ, the api for dealing with timephased work (and cost) has been changed considerably. Here's what you would do now:
This part's the same:
TimescaleUtility timescale = new TimescaleUtility();
ArrayList<DateRange> dateList = timescale.createTimescale(startDate, TimescaleUnits.DAYS, length);
This has changed (notice the different return type and method for getting the planned work, and the new method on the TimephasedUtility class):
List<TimephasedWork> plannedWork = assignment.getTimephasedWork();
ProjectCalendar calendar = assignment.getCalendar();
TimephasedUtility util = new TimephasedUtility();
ArrayList<Duration> durationList = util.segmentWork(calendar, plannedWork, TimescaleUnits.DAYS, dateList);
One thing you also have to know is that the planned work data only contains values for work that has not been completed yet (ie, no actual values have been recorded for that time). For example, if your assignment lasts for 4 days, and you've completed 50% of the work, then you will have timephased ACTUAL work values for the first two days, and timephased PLANNED work values only for the last two days. They do not overlap or duplicate.
So if you are trying to show planned work values for the whole time period of the assignment (like what you'd see in the Task Usage views in MS Project), you'd need to also retrieve the timephased actual work values and use them as if they were planned work too.
your starting point is the following methods on the assignment object:
List<TimephasedResourceAssignment> complete = assignment.getTimephasedComplete();
List<TimephasedResourceAssignment> planned= assignment.getTimephasedComplete();
As their names suggest, these will get you either the planned work or the complete work, expressed as work carried out over periods of time.
The "gotcha" here is that this data is represented in a compact format (reflecting how it's stored by MS Project internally), and this does not lend itself well to showing a period-by-period breakdown of work.
To get what you want, there are two utility classes which will help you to convert this compact representation into a list of work values. For example, you can give them a start date a period type (day, week, month and so on) and a number of periods, and ask for the work to be broken down over these periods.
First step is to create an instance of the TimescaleUtility class, and get it to generate a range of dates for you. You give it the start date, the timescale units you require, and the numnber of periods you want.
TimescaleUtility timescale = new TimescaleUtility();
ArrayList<DateRange> dateList = timescale.createTimescale(startDate, TimescaleUnits.DAYS, length);
The dateList variable now contains the list of date ranges you are going to split the work over. This split is carried out using the TimephasedUtility class:
ProjectCalendar calendar = assignment.getCalendar();
TimephasedUtility timephased = new TimephasedUtility();
ArrayList<Duration> durationList = timephased.segmentResourceAssignment(calendar, planned, TimescaleUnits.DAYS, dateList);
That's it, your durationList now contains one entry for each entry in the datList showing the amount of work for that period.
Hope that makes sense!
Jon
Related
I am new to Pentaho, so please be gentle.
I am, perhaps naively, wanting to use a Formula to convert a six-character string in the form YYYYMM to the date representing the final day of that month.
I imagine doing this step by step using successive lines of the Formula: checking that the string is of the correct length and, if so:
extracting the year and converting it to integer (with error checking)
extracting the month and converting it to integer (also with error checking)
converting ([year], [month], 1) to a date (the first of the month)
adding a month
subtracting a day
Some of those steps may be combined but, overall, it relies on a succession of steps to achieve a final result.
Formula does not seem to recognise the values achieved along the way though, at least not by enclosing them in square brackets as you do with fields from previous objects in the mapping.
I suppose I could have a series of Formula objects one after the other in the mapping but that seems untidy and inefficient. If a single Formula object cannot have a series of values defined on successive lines, what is the point of even having lines? How do I use a value I have defined on a previous line?
The formula step isn’t the best way to achieve that. The resulting formula will be hard to read and quite cumbersome.
It’s better (and faster) to use a calculator step. A javascript step can also be used, and it will be easier to read, but slower (though that probably won't be a major issue).
So, one way forward is to implement this on a calculator step:
Create a copy of your string field as a Date
Create 2 constant fields: 1 and -1
Add 1 month to the date field
Subtract 1 day to the result
Create a copy of the result as a string.
See screenshot:
I currently have a dataframe which includes a running timeline of POSIXct (see below).
Basically given a starting time of my choosing I want to be able to take rows at specific time interval. E.g. Say I start taking rows at four pm I then want to take 9 minutes, then not take anything for the next two, then nine again. I'm guessing the best approach is possibly using indexing but I also thought something like the lubridae package could be used but not sure how to exactly do it.
Thanks!
I have some COT data that I want to plot under the main price window as an indicator. The COT data are external data, i.e. independent of the prices. So one can not write it like a traditional indicator calculated from the prices. Since I have all the data needed, I don't need to do any calculation. I only need to convert the date and time so that it aligns with the price chart. I will figure out how to do it later. Now, if we ignore the alignment, what I want to ask is how could I plot the data under the price chart? Thanks!
Alternative A:
Use the MT4-GUI tools and plot the data programmatically right into the MT4.Graph or using the screen-layout-plane of GUI-objects, independent of the underlying live-[TimeDOMAIN,PriceDOMAIN]-graphing, both using Expert Advisor-type of MQL4-code. We use this approach most often for all the tasks, that would normally land as a Custom Indicator-type of MQL4-code, as the New-MQL4.56789 code-execution engine has reduced the achievable performance for all ( yes, ALL ) Custom Indicator code-units' execution into a single, thus both RealTime-sensitive and potentially blocking, thread.
Using this alternative, you retain the full freedom of the code-design and may benefit a lot from pre-computing & pre-setting the GUI-objects inside OnInit(){...} section, before entering the trading-loop. This also minimises the latency costs associated with a need to update the GUI-scene from inside an OnTick(){...} event-loop.
Alternative B:
One may also opt to do a similar job using an independent Script-type of MQL4-code unit, as the COT data are weekly announced and thus static per-se.
Launching Script is a step, that can happen whenever feasible and this implementation model may also enjoy some ex-post modification tools, that could be run from another Expert Advisor or another Script MQL4-code, for the sake for some ex-post live-GUI-scene modification/maintenance.
Alternative C:
If one indeed insists to do so, the GUI-composition might be assembled inside a rather special-purpose live-calculated Custom Indicator-type of MQL4-code.
This approach but has to carefully deploy the GUI-composition into the Custom Indicator OnInit(){...} section and avoid any risk of blocking a flow of execution inside the above said critical section of OnCalculate(){...}.
Buffer-mapped, register-based Custom Indicator data & graphing tools are rather rigid for more advanced purposes, that do not strictly follow the hard-wired logic of a code, responding just to a stream of MarketEvent-s, which may, but need not, happen at once, but is being arranged by a sort of mini-batches, so as to process the whole depth of the DataStore in a segmented ( thus less-blocking ) processing approach.
Building the GUI-scene inside the OnInit() section of the Custom Indicator, one may still benefit from distributed processing, if external data source is to be read and/or any similar type inter-platform communications ( be it for a messaging or a signalling purpose ).
My choice would be the [A]
Mapping { Date, Time } onto a MQL4-datetime is trivial, MQL4 used to use since its beginning datetime as int seconds elapsed since 1970-01-01,00:00:00.000 - so simple, so easy.
declare the indicator buffer:
double ExtBufferCOT[];
assign indexes of buffers
SetIndexStyle( 0, DRAW_LINE );
SetIndexBuffer( 0, ExtBufferCOT );
in the OnCalculate() function - make sure it is time to check the levels again ( I think you do not need to update them every tick, right? Maybe once a day or once a week) and then read the file that you have ( we do not have example of file so senseless to describe how to do that here ), convert elements of the file, using StrToTime() and StrToDouble()
the last step - get last N lines from your file, and map them to the indicator buffers:
double value;
datetime time; // - your values from file are here
int shift = iBarShift( _Symbol, 0, time );
ExtBufferCOT[shift] = value; /* probably need to fill buffer
of next candles too
if your chart timeframe
is smaller then frequency
of observations in the file
*/
I have time series data that I'm trying to analyse in R. It was provided as a CSV from excel, which I subsequently read as a data.frame all. Let's say it has two columns: all$date and all$people, representing the count of people on a particular date. The frequency is hence daily.
Being from Excel, the dates are integers representing the number of days since 1900-01-01.
I could read the data as people = ts(all$people, start=c(all$date[1], 1), frequency=365); but that gives a silly start value of almost 40000 because the data starts in 2006. The start parameter doesn't take a date object, according to ?ts, so I can't just use as.Date():
ts - ...
start: the time of the first observation. Either a single number
or a vector of two integers, which specify a natural time unit and
a (1-based) number of samples into the time unit. See the examples
for the use of the second form.
I could of course set start=1, but it's a bit painful to figure out what season we're in when the plot tells me interesting things are happening around day 2100. (To be clear, setting frequency=365 does tell me what year we're in, but isn't useful more precise dates). Is there a useful way of expressing the date in ts in a human-readable form so that I don't have to keep calling as.Date() to understand when the interesting features are happening?
I have an xts time series in R and am using the very handy function to subset the time series based on a string, for example
time_series["17/06/2006 12:00:00"]
This will return the nearest observation to that date/time - which is very handy in many situations. However, in this particular situation I only want to return the elements of the time series which are at that exact time. Is there a way to do this in xts using a nice date/time string like this?
In a more general case (I don't have this problem immediately now, but suspect I may run into it soon) - is it possible to extract the closest observation within a certain period of time? For example, the closest observation to the given date/time, assuming it is within 10 minutes of the given date/time - otherwise just discard that observation.
I suspect this more general case may require me writing a function to do this - which I am happy to do - I just wanted to check whether the more specific case (or the general case) was already catered for in xts.
AFAIK, the only way to do this is to use a subset that begins at the time you're interested in, then get the first observation of that.
e.g.
first(time_series["2006-06-17 12:00:00/2006-06-17 12:01"])
or, more generally, to get the 12:00 price every day, you can subset down to 1 minute of each day, then split by days and extract the first observation of each.
do.call(rbind, lapply(split(time_series["T12:00:00/T12:01"],'days'), first))
Here's a thread where Jeff (the xts author) contemplates adding the functionality you want
http://r.789695.n4.nabble.com/Find-first-trade-of-day-in-xts-object-td3598441.html#a3599887