DLL Library for making Charts with Visual Prolog
Kari Rastas |
Contents
2 Installing and connecting with Visual Prolog projects
2.2 Connecting to a VIP project
2.3 Structure of predicates in different class interfaces
2.5 Using gradient colouring in the charts
3.1.1.3 Stacked percentage horizontal
3.4.1 Basic representation styles
3.4.2 Charts based on company key figures
3.4.3 Charts based on index or stock information
3.4.3.2 Open, high, low, close chart
3.4.3.3 Daily changes in the index of stock price
3.4.4 Charts with second based data
3.6 Boston Consulting Group matrix chart
4.2 Creating stock and index charts 1
4.3 Creating stock and index charts 2
4.5 Discounted cash flow calculator
4.6 Stock picture with a time zoom
In program development more time is needed / spent building the user interface and outputs of the program than to the essential core “problem’s” coding. By using readymade “building blocks” total development time can substantially be reduced. The purpose of this dll library is to minimize the time required to produce professional quality graphical presentations of numeric data.
Considerable effort has been made to make this graphics library user friendly[1]. PictureDLL generates graphs with relative few instructions and provides the flexibility for modification. Chapters 3 and 4 provide example code with the resulting charts generated.
This manual assumes the reader has reasonably good knowledge of programming with Prolog Development Center’s Visual Prolog version 7.
Designing charts is not always an easy task. Some good advice can be found in the following document link http://www.stat.auckland.ac.nz/~ihaka/120/Lectures/lecture03.pdf .
The class and interface files must be copied to a user defined directory (for example in “C:\PrologTools\Pictures”).
The PictureDLL.dll file must be copied to either the exe directory of your own projects or included in the computer’s path directories.
The help file of the documentation of the classes is in the file pictureDLL.hlp file. It can also be found in internet.
When a chart of the PictureDLL is needed for the first time in a Visual Prolog project, the package of the desired chart type is added in the normal way. Also the LIB file (pictureDLL.lib) must be added to the project, when the first chart package is added.
The way charts of the dll library are used depends in the end of the application’s properties where it is used. The pictureDLL.dll draws the produced picture in a picture “window” which can be then drawn to the chosen window, saved in a file or external database, clipboard etc.
There is a test project which describes some ways of integrating pictureDll with dialogs and windows.
The predicates in each charts interface can be divided in two subgroups
· predicates that are common[2] to most or all different chart styles
· special predicates that are used only in one or two the chart types.
The amount of special predicates is tried to keep as limited as possible.
The documentation for other classes can be found in the help file pictureDLL.hlp or in internet http://koti.welho.com/krastas/picturedll/index-hhc.htm This document can be found in the address http://koti.welho.com/krastas/picturedll.htm or http://koti.welho.com/krastas/prologPicturedll.pdf .
The order of different chart drawing predicates in the user’s own code is not very relevant, expect:
· drawPicture (when using drawing to a working picture) or drawToWindow (when drawing directly to window) must be the last command
· Order of inputting data to the chart object is in many chart types relevant. The values are drawn in the order they were given. With the timeserie and xy charts this has to be kept in mind. If for example the dataset number 3 is presented in an “area” style and datasets 1 and 2 are normal lines, there is a high possibility that the lines of 1 and 2 are overdrawn by number 3. In this case the dataset number 3 should be number one and the line datasets number 2 and 3.
The whole drawing area means the area reserved for the whole output, meaning the chart tiles, legends etc. The actual chart area means the area where the chart figure is drawn.
The proportions of the whole area is controlled by the object constructors[3] newPicture:(,positive Width, positive Height) when a working picture created. The size of a working picture is changed with the predicate changePictureSize:(positive Width, positive Height).
The dimensions of the actual chart area is controlled with the predicate setInnerGraphAreaDimensions:(integer UpperLeftX, integer UpperLeftY, integer DownRightX, integer DownRightX).
There is a possibility to use gradient colouring in the different parts of the picture (the whole area, the actual chart area and bars). The possibilities are:
constants
no_gradient : gradientDirection = 0.
gradient_left_right : gradientDirection = 1.
gradient_top_bottom : gradientDirection = 2.
gradient_tube_left_right : gradientDirection = 3.
gradient_tube_top_bottom : gradientDirection = 4.
Gradients direction constants.
Choosing colors for the gradient output must be done with some care. Not all color combinations produce a good visual result.
The result of a drawn chart can be saved in file using the predicate
pictureTools::savePictureToFile : (picture, string FileName).
There are many different chart styles used to illustrate numeric information. The main styles are bar, column, line, scatter and pie chart. There are also dozens of other more or less used special types and combinations of the main styles.
Bar charts are a very common type of graph best suited for a qualitative independent variable.
Bar graphs can be oriented either horizontally or vertically. Vertical bar graphs are also called as column charts.
Bars can be also divided in the following sub types:
· Normal (or often called as simple or side-by-side bar chart ) where the bars of the different observations are beside each other
· Stacked[4] (or composite)
· Stacked percentage.
· Build-Up (possible only in vertical orientation)
· Histogram.
Histograms are similar to normal bar charts except that each bar represents a range of independent variable values rather than just a single value.
In a normal horizontal bar chart the different value bars of the dataset are located besides each other.
O = bar::newPicture(500,500),
O:setBarChartType(bar::horizotal,bar::normal), O:setBackgroundColor(picCore::gradient_top_bottom,color_ivory,color_DodgerBlue),
O:setChartBackgroundColor(picCore::gradient_left_right,color_gray,color_white),
O:setInnerGraphAreaDimensions(20,19,95,80), O:setBarColor(1,color_olive),
O:setBarColor(2,color_silver),
O:setBarColor(3,color_gold),
O:inputBarData(bar::bData("Company A","Car sales",34)),
O:inputBarData(bar::bData("Company A","Repairs",25)),
O:inputBarData(bar::bData("Company A","Spare parts",24)),
O:inputBarData(bar::bData("Company B","Car sales",14)),
O:inputBarData(bar::bData("Company B","Repairs",35)),
O:inputBarData(bar::bData("Company B","Spare parts",44)),
O:inputBarData(bar::bData("Company C","Car sales",42)),
O:inputBarData(bar::bData("Company C","Repairs",5)),
O:inputBarData(bar::bData("Company C","Spare parts",34)),
O:setDataUnit("m. "),
O:setvalueAxisTitle("million Euro"),
O:setChartTitle("Sales of Car Companies in 2010",12,color_blue),
O:setSourceText("Peter Seller: Market study 2011",8,color_yellow),
O:drawPicture(),
PICT = O:getPicture(),
The labels can be hidden by adding to the code predicate showDataLabels(false). The default value is to show data labels (true).
If we use the definitions of the previous and would add setBarChartType command with the definition bar::stacked, the result would be the following.
O:setBarChartType(bar::horizontal,bar::stacked),
If the bar style is stackedPercentage also the header of the value axis must be changed manually. This must be done, because the scale of the value axis is in percents.
O:setBarChartType(bar::horizontal,bar::stackedpercentage),
To produce vertical bar charts is exactly equal to making horizontal bar charts. The main difference is in the setBarChartType command where bar orientation is changed to bar::vertical.
With vertical bar charts it is also possible to draw the value axis numbers to the right side. This is done by adding to the code the command
O:drawValueAxisNumbersOnRightSide(true),
The result would be:
BuildUp chart demonstrates the growth or decline of an item between different measurement points.
O = bar::newPicture(700,400),
O:setTextAndLineColor(color_black),
O:setBackgroundColor(picCore::gradient_top_bottom,color_white,color_seagreen),
O:setBarChartType(bar::vertical,bar::buildUp),
O:setChartBackgroundColor(1,color_steelBlue,color_white),
O:setInnerGraphAreaDimensions(10,19,95,80),
O:setBarSpace(5),
O:setBarColor(1,picCore::gradient_top_bottom,color_red,color_Chocolate),
O:inputBarData(bar::bData("2004","FUND 1",34)),
O:inputBarData(bar::bData("2005","FUND 1",44)),
O:inputBarData(bar::bData("2006","FUND 1",54)),
O:inputBarData(bar::bData("2007","FUND 1",45)),
O:inputBarData(bar::bData("2008","FUND 1",49)),
O:inputBarData(bar::bData("2009","FUND 1",60)),
O:inputBarData(bar::bData("2004","FUND 2",14)),
O:inputBarData(bar::bData("2005","FUND 2",24)),
O:inputBarData(bar::bData("2006","FUND 2",34)),
O:inputBarData(bar::bData("2007","FUND 2",24)),
O:inputBarData(bar::bData("2008","FUND 2",36)),
O:inputBarData(bar::bData("2009","FUND 2",40)),
O:setDataUnit("m. "),
O:setvalueAxisTitle("million "),
O:setChartTitle("Development of Funds",14,color_red),
O:setSourceText("Peter Seller: Bankstudy 2010",10,color_yellow),
O:drawPicture(),
PICT = O:getPicture(),
vpi::cbPutPicture(PICT),
Histograms are similar to normal bar charts except, that each bar represents a range of independent variable values rather than just a single value. The amount of values belonging to certain range of values can be calculated by the pictureDLL. Then the values are transferred with the predicate
inputBarData:(bData) , where bData is hData : (real).
The amount of values belonging to each range are calculated with the predicate
setHistogramClassRange:(integer OrderNumber, string Name, real LowerLimit, real UpperLimit) .
The other obvious strategy would naturally be that the histogram data is given like in the other bar graphs.
(See also example of a histogram dialog in Chapter 4).
INDEX = "NOK",
Width = 600, Height = 300,
HDB1 = dbBrowser::transferFromAccessDB("STOCKDBA",INDEX,dateTools:: makeDateNumber(1996,1,1)),
retractFactDB(timeserie),
localdatabases::readFactsFromString(timeserie,HDB1),
WINOBJ = pictWin::new(WIN),
O = bar::newPicture(Width,Height),
Dates = [Date||ind(stat(INDEX,"D",Date,_,_,_,_,_,_))],
Time = time::new(),
Time:getGmtDateAndTime(Year, Month, Day, _, _, _),
percentChangeOfStock(O,INDEX,Dates),
O:setChartTitle(string::format("Nokia ADR Daily Change Percent in Stock Rate between 1.1.1996-%.%.%",Day,Month,Year),
9,color_ivory),
O:setBackgroundColor(picCore::gradient_tube_top_bottom,color_steelBlue,color_ivory),
O:setBarChartType(bar::vertical,bar::histogram),
O:setChartBackgroundColor(picCore::gradient_left_right,color_red,color_green),
O:setBarColor(1,picCore::gradient_tube_left_right,color_black,color_SeaShell),
O:setHistogramClassRange(1,"Great drop > -15%",-999999,-10),
O:setHistogramClassRange(2,"-10% - -5%",-10,-5),
O:setHistogramClassRange(3,"-5% - -3%",-5,-3),
O:setHistogramClassRange(4,"-3% - -2%",-3,-2),
O:setHistogramClassRange(5,"-2% - -1%",-2,-1),
O:setHistogramClassRange(6,"-1% - 0%",-1,0),
O:setHistogramClassRange(7,"0% - +1%",0,1),
O:setHistogramClassRange(8,"+1% - +2%",1,2),
O:setHistogramClassRange(9,"+2% - +3%",2,3),
O:setHistogramClassRange(10,"+3% - +5%",3,5),
O:setHistogramClassRange(11,"+5% - +10%",5,10),
O:setHistogramClassRange(12,"Great rise < +15%",10,999999),
O:setvalueAxisTitle("AMOUNT"),
O:setInnerGraphAreaDimensions(10,19,90,80),
O:setBarSpace(1),
O:drawPicture(),
PICT2 = O:getPicture(),
vpi::cbPutPicture(PICT2),
WINOBJ:setPicture(PICT2,rct(10,10,Width+10,Height+10)),
A pie chart is a way of summarizing a set of categorical data or displaying the different values of a given variable (e.g., percentage distribution). This type of chart is a circle divided into a series of segments. Each segment represents a particular category. The area of each segment is the same proportion of a circle as the category is of the total data set.
WINOBJ = pictWin::new(Win),
O = pie::newPicture(500,500),
O:setBackgroundColor(2,color_silver,color_black),
O:setInnerGraphAreaDimensions(25,30,75,65),
O:setChartTitle("Marketshares 2010",20,color_gold),
O:inputPieData(pie::pData("Nokia",33)),
O:inputPieData(pie::pData("Sony Ericsson",20)),
O:inputPieData(pie::pData("Motorola",20)),
O:inputPieData(pie::pData("Samsung",20)),
O:inputPieData(pie::pData("Thosiba",20)),
O:inputPieData(pie::pData("IBM",20)),
O:inputPieData(pie::pData("Siemens",20)),
O:inputPieData(pie::pData("Lukoil",20)),
O:inputPieData(pie::pData("BP",20)),
O:inputPieData(pie::pData("Microsoft",20)),
O:inputPieData(pie::pData("Rio Tinto",33)),
O:setDisplacementRatio(0.3),
O:setDataUnit("m. "),
O:drawPicture(),
PICT = O:getPicture(),
vpi::cbPutPicture(PICT),
WINOBJ:setPicture(PICT,rct(10,10,510,510)),
The pie chart has also a 3D effect. It is activated if the rectangle reserved for the essential graph is not a square. So when O:setInnerGraphAreaDimensions(25,30,75,65) produces a “normal” pie (X2-X1 = Y2-Y1), O:setInnerGraphAreaDimensions(25,40,75,55) would add a 3D effect (X2 – X1 <> Y2-Y1).
With a couple predicates certain or all slices can be displaced with a wanted displacement ratio.
O:setDisplacementRatio(0.3),
|
O:setDisplacementRatio(0.3), |
The displacement can be cancelled with the predicate removeSliceDisplacementForSlice(<name of observation>).
The labels can be hidden with predicate showDataLabels:(false()). The default value is to show data labels (=true()).
Line charts provide a way to map independent and dependent variables that are both quantitative. When both variables are quantitative, the line segment that connects two points on the graph expresses a slope, which can be interpreted visually relative to the slope of other lines or expressed as a precise mathematical formula.
Scatter plots are similar to line charts in that they start with mapping quantitative data points. The difference is that with a scatter plot, the decision is made that the individual points should not be connected directly together with a line but, instead express a trend. This trend can be seen directly through the distribution of points or with the addition of a regression line.
WINOBJ = pictWin::new(thisWin),
O = xyGraph::newPicture(600,600),
O:setBackgroundColor(2,color_yellow,color_black),
O:setGraphBackgroundColor(1,color_BlanchedAlmond,color_white),
O:setInnerGraphAreaDimensions(15,20,95,80),
O:setGraphTitle("Y = sin(X) + cos(X)",20,color_gray),
O:setSourceText("Peter Sellers: Study in University © 2010",12,color_yellow),
O:setValueAxesXTitle("X"),
O:setValueAxesYTitle("Y"),
countFormula(O,-math::pi),
countFormula2(O,-1),
O:setTextBox(70,30,"sin(x) + cos(x)",10,color_black,color_yellow),
O:setTextBox(40,65,"arcSin(x,10,color_black,color_pink),
O:setLegendStartPoint(10,95),
O:drawPicture(),
PICT = O:getPicture(),
vpi::cbPutPicture(PICT),
WINOBJ:setPicture(PICT,rct(10,10,610,610)),
predicates
countFormula:(xyGraph O,real X).
countFormula2:(xyGraph O,real X).
clauses
countFormula(_O,X):-
X >= 2*math::pi,!.
countFormula(O,X):-
O:inputXYData(xyGraph::xyData("XY","sin(X)+cos(X)",X,math::sin(X)+math::cos(X))),
countFormula(O,X+0.05).
countFormula2(_O,X):-
X > 1,!.
countFormula2(O,X):-
O:inputXYData(xyGraph::xyData("XY","arcSin(X)",X,math::arcsin(X))),
countFormula2(O,X+0.05).
Timeserie chart is a special form of a XY-chart, where the X-values are date related order numbers. The data can be yearly, quarterly, daily or second based information.
Normally the chart’s observations are drawn as a line or area. The basic code
O = timeseries::newPicture(600,350),
O:setInnerGraphAreaDimensions(15,20,90,90),
O:setvalueAxisTitle("Percent (%)"),
O:setGraphTitle("Changes in Production ",12,color_blue),
O : inputTimeGraphData(timeseries::tData2("Product 1","31.12.2000",30)),
O : inputTimeGraphData(timeseries::tData2("Product 1","31.6.2001",25)),
O : inputTimeGraphData(timeseries::tData2("Product 1","31.12.2002",22)),
O : inputTimeGraphData(timeseries::tData2("Product 1","30.6.2003",5)),
O : inputTimeGraphData(timeseries::tData2("Product 1","31.12.2004",-10)),
O : inputTimeGraphData(timeseries::tData2("Product 1","31.10.2005",3)),
O : inputTimeGraphData(timeseries::tData2("Product 1","31.12.2006",10)),
O : inputTimeGraphData(timeseries::tData2("Product 2","15.11.2000",5)),
O : inputTimeGraphData(timeseries::tData2("Product 2","31.12.2001",10)),
O : inputTimeGraphData(timeseries::tData2("Product 2","1.10.2002",22)),
O : inputTimeGraphData(timeseries::tData2("Product 2","31.12.2003",15)),
O : inputTimeGraphData(timeseries::tData2("Product 2","1.12.2004",10)),
O : inputTimeGraphData(timeseries::tData2("Product 2","31.12.2005",23)),
O : inputTimeGraphData(timeseries::tData2("Product 2","31.12.2006",15)),
O:drawPicture(),
PICT = O:getPicture(),
would produce a picture below.
With the predicate setSerieAreaColor a line representation will be changed to an area.
O:setSerieAreaColor(1,color_gold),
It is also possible to use a bar representation for wanted time series. It is performed by using the predicate setSerieBar
O:setSerieBar(1,color_gold),
With the predicate setTimeGraphSpace it is possible to add space between the observation bars. The space figure is given in pixels.
It is also possible to mark the observation points with a circle. This is done with the predicate setSeriePoint.
O:setSeriePoint(1,color_yellow,8,false()),
O:setSeriePoint(2,color_white,8,true()),
Own future development estimates can be presented with predicates
· drawTrendEstimate : (string DataSetName, string EndDate, real Value) or
· drawTrendEstimateArea : (string DataSetName, string EndDate, real Value1, real Value2,color)
O:drawTrendEstimate("Product 1", "1.1.2010",-10),
O:drawTrendEstimateArea("Product 2", "1.1.2010",10,20,color_gray),
It is also possible to use the right side of the chart for the number scale. This is done using predicate drawValueAxisNumbersOnRightSide(true) in the code. Default is the left side and then there is no need to use this predicate.
Companies’ key figures level and development are often presented using different charts. A person can faster identify the different levels and development trends from a chart that he/she could from a large numeric table. By adding the company key figure databases to the charts and rule based text generation modules a system which produces very complex verbal company analyses could be programmed relative easily.
http://koti.welho.com/krastas/pap98_e.pdf
http://koti.welho.com/krastas/nokiate.pdf
Normally the key figure data of companies is given in quarter or year level. In internal reports also weekly and monthly levels are used.
Example of yearly based data:
O = timeseries::newPicture(600,350),
O : setInnerGraphAreaDimensions(15,20,90,90),
O : setvalueAxisTitle("Percent (%)"),
O : setGraphTitle("Keyfigure ",12,color_blue),
O : inputTimeGraphData(timeseries::tyData("NOKIA",2007,23)),
O : inputTimeGraphData(timeseries::tyData("NOKIA",2008,24.5)),
O : inputTimeGraphData(timeseries::tyData("NOKIA",2010,23)),
O : inputTimeGraphData(timeseries::tyData("NOKIA",2011,26)),
O : inputTimeGraphData(timeseries::tyData("NOKIA",2012,27)),
O : inputTimeGraphData(timeseries::tyData("NOKIA",2013,27.2)),
O : inputTimeGraphData(timeseries::tyData("NOKIA",2013,26)),
O : drawPicture(),
PICT = O : getPicture(),
To a yearly based key figure picture can easily be added the data of the industry by using the quartile and median information.
O = timeseries::newPicture(600,350),
O : setInnerGraphAreaDimensions(15,20,90,90),
O : setvalueAxisTitle("Percent (%)"),
O : setSerieBar(1,color_blue),
O : setSerieLineColor(3,color_red,3),
O : setGraphTitle("Keyfigure ",12,color_blue),
O : inputTimeGraphData(timeseries::tyData("NOKIA",2008,23)),
O : inputTimeGraphData(timeseries::tyData("NOKIA",2009,24.5)),
O : inputTimeGraphData(timeseries::tyData("NOKIA",2010,18)),
O : inputTimeGraphData(timeseries::tyData("NOKIA",2011,20)),
O : inputTimeGraphData(timeseries::tyData("NOKIA",2012,27)),
O : inputTimeGraphData(timeseries::tyData("NOKIA",2013,27.2)),
O : inputTimeGraphData(timeseries::tyData("NOKIA",2014,26)),
O : inputTimeGraphData(timeseries::tyData("Lower quartile",2008,5)),
O : inputTimeGraphData(timeseries::tyData("Lower quartile",2009,6)),
O : inputTimeGraphData(timeseries::tyData("Lower quartile",2010,8)),
O : inputTimeGraphData(timeseries::tyData("Lower quartile",2011,7)),
O : inputTimeGraphData(timeseries::tyData("Lower quartile",2012,7)),
O : inputTimeGraphData(timeseries::tyData("Lower quartile",2013,9)),
O : inputTimeGraphData(timeseries::tyData("Lower quartile",2014,9.5)),
O : inputTimeGraphData(timeseries::tyData("Median",2008,10)),
O : inputTimeGraphData(timeseries::tyData("Median",2009,12)),
O : inputTimeGraphData(timeseries::tyData("Median",2010,11)),
O : inputTimeGraphData(timeseries::tyData("Median",2011,12)),
O : inputTimeGraphData(timeseries::tyData("Median",2012,9)),
O : inputTimeGraphData(timeseries::tyData("Median",2013,11)),
O : inputTimeGraphData(timeseries::tyData("Median",2014,12)),
O : inputTimeGraphData(timeseries::tyData("Upper quartile",2008,18)),
O : inputTimeGraphData(timeseries::tyData("Upper quartile",2009,19)),
O : inputTimeGraphData(timeseries::tyData("Upper quartile",2010,21)),
O : inputTimeGraphData(timeseries::tyData("Upper quartile",2011,22)),
O : inputTimeGraphData(timeseries::tyData("Upper quartile",2012,19)),
O : inputTimeGraphData(timeseries::tyData("Upper quartile",2013,19)),
O : inputTimeGraphData(timeseries::tyData("Upper quartile",2014,18)),
O : drawPicture(),
PICT = O : getPicture(),
Example of quarter based data:
O = timeseries::newPicture(600,350),
O : setInnerGraphAreaDimensions(15,20,90,90),
O : setTimeGraphType(timeseries::quarter),
O : setSerieBar(1,color_red),
O : setvalueAxisTitle("Percent (%)"),
O : setGraphTitle("Keyfigure ",12,color_blue),
O : inputTimeGraphData(timeseries::tqData("NOKIA","2009Q1",23)),
O : inputTimeGraphData(timeseries::tqData("NOKIA","2009Q2",24.5)),
O : inputTimeGraphData(timeseries::tqData("NOKIA","2009Q3",23)),
O : inputTimeGraphData(timeseries::tqData("NOKIA","2009Q4",26)),
O : inputTimeGraphData(timeseries::tqData("NOKIA","2010Q1",27)),
O : inputTimeGraphData(timeseries::tqData("NOKIA","2010Q2",27.2)),
O : inputTimeGraphData(timeseries::tqData("NOKIA","2010Q3",26)),
O : inputTimeGraphData(timeseries::tqData("Motorola","2009Q1",22)),
O : inputTimeGraphData(timeseries::tqData("Motorola","2009Q2",25.5)),
O : inputTimeGraphData(timeseries::tqData("Motorola","2009Q3",27)),
O : inputTimeGraphData(timeseries::tqData("Motorola","2009Q4",21)),
O : inputTimeGraphData(timeseries::tqData("Motorola","2010Q1",19)),
O : inputTimeGraphData(timeseries::tqData("Motorola","2010Q2",21)),
O : inputTimeGraphData(timeseries::tqData("Motorola","2010Q3",22)),
O : drawPicture(),
PICT = O : getPicture(),
PictureDLL has numerous possibilities to produce stock exchange charts.
The example below is a case where stock information of Nokia’s ADR is fetched from a Microsoft Access or a MySql database (using Visual Prolog’s ODBC linking). Notice in the picture a trend line between 1.7.2008 – 31.12.2008 and moving averages of 60 and 200 day.
Width = 600, Height = 400,
STOCK ="NOK",
HDB1 = dbBrowser::transferFromAccessDB("STOCKDBA",STOCK,dateTools:: makeDateNumber(2001,1,1)),
retractFactDB(timeserie),
localdatabases::readFactsFromString(timeserie,HDB1),
WINOBJ = pictWin::new(WIN),
O = timeseries::newPicture(Width,Height),
input(O,"CLOSE"),
O:setChartTitle("NOKIA ADR",10,color_black),
O:setInnerGraphAreaDimensions(10,15,90,85),
O:showLegend(false),
O:drawTrend(STOCK,"1.7.2008","31.12.2008",color_red,2,true),
O:drawMovingAverage(STOCK,200,color_gray,2),
O:drawMovingAverage(STOCK,60,color_blue,1),
O:setTimeScale("1.1.2008","maximum"),
O:setBackgroundColor(picCore::gradient_top_bottom,color_white,color_black),
O:setChartBackgroundColor(color_white),
O:setSerieAreaColor(1,color_gold),
O:setValueAxisTitle("USD"),
O:drawPicture(),
PICT = O:getPicture(),
vpi::cbPutPicture(PICT),
WINOBJ:setPicture(PICT,rct(10,10,Width+10,Height+10)),
Normally the value and time axis start and end point are calculated from the given data. However with predicates setValueScale:(real Minimum,real Maximum) and setTimeScale:(string MinimumDate,string MaximumDate).the focus can be restricted to the wanted space. With the clauses
o O:setValueScale(10,25),
o O:setTimeScale("1.1.2004","30.3.2004"),
The picture in the beginning of this picture class would look with the above limitations like this:
It is possible to eliminate from the chart the observations if one wants to emphasise the trend lines, moving average etc. This is done by adding observationDrawing(false) to the commands. The previous picture with this command would look like this.
Trend
There is also a possibility to draw a trend line formed from the wanted observations. The possibilities to inform about the need of calculating and drawing a trend in time graphs are predicates
drawTrend:(string DatasetName, string StartDate,string EndDate)
drawTrend : (string DataSetName, string StartDate, string EndDate, vpiDomains::color, integer Width, boolean WriteFormula)
drawTrend : (string DataSetName, string CalculationStartDate, string CalculationEndDate, string DrawingStartDate, string DrawingEndDate, vpiDomains::color, integer Width, boolean WriteFormula).
The predicate for calculating and drawing moving averages is
drawMovingAverage:(string DataSet, positive Lenght, color, integer Width).
The predicate for calculating and drawing exponential moving averages is
drawExponentialMovingAverage:(string DataSet, positive Length, color, integer Width).
Relative Strength Index (RSI)
The following predicate calculates and draws the RSI index.
drawRSI:(string DatasetName, positive LenghtOfTheCalculationPeriod, vpiDomains::color LineColor, integer Width).
The following predicate draws the Average True Range for the wanted stock or index
drawAverageTrueRange : (string DatasetName, positive Lenght, vpiDomains::color LineColor, integer Width)
For True Range (TR) and Average True Range (ATR) the input data must have the open, close, high and low figures.
Absolute Price Oscillator (APO) and Percentage Price Oscillator (PPO) can be drawn with predicates
drawPercentagePriceOscillator : (string DatasetName,
positive LenghtOfTheCalculationPeriodShort,
positive LenghtOfTheCalculationPeriodLong,
vpiDomains::color
LineColor,
integer
Width)
Commodity Channel Index (CCI) developed by Donald Lambert can be calculated and drawn with the predicate
drawCCI:(string DatasetName, positive Lenght, vpiDomains::color LineColor, integer Width)
TRIX developed by Jack Hutson is drawn by using predicate
drawTRIX : (string DatasetName, positive LenghtOfTheCalculationPeriod, vpiDomains::color LineColor, integer Width)
So called candlesticks charts are widely used in Asian stock information. Candlestick charts are on record as being the oldest type of charts used for price prediction. They date back to the 1700's, when they were used for predicting rice prices. More information how to interoperate candle stick charts can be found on http://www.tradersedgeindia.com/candlestick.htm .
To be able to make a candlestick chart, the data must include open, high, low and close values of daily observations. This is done using domain
· stockData(string Name,real Date,real OPEN,real HIGH,real LOW,real CLOSE,real VOLUME); or
· stockData2(string Name,string DateStr,real OPEN,real HIGH,real LOW,real CLOSE,real VOLUME).
with the predicate inputTimeGraphData for example
O:inputTimeGraphData(timeseries::stockData2(“NOK”,”16.8.2004”,10.2,10.1,10,96,10.8,1234567)).
Besides, that the data must inputted in a special way, also the type must be defined. It is performed with the predicate setTimeGraphType: (timeGraphType). In this case the type would be timeseries::candlestick.
O:setTimeGraphType(timeseries::candleStick),
Also this chart type is widely used is in stock analysis.
O:setTimeGraphType(timeseries::openClose),
This chart type is widely used to describe the relative changes of indexes or stock prices.
With the predicate
O: showRightMarginLabels(timeSeries::yes)
the name labels of time series are added in the right margin.
Bollinger band is a method to define a moving range around the stock prices. A solution, recommended by John Bollinger, defines the upper boundary as a chosen moving average plus twice the corresponding standard deviation, with the lower boundary as the moving average minus twice the standard deviation. The method is described below:
The Bollinger Band includes 3 lines: the upper band, lower band, and the centreline. The centreline is simply the moving average, and the upper and lower bands are, respectively, the centre line plus/minus twice the standard deviation. For a p-period Bollinger band:
· Centre Line = p-period moving average
· Upper Band = Centre Line + 2 x StdDev
· Lower Band = Centre Line -2 x StdDev
http://www.tradetrek.com/Education/tech_ind/technical_indicators02.asp
WINOBJ = pictWin::new(WIN),
Time = time::new(),
Time:getDateAndTime(Year, Month, Day, _Hour, _, _),
START = "1.1.2010",
END = string::format("%.%.%",Day,Month,Year),
O = timeseries::newPicture(500,300),
input(O,"CLOSE"),
O : setChartTitle("Nokia ADR",10,color_black),
O : setText(15,10,95,44,"Bollinger Band 21 days",[dtext_right],8,color_black),
O : setTimeScale(START,END),
O : setLogoParameters("nokia1.bmp",16,16,85),
O : setInnerGraphAreaDimensions(15,15,95,85),
O : showLegend(false),
O : setChartBackgroundColor(picCore::gradient_top_bottom,color_black,color_white),
O : setSerieLineColor(1,color_blue,3),
O : setvalueAxisTitle("USD"),
O : drawBollingerBand("NOK",21,2,color_yellow,color_red,1),
O : drawTrend("NOK","1.1.2009","12.3.2009"),
O : drawPicture(),
PICT = O:getPicture(),
WINOBJ:setPicture(PICT,rct(10,10,510,310)),
O2 = timeseries::newPicture(500,150),
input(O2,"CLOSE"),
O2 : setTimeScale(START,END),
O2 : showLegend(false),
O2 : hideTimeAxisNumbers(),
O2 : setInnerGraphAreaDimensions(15,6,95,95),
O2 : setChartBackgroundColor(picCore::gradient_top_bottom,color_black,color_white),
O2 : setSerieLineColor(1,color_lavender,1),
O2 : drawBollingerBandWidth("NOK",21,2,color_gold),
O2 : setvalueAxisTitle("Bandwidth"),
O2 : setDataUnit(""),
O2 : drawPicture(),
PICT2 = O2:getPicture(),
WINOBJ:setPicture(PICT2,rct(10,310,510,460)),
O3 = timeseries::newPicture(500,150),
input(O3,"CLOSE"),
O3 : showLegend(false),
O3 : hideTimeAxisNumbers(),
O3 : setTimeScale(START,END),
O3 : setInnerGraphAreaDimensions(15,6,95,95),
O3 : setChartBackgroundColor(picCore::gradient_top_bottom,color_black,color_white),
O3 : drawBollingerBandB("NOK",21,2,color_yellow),
O3 : setvalueAxisTitle("b"),
O3 : drawPicture(),
PICT3 = O3:getPicture(),
WINOBJ:setPicture(PICT3,rct(10,460,510,610)),
PICT5 = vpi::pictOpen(rct(0,0,500,600)),
vpi::pictDraw(PICT5,PICT,pnt(0,0),rop_SrcCopy),
vpi::pictDraw(PICT5,PICT2,pnt(0,300),rop_SrcCopy),
vpi::pictDraw(PICT5,PICT3,pnt(0,450),rop_SrcCopy),
vpi::cbPutPicture(vpi::pictClose(PICT5)),
When there is a need to create a chart based on second based information (for example in simulation applications or in a daily stock chart), it can be done with this dll library.
The picture above is created with the code
drawRangePicture(4):-
page(4,_,PictControl),!,
rct(X,Y,W,H) = PictControl : getOuterRect(),
gObj := timeseries::newPicture(W-X-5,H-Y-5),
gObj:setBackgroundColor(2,color_blue,color_white),
gObj:setGraphBackgroundColor(1,color_black,color_black),
gObj:setSerieAreaColor(1,color_gold),
gObj:setSerieAreaColor(2,color_silver),
gObj:setInnerGraphAreaDimensions(10,20,95,80),
gObj:setGraphTitle("Development of Population size",12,color_white),
readDataInThePicture(“Population”),
gObj:setValueAxesTitle("Size of the living population"),
gObj:drawPicture(),
PICT = gObj:getPicture(),
vpi::cbPutPicture(PICT),
PictControl :setPicture(PICT).
The data is updated in chart object in this example with the following code
readDataInThePicture("POPULATION"):-
stat(Time, _Speed, _Vision, _Reproduction,_,Population,Predators),
gOBJ:inputTimeGraphData(timeseries::tData4("Population",Time,Population)),
gOBJ:inputTimeGraphData(timeseries::tData4("Predators",Time,Predators)),
fail.
If there is a need to present data with several dimensions one solution is a so called radar chart.
If there is only one observation the area is filled.
The amount of axis must be greater than two. The axis name and its scale are set with predicate setAxesAndScale:(integer AxesNumber,string Text,real Minimum, real Maximum)
O:setAxesAndScale(1,"Temperature",-20,50),
O = radar::newPicture(500,500),
O:setBackgroundColor(2,color_GoldenRod,color_black),
O:setSourceText("Peter Sellers: Study in University 2010",10,color_white),
O:setGraphTitle("Six Conditions for excelent value-based management",14,color_yellow),
O:setAxisAndScale(1,"Low Cost",0,100),
O:setAxisAndScale(2,"Performance driven",-20,50),
O:setAxisAndScale(3,"Value based",0,1000),
O:setAxisAndScale(4,"Managed bottom up as well as top down",0,100),
O:setAxisAndScale(5,"Two way communication",0,3),
O:setAxisAndScale(6,"Strong self-reinforcement process",0,3),
O:setDataSerieColor(1,color_CadetBlue),
O:inputRadarData(radar::rData("Company A","Low Cost",80)),
O:inputRadarData(radar::rData("Company A","Performance driven",0)),
O:inputRadarData(radar::rData("Company A","Value based",200)),
O:inputRadarData(radar::rData("Company A","Managed bottom up as well as top down",80)),
O:inputRadarData(radar::rData("Company A","Two way communication",1)),
O:inputRadarData(radar::rData("Company A","Strong self-reinforcement process",2)),
O:drawpicture(),
PICT = O:getPicture(),
If there are several observations, the area for each observation is surrounded with a line.
O = radar::newPicture(500,500),
O:setBackgroundColor(4,color_black,color_white),
O:setChartTitle("Key
figure rating Company X",14,color_silver),
O:setAxisAndScale(1,"Income",0,100),
O:setAxisAndScale(2,"Profitability",-20,50),
O:setAxisAndScale(3,"Financial burden",0,1000),
O:setAxisAndScale(4,"Liquidity",0,100),
O:setAxisAndScale(5,"Financial risk",0,3),
O:setAxisAndScale(6,"Business risk",0,3),
O:setDataSerieColor(1,color_red),
O:setDataSerieColor(2,color_CadetBlue),
O:inputRadarData(radar::rData("Fiscal period 2010","Income",80)),
O:inputRadarData(radar::rData("Fiscal period 2010","Profitability",0)),
O:inputRadarData(radar::rData("Fiscal period 2010","Financial burden",200)),
O:inputRadarData(radar::rData("Fiscal period 2010","Liquidity",80)),
O:inputRadarData(radar::rData("Fiscal period 2010","Financial risk",1)),
O:inputRadarData(radar::rData("Fiscal period 2010","Business risk",2)),
O:inputRadarData(radar::rData("Fiscal period 2009","Income",40)),
O:inputRadarData(radar::rData("Fiscal period 2009","Profitability",20)),
O:inputRadarData(radar::rData("Fiscal period 2009","Financial burden",500)),
O:inputRadarData(radar::rData("Fiscal period 2009","Liquidity",60)),
O:inputRadarData(radar::rData("Fiscal period 2009","Financial risk",3)),
O:inputRadarData(radar::rData("Fiscal period 2009","Business risk",1)),
O:drawpicture(),
PICT = O:getPicture(),
The Boston Consulting Group matrix chart was created for strategic mapping. It is used in business plans and other business analyses.
As in the below example can be seen the observations can be drawn with a third parameter which controls the observations size (for example turnover).
WINOBJ = pictWin::new(WIN),
O = boston::newPicture(400,400),
O:setBackgroundColor(boston::gradient_top_bottom,color_skyblue,color_brown),
O:setGraphBackgroundColor(boston::gradient_left_right,color_black,color_white),
O:setInnerGraphAreaDimensions(15,15,95,80),
O:setGraphTitle("Market Situation 2010",14,color_white),
O:setXScaleTitles("Relative Market Share","high","low"),
O:setYScaleTitles("Market Growth Rate","low","high"),
O:inputBostonData(boston::bostonData("Company A","",10,75,20,color_gold)),
O:inputBostonData(boston::bostonData("Company B","",70,25,100,color_red)),
O:inputBostonData(boston::bostonData("Company C","",40,45,40,color_blue)),
O:inputBostonData(boston::bostonData("Company D","",10,20,60,color_gold)),
O:inputBostonData(boston::bostonData("Company E","",85,80,60,color_silver)),
O:setSourceText("Consulting Ltd © 2010",8,color_yellow),
O:setText(30,16,"STARS",10,color_yellow),
O:setText(60,16,"QUESTION MARKS",10,color_black),
O:setText(30,75,"CASH COWS",10,color_yellow),
O:setText(70,75,"DOGS",10,color_black),
O:setLegendStartPoint(10,95),
O:drawPicture(),
PICT = O:getPicture(),
vpi::cbPutPicture(PICT),
WINOBJ:setPicture(PICT,rct(10,10,410,410)),
It is possible to add own text (comments etc) to the graph as in the above example. This is done with the predicates described below:
setText : (
integer UpperX,
integer UpperY,
string Text,
integer FontSize,
color FontColor)
procedure (i,i,i,i,i)
language stdcall.
Sets a text to a desired place with a desired font size and color.
Description
Sets a text to a desired place with desired font and colour.
Start points coordinates are in percent from the whole pictures drawing area.
Example:
O:setText:(90,10,"Hello there",12,color_black).
setTextBox : (
integer UpperX,
integer UpperY,
string Text,
integer FontSize,
color FontColor,
color BoxColor)
procedure (i,i,i,i,i,i)
language stdcall.
Sets a text in a box to a desired place with desired font and background colour.
Description
Sets a text in a box to a desired place with desired font and
background colour.
Start points coordinates are in percent from the whole pictures drawing area.
Example:
O:setTextBox:(90,10,"Hello there",12,color_black,color_yellow).
Gauge chart is relative rarely used chart type in documents which have charts. The reason is simple. A Gauge chart can present only one measurement value.
W = 620, H=420,
O = gauge::newPicture(W,H),
O : setGraphTitle("Production during September",12,color_blue),
O:setGaugeDegrees(135,45),
O:scaleNumbers([0,100,300,700,1000,1500,3000,4000,5000,6000,7000]),
O:setGaugeColors([gauge::gaugeColor(0,1500,color_red),gauge::gaugeColor(4000,5500,color_blue),gauge::gaugeColor(5500,7000,color_yellow)]),
O:setValue(3200),
O:drawPicture(),
PICT = O:getPicture(),
Gantt chart was developed by Henry L. Gantt (1861-1919), an American engineer, in 1917. His first charts were used in ship building projects during WW1. Gantt chart is a type of bar chart that illustrates a project schedule.
The main reason for this chapter is to give some ideas how to use PictureDLL in producing graphical output as a part of your application. PictureDLL can produce charts to be used in output documents and also charts as a part in complex dialogs and windows.
With the PictureDLL can easily composed several charts on the same time and then added into a bigger chart combination. These chart sets can be a mixture of different chart types. Each chart is produced separately and in the end the pictures are drawn in a new large picture. Finally that new picture is drawn on the screen.
The example below consists of a pie and bar chart, which are drawn to the same window.
O = pie::newPicture(500,500),
O:setBackgroundColor(picCore::gradient_top_bottom,color_black,color_black),
O:setInnerGraphAreaDimensions(25,35,75,65),
O:setChartTitle("Import from Russia to Finland",12,color_white),
O:setSliceDisplacementForSlice("ALL"),
O:inputPieData(pie::pData("Gas",12)),
O:inputPieData(pie::pData("Wood",3.7)),
O:inputPieData(pie::pData("Chemicals",5.2)),
O:inputPieData(pie::pData("Metals",6.9)),
O:inputPieData(pie::pData("Electricity",5.2)),
O:inputPieData(pie::pData("Coal",4.3)),
O:inputPieData(pie::pData("Others",5.1)),
O:inputPieData(pie::pData("Oil and oil products",57.7)),
O:setDataUnit("%"),
O:setSourceText("Source: Finnish Customs",10,color_white),
O:drawPicture(),
PICT = O:getPicture(),
vpi::cbPutPicture(PICT),
WINOBJ:setPicture(PICT,rct(10,10,510,510)),
O2 = bar::newPicture(500,500),
O2:setTextAndLineColor(color_ltGray),
O2:setBackgroundColor(picCore::gradient_top_bottom,color_white,color_seagreen),
O2:setBarChartType(bar::vertical,bar::normal),
O2:setChartBackgroundColor(picCore::gradient_top_bottom,color_white,color_ltGray),
O2:setInnerGraphAreaDimensions(15,19,95,85),
O2:setBarSpace(30),
O2:setBarColor(1,0,color_red,color_red),
O2:setBarColor(2,0,color_blue,color_black),
O2:inputBarData(bar::bData("2004","Import from Russia",4362)),
O2:inputBarData(bar::bData("2004","Import from Germany",5960)),
O2:inputBarData(bar::bData("2005","Import from Russia",5744)),
O2:inputBarData(bar::bData("2005","Import from Germany",7027)),
O2:inputBarData(bar::bData("2006","Import from Russia",6220)),
O2:inputBarData(bar::bData("2006","Import from Germany",7668)),
O2:inputBarData(bar::bData("2007","Import from Russia",6724)),
O2:inputBarData(bar::bData("2007","Import from Germany",8416)),
O2:inputBarData(bar::bData("2008","Import from Russia",7618)),
O2:inputBarData(bar::bData("2008","Import from Germany",8787)),
O2:inputBarData(bar::bData("2009","Import from Russia",6724)),
O2:inputBarData(bar::bData("2009","Import from Germany",6313)),
O2:setDataUnit("m. "),
O2:setvalueAxisTitle("million Euro"),
O2:setChartTitle("Import from Russia and Germany 2004-2009",12,color_black),
O2:setSourceText("Source: Finnish Customs - Tullihallitus",10,color_white),
O2:drawPicture(),
PICT2 = O2:getPicture(),
PICT3 = vpi::pictOpen(rct(0,0,1000,500)),
vpi::pictDraw(PICT3,PICT,pnt(0,0),rop_SrcCopy),
vpi::pictDraw(PICT3,PICT2,pnt(500,0),rop_SrcCopy),
vpi::cbPutPicture(vpi::pictClose(PICT3)),
In the following examples is stock index data fetched from a SQL database and used for drawing different kind of stock charts.
The first example is a “traditional” stock chart with the development of the index, volume and Relative Strength Index (RSI).
pictures(1,WIN):-
INDEX = "NDX",
HDB = dbBrowser::transferFromAccessDB("INDEXDBA",INDEX,
dateTools:: makeDateNumber(2008,1,1)),
retractFactDb(timeserie),
localdatabases::readFactsFromString(timeserie,HDB),
WINOBJ = pictWin::new(WIN),
O = timeseries::newPicture(500,300),
input(O,"CLOSE"),
O : setChartTitle("NASDAQ 100 INDEX development",10,color_black),
O : setLogoParameters("nasdaq_logo1.bmp",70,20,90),
O : setInnerGraphAreaDimensions(15,15,95,99),
O : setTimeScale("1.6.2008","maximum"),
O : showLegend(false),
O : showOuterFrame(false),
O : showWeekEnds(false),
O : hideTimeAxisNumbers(),
O : setChartBackgroundColor(picCore::gradient_top_bottom,color_silver,color_white),
O : setSerieLineColor(1,color_black,1),
O : drawLine(color_blue,2,"28.11.2008",1300,"5.4.2009",1300),
O : drawLine(color_blue,2,"28.11.2008",1100,"5.4.2009",1100),
O : setValueAxisTitle("INDEX"),!,
O : drawPicture(),
PICT = O : getPicture(),
O2 = timeseries::newPicture(500,120),
input(O2,"CLOSE"),
O2 : setTimeScale("1.6.2008","maximum"),
O2 : showLegend(false),
O2 : showOuterFrame(false),
O2 : showWeekEnds(false),
O2 : hideTimeAxisNumbers(),
O2 : drawRSI(INDEX,20, color_black,1),
O2 : setInnerGraphAreaDimensions(15,5,95,95),
O2 : setChartBackgroundColor(picCore::gradient_top_bottom,color_silver,color_white),
O2 : setvalueAxisTitle("RSI"),
O2 : drawPicture(),
PICT2 = O2 : getPicture(),
O3 = timeseries::newPicture(500,180),
input(O3,"VOLUME"),
O3 : setInnerGraphAreaDimensions(15,6,95,78),
O3 : setTimeScale("1.6.2008","maximum"),
O3 : setTimeChartType(timeseries::bar),
O3 : showLegend(false),
O3 : showOuterFrame(false),
O3 : showWeekEnds(false),
O3 : setChartBackgroundColor(picCore::gradient_top_bottom,color_silver,color_white),
O3 : setSerieBar(1,color_red),
O3 : setvalueAxisTitle(""),
O3 : setDataUnit("$"),
O3 : drawPicture(),
PICT3 = O3 : getPicture(),
PICT4 = vpi::pictOpen(rct(0,0,500,600)),
vpi::pictDraw(PICT4,PICT,pnt(0,0),rop_SrcCopy),
vpi::pictDraw(PICT4,PICT2,pnt(0,300),rop_SrcCopy),
vpi::pictDraw(PICT4,PICT3,pnt(0,420),rop_SrcCopy),
PIC = vpi::pictClose(PICT4),
vpi::cbPutPicture(PIC),
WINOBJ:setPicture(PIC,rct(10,10,510,610)),
!.
pictures(_,_WIN):-!.
class predicates
inputStockData:(timeseries,dbBrowser::indChgSeries) determ.
stockSerieInput:(timeseries,string INDEX,core::unsigned_list Dates,core::real_list) determ.
input:(timeseries,string).
clauses
inputStockData(_O,[]):-!.
inputStockData(O,[dbBrowser::indChg(INDEX,DATES,VALUES)|TAIL]):-
stockSerieInput(O,INDEX,DATES,VALUES),
inputStockData(O,TAIL).
stockSerieInput(_O,_,[],[]):-!.
stockSerieInput(O,INDEX,[DATE|TAIL1],[VALUE|TAIL2]):-
O:inputTimeGraphData(timeseries::tData(INDEX,DATE,VALUE)),!,
stockSerieInput(O,INDEX,TAIL1,TAIL2).
input(O,"VOLUME"):-
ind(stat(INDEX,"D",Date,_,_,_,_,Volume)),
O:inputTimeGraphData(timeseries::tData(INDEX,DATE,Volume)),
fail.
input(O,"CLOSE"):-
ind(stat(INDEX,"D",Date,_,_,_,Close,_)),
O:inputTimeGraphData(timeseries::tData(INDEX,DATE,Close)),
fail.
input(_,_):-!.
As form the chart and code of this example can be seen, it is possible to add extra bitmaps (the logo of Nasdaq Stock Exchange in the example) to the drawn chart. This is done with following predicates[5]:
bar::setLogoAndMaskParameters/5
setLogoAndMaskParameters : (
string LogoBitmapFile,
string MaskBitmapFile,
integer UpperLeftX,
integer UpperLeftY,
integer PercentageOfBitmapsOriginalSize)
procedure (i,i,i,i,i)
language stdcall.
Sets the parameters of the logo drawing.
Description
Sets the parameters of the logo drawing. This predicate is used if
the user wants to use a mask with the actual bitmap file.
The figures are in percentage of the area. For example 10 in UpperLeftX means
that the inner drawing area begins from 10 percent of the total width of the
graph. The last parameter is the size in percents of the original bitmap.
Predicate fails if the either of the bitmap files is not found.
Example:
O:setLogoParameters("logo.bmp","logomask.bmp",80,15,50),
setLogoParameters : (
string LogoBitmapFile,
integer UpperLeftX,
integer UpperLeftY,
integer PercentageOfBitmapsOriginalSize)
procedure (i,i,i,i)
language stdcall.
Sets the parameters for the logo drawing.
Description
Sets the parameters of the logo drawing. This predicate informs
the start point of logo bitmap and the percentage of its size (100 means
original size). The figures are in percentage of the area. For example 10 in
UpperLeftX means that the inner drawing area begins from 10 percent of the
total width of the graph. The last parameter is the size in percents of the
original bitmap.
Predicate fails if the bitmap file is not found.
Example:
O:setLogoParameters("logo.bmp",80,15,80),
setLogoParameters : (
string LogoBitmapFile,
integer X1,
integer Y1,
integer X2,
integer Y2)
procedure (i,i,i,i,i)
language stdcall.
Set the parameters of the logo drawing.
Description
Sets the parameters for the logo drawing. This predicate is used if the user wants to fill certain areas of the graph with a bitmap. The figures are in percentage of the area. For example 10 in UpperLeftX means that the inner drawing area begins from 10 percent of the total width of the graph.
Fails if the bitmap file is not found.
Example:
O:setLogoParameters("logo.bmp",80,15,95,30),
The second example is a set of four major companies’ stocks price development.
pictures(11,WIN):-
PICT1 = produceStockPicture("NOK","NOKIA ADR"),
PICT2 = produceStockPicture("MOT","MOTOROLA"),
PICT3 = produceStockPicture("ERICY","ERICSSON ADR"),
PICT4 = produceStockPicture("MSFT","MICROSOFT"),
PICT5 = vpi::pictOpen(rct(0,0,800,800)),
vpi::pictDraw(PICT5,PICT1,pnt(0,0),rop_SrcCopy),
vpi::pictDraw(PICT5,PICT2,pnt(400,0),rop_SrcCopy),
vpi::pictDraw(PICT5,PICT3,pnt(0,400),rop_SrcCopy),
vpi::pictDraw(PICT5,PICT4,pnt(400,400),rop_SrcCopy),
PICT6 = vpi::pictClose(PICT5),
WINOBJ = pictWin::new(WIN),
WINOBJ:setPicture2(PICT6,pnt(10,10)),
!.
class predicates
produceStockPicture:(string STOCK,string HEADER) -> picture determ.
clauses
produceStockPicture(STOCK,HEADER) = O:getPicture():-
HDB1 = dbBrowser::transferFromAccessDB("STOCKDBA",STOCK,dateTools:: makeDateNumber(2004,1,1)),
retractFactDB(timeserie),
localdatabases::readFactsFromString(timeserie,HDB1),
O = timeseries::newPicture(400,400),
input(O,"CLOSE"),
O:setGraphTitle(HEADER,10,color_black),
O:setInnerGraphAreaDimensions(20,20,95,85),
O:showLegend(false()),
O:setGraphBackgroundColor(picCore::gradient_tube_top_bottom,color_lightgray,color_lavender),
O:setSerieLineColor(1,color_black,1),
O:drawTrend(STOCK,"1.1.2004","31.12.2004",color_red,1,false()),
O:drawTrend(STOCK,"1.1.2005","31.12.2005",color_green,1,false()),
O:drawTrend(STOCK,"1.1.2006","31.12.2006",color_red,1,false()),
O:drawTrend(STOCK,"1.1.2007","31.12.2007",color_green,1,false()),
O:drawTrend(STOCK,"1.1.2008","31.12.2008",color_blue,1,false()),
O:drawTrend(STOCK,"1.1.2009","15.12.2009",color_green,1,false()),
O:showLogos(true()),
addLogo(O,STOCK),
O:setvalueAxisTitle("USD"), O:drawPicture().
This example shows the structure of a dialog where is calculated a distribution histogram of random function (vp::random()) and a random normal distribution function (Box-Muller method). The full code of this example is in ptest2 project in histograms.pack.
In the dialog is first created objects for both charts.
predicates
onCreate : vpiDomains::createHandler.
clauses
onCreate(_CreationData) = defaultHandling():-
createPicture(1),
createPicture(2).
predicates
createPicture:(integer).
clauses
createPicture(1):-
picWin1 := vpi::winGetCtlHandle(thisWIN,idct_random),
DestRect = vpi::winGetClientRect(picWin1),
DestRect = rct(_,_,W,H),
O = bar::newPicture(W,H),
O:setGraphTitle("Random numbers between 0-1",10,color_white),
O:setBackgroundColor(3,color_ivory,color_dkgray),
O:setBarChartType(bar::vertical,bar::histogram),
O:setGraphBackgroundColor(4,color_silver,color_white),
O:setScale(0,bar::maximum),
O:setHistogramClassRange(1,"0-0.1",-1, 0.1),
O:setHistogramClassRange(2,"0.1 - 0.2",0.1,0.2),
O:setHistogramClassRange(3,"0.2 - 0.3",0.2,0.3),
O:setHistogramClassRange(4,"0.3 - 0.4",0.3,0.4),
O:setHistogramClassRange(5,"0.4 - 0.5",0.4,0.5),
O:setHistogramClassRange(6,"0.5 - 0.6",0.5,0.6),
O:setHistogramClassRange(7,"0.6 - 0.7",0.6,0.7),
O:setHistogramClassRange(8,"0.7 - 0.8",0.7,0.8),
O:setHistogramClassRange(9,"0.8 - 0.9",0.8,0.9),
O:setHistogramClassRange(10,"0.9 - 1",0.9,1.1),
O:setValueAxesTitle("AMOUNT"),
O:setInnerGraphAreaDimensions(19,19,96,80),
O:setBarSpace(0),
O:drawPicture(),
picture1 := O:getPicture(),
assert(pictureObject(1,O)),
assert(timerPicture(1,vpi::timerSet(thisWin,1000))),
assert(timerCalculation(1,vpi::timerSet(thisWin,100))),
!.
createPicture(2):-
picWin2 := vpi::winGetCtlHandle(thisWIN,idc_histo2),
DestRect = vpi::winGetClientRect(picWin2),
DestRect = rct(_,_,W,H),
O = bar::newPicture(W,H),
O:setGraphTitle("Random normal distribution between -1- +1",10,color_white),
O:setBackgroundColor(bar::gradient_left_right,color_ivory,color_dkgray),
O:setBarChartType(bar::vertical,bar::histogram),
O:setGraphBackgroundColor(bar::gradient_top_bottom,color_silver,color_white),
O:setScale(0,bar::maximum),
O:setBarColor(1,bar::gradient_tube_left_right,color_powderblue,color_white),
O:setHistogramClassRange(1,"-0.8- -1",-1.1,-0.8),
O:setHistogramClassRange(2,"-0.6 - -0.8",-0.8,-0.6),
O:setHistogramClassRange(3,"-0.4 - -0.6",-0.6,-0.4),
O:setHistogramClassRange(4,"-0.2 - -0.4",-0.4,-0.2),
O:setHistogramClassRange(5,"0 - -0.2",-0.2,0),
O:setHistogramClassRange(6,"0.0 - 0.2",0,0.2),
O:setHistogramClassRange(7,"0.2 - 0.4",0.2,0.4),
O:setHistogramClassRange(8,"0.4 - 0.6",0.4,0.6),
O:setHistogramClassRange(9,"0.6 - 0.8",0.6,0.8),
O:setHistogramClassRange(10,"0.8 - 1",0.8,1.1),
O:setValueAxesTitle("AMOUNT"),
O:setInnerGraphAreaDimensions(19,19,96,80),
O:setBarSpace(0),
O:drawPicture(),
picture2 := O:getPicture(),
assert(pictureObject(2,O)),
assert(timerPicture(2,vpi::timerSet(thisWin,1000))),
assert(timerCalculation(2,vpi::timerSet(thisWin,100))),
!.
createPicture(_).
Both chart objects create two timers. The first one counts the random value every 0.1 second and sends it to the chart object using predicate inputBarData. The other timer sends every one second an update request to the chart object and updates the screen.
predicates
onTimer : vpiDomains::timerHandler.
clauses
onTimer(TimerID) = defaultHandling():-
timerCalculation(1,TimerID),
pictureObject(1,O),
O:inputBarData(bar::hData(math::random())),
!.
onTimer(TimerID) = defaultHandling():-
timerPicture(1,TimerID),
pictureObject(1,O),
O:drawPicture(),
picture1 := O:getPicture(),
upDatePicture(1),
!.
onTimer(TimerID) = defaultHandling():-
timerCalculation(2,TimerID),
pictureObject(2,O),
O:inputBarData(bar::hData(statisticalTools::randomNormalDistibution())),
!.
onTimer(TimerID) = defaultHandling():-
timerPicture(2,TimerID),
pictureObject(2,O),
O:drawPicture(),
picture2 := O:getPicture(),
upDatePicture(2),
!.
onTimer(_TimerID) = defaultHandling().
Because the data amount of each chart increases, the heap memory is sooner or later used. To avoid this there is an extra predicate deleteOldHistogramInput(), which takes care that the input data is deleted after it has been added to its histogram class.
The following example is a simple cash flow calculator. The calculator has four input fields and produces every time the input is changed a chart and two key figure fields.
The code for this example can be found in the example project ptest2.
This example shows how to program a dialog showing two stock datasets where the time axis can be changed using a scrollbar control and radiobuttons.
Because the documentation of all chart classes would demand to many pages in this document, here is listed only the predicate summary of timeseries class. The documentation of all chart classes can be found in internet from the address http://koti.welho.com/krastas/picturedll/index-hhc.htm .
The interface contains a collection of predicates for drawing time related charts.
calculateAndDrawBollingerBand : (string DatasetName,
positive Lenght, real STD, timeNumbers* Dates, real* DataValues, vpiDomains::color BandArea, vpiDomains::color
LineColorForMiddle, integer Width) procedure
(i,i,i,i,i,i,i,i). |
|
changePictureSize :
(positive Width,
positive Height) procedure
(i,i). |
|
drawAbsolutePriceOscillator : (string DatasetName,
positive LenghtOfTheCalculationPeriodShort,
positive LenghtOfTheCalculationPeriodLong, vpiDomains::color
LineColor, integer Width) procedure
(i,i,i,i,i). |
|
drawAverageTrueRange : (string DatasetName,
positive Lenght, vpiDomains::color
LineColor, integer Width) procedure
(i,i,i,i). |
|
drawBand : (string
DatasetName, timeNumbers* Dates, real* LowerBandData, real* UpperBandData, vpiDomains::color
BandArea) procedure
(i,i,i,i,i). |
|
drawBandWithMedium : (string DatasetName, timeNumbers* Dates, real* LowerBandData, real* MediumBandData, real* UpperBandData, vpiDomains::color BandArea, vpiDomains::color
LineColorForMiddle, integer Width) procedure
(i,i,i,i,i,i,i,i). |
|
drawBollingerBand : (string DatasetName,
positive Lenght, real STD, vpiDomains::color
ColorBandArea, vpiDomains::color
LineColorForMiddle, integer Width) procedure
(i,i,i,i,i,i). |
|
drawBollingerBandB : (string DatasetName,
positive Lenght, real STD, vpiDomains::color
Color) procedure
(i,i,i,i). |
|
drawBollingerBandwidth : (string DatasetName,
positive Lenght, real STD, vpiDomains::color
Color) procedure
(i,i,i,i). |
|
drawCCI : (string
DatasetName,
positive Lenght, vpiDomains::color
LineColor, integer Width) procedure
(i,i,i,i). |
|
drawExponentialMovingAverage : (string DatasetName,
positive Lenght, vpiDomains::color
LineColor, integer Width) procedure
(i,i,i,i). |
|
drawLine : (vpiDomains::color, integer
Width, string Date1, real Y1, string Date2, real Y2) procedure
(i,i,i,i,i,i). |
|
drawMovingAverage : (string DatasetName,
positive Lenght, vpiDomains::color
LineColor, integer Width) procedure
(i,i,i,i). |
|
drawPercentagePriceOscillator : (string DatasetName,
positive LenghtOfTheCalculationPeriodShort,
positive LenghtOfTheCalculationPeriodLong, vpiDomains::color
LineColor, integer Width) procedure
(i,i,i,i,i). |
|
drawPicture : () procedure (). |
|
drawRSI : (string
DatasetName,
positive LenghtOfTheCalculationPeriod, vpiDomains::color
LineColor, integer Width) procedure
(i,i,i,i). |
|
drawTRIX : (string
DatasetName,
positive LenghtOfTheCalculationPeriod, vpiDomains::color
LineColor, integer Width) procedure
(i,i,i,i). |
|
drawTrend : (string
DatasetName, string StartDate, string EndDate) procedure
(i,i,i). |
|
drawTrend : (string
DataSetName, string StartDate, string EndDate, vpiDomains::color, integer Width, boolean WriteFormula) procedure
(i,i,i,i,i,i). |
|
drawTrend : (string
DataSetName, string CalculationStartDate, string CalculationEndDate, string DrawingStartDate, string DrawingEndDate, vpiDomains::color, integer Width, boolean WriteFormula) procedure
(i,i,i,i,i,i,i,i). |
|
drawTrendEstimate : (string DataSetName, string EndDate, real Value) procedure
(i,i,i). |
|
drawTrendEstimateArea : (string DataSetName, string EndDate, real Value1, real Value2, vpiDomains::color) procedure
(i,i,i,i,i). |
|
drawTrueRange : (string
NAME, vpiDomains::color
COLOR, integer WIDTH) procedure
(i,i,i). |
|
drawValueLine : (real, vpiDomains::color, integer Width) procedure
(i,i,i). |
|
getInnerGraphAreaDimensions :
(positive UpperLeftX,
positive UpperLeftY,
positive DownRightX,
positive DownRightX) determ
(o,o,o,o). |
|
getLegendStartPoint : (positive UpperLeftX,
positive UpperLeftY) procedure
(o,o). |
|
getPicture : () -> picture procedure (). |
|
getPictureSize : (positive Width,
positive Height) procedure
(o,o). |
|
getTimeGraphType : () -> timeGraphType TYPE determ. |
|
hideTimeAxisNumbers : () procedure. |
|
inputTimeGraphData : (tData) procedure (i). |
|
setBackgroundColor : (vpiDomains::color) procedure (i). |
|
setBackgroundColor : (picCore::gradientDirection, vpiDomains::color
StartColor, vpiDomains::color
EndColor) procedure
(i,i,i). |
|
setBarSpace : (positive Pixels) procedure (i). |
|
setDataUnit : (string) procedure (i). |
|
setGraphBackgroundColor : (vpiDomains::color) procedure (i). |
|
setGraphBackgroundColor : (picCore::gradientDirection, vpiDomains::color, vpiDomains::color) procedure
(i,i,i). |
|
setGraphTitle : (string
Title) procedure (i). |
|
setGraphTitle : (string
TitleText, integer FontSize, vpiDomains::color
FontColor) procedure
(i,i,i). |
|
setInnerGraphAreaDimensions :
(positive UpperLeftX,
positive UpperLeftY,
positive DownRightX,
positive DownRightY) procedure
(i,i,i,i). |
|
setLegendStartPoint : (positive UpperLeftX,
positive UpperLeftY) procedure
(i,i). |
|
setLogoAndMaskParameters : (string LogoBitmapFile, string MaskBitmapFile,
positive X1,
positive Y1,
positive PercentageOfOriginalSize) procedure
(i,i,i,i,i). |
|
setLogoParameters : (string LogoBitmapFile, positive
X1,
positive Y1,
positive PercentageOfOriginalSize) procedure
(i,i,i,i). |
|
setLogoParameters : (string LogoBitmapFile,
positive X1,
positive Y1,
positive X2,
positive Y2) procedure
(i,i,i,i,i). |
|
setLogoParametersAndCreateMask : (string LogoBitmapFile,
positive X1,
positive Y1,
positive PercentageOfOriginalSize) procedure
(i,i,i,i). |
|
setNumberScaleNumberSize :
(positive) procedure (i). |
|
setRightValueScale : (real Minimum, real Maximum) procedure
(i,i). |
|
setSerieAreaColor :
(positive DataSerieNumber, vpiDomains::color
SolidColor) procedure
(i,i). |
|
setSerieBar : (positive DataSerieNumber, vpiDomains::color
SolidColor) procedure
(i,i). |
|
setSerieLineColor :
(positive DataSerieNumber, vpiDomains::color
SolidColor,
positive Width) procedure
(i,i,i). |
|
setSeriePoint : (positive DataSerieNumber, vpiDomains::color
SolidColor,
positive Size, boolean LineBetweenPointMarks) procedure
(i,i,i,i). |
|
setSourceText : (string
SourceText) procedure (i). |
|
setSourceText : (string
SourceText, integer FontSize, vpiDomains::color) procedure
(i,i,i). |
|
setText : (integer
UpperX, integer UpperY, string Text, integer FontSize, vpiDomains::color
FontColor) procedure
(i,i,i,i,i). |
|
setText : (integer
UpperX, integer UpperY, integer LowerX, integer LowerY, string Text, integer* FormatFlags, integer FontSize, vpiDomains::color
FontColor) procedure
(i,i,i,i,i,i,i,i). |
|
setTextBox : (integer
UpperX, integer UpperY, string Text, integer FontSize, vpiDomains::color
FontColor, vpiDomains::color
BoxColor) procedure
(i,i,i,i,i,i). |
|
setTimeGraphType : (timeGraphType
TYPE) procedure (i). |
|
setTimeScale : (string
MinimumDate, string MaximumDate) procedure
(i,i). |
|
setTimeScale2 : (timeNumbers
MinimumDate, timeNumbers MaximumDate) procedure
(i,i). |
|
setTimeScaleNumberSize :
(positive) procedure (i). |
|
setValueAxisTitle : (string TitleText) procedure (i). |
|
setValueAxisTitle : (string TitleText, integer Size) procedure
(i,i). |
|
setValueScale : (real
Minimum, real Maximum) procedure
(i,i). |
|
showDataLabels : (boolean) procedure (i). |
|
showLegend : (boolean) procedure (i). |
|
showLogos : (boolean) procedure (i). |
|
showOuterFrame : (boolean) procedure (i). |
|
showRightMarginLabels : (boolean) procedure (i). |
|
showTimeAxisNumbers : () procedure. |
|
showWeekEnds : (boolean) procedure (i). |
|
writeAllTimescaleLabels : (boolean) procedure (i). |
The following is the list of recognized color keywords that can be used as a keyword value for data type <color>:
|
|
|
3
3D · 15
3D effect · 15
A
absolute price oscillator · 27
APO · 27
application · 3
ATR · 27
average true range · 27
Average True Range · 27
averages · 27
B
bar chart · 6, 39, 41
bar orientation · 10
bitmap file · 46
bitmaps · 45
Bollinger band · 30
Bollinger, John · 30
Boston Consulting Group · 37
Box-Muller method · 49
build-up bar · 6
buildUp chart · 11
business plan · 37
C
calculator · 51
candlestick · 28
cash flow · 51
CCI · 28
changePictureSize · 5
chart tile · 4
column chartss · 6
comments · 38
commodity channel index · 28
common predicates · 3
company key figure · 21
D
deleteOldHistogramInput · 51
dimensions · 5
displacement ratio · 15
documentation · 3, 53
drawAverageTrueRange · 27
drawCCI · 28
drawExponentialMovingAverage · 27
drawing area · 4
drawMovingAverage · 25, 27
drawPicture · 3
drawRSI · 27
drawToWindow · 3
drawTrend · 26
drawTrendEstimate · 20, 54
drawTrendEstimateArea · 20
drawTRIX · 28
drawValueAxisNumbersOnRightSide · 10, 21
E
exponential moving averages · 27
G
gantt chart · 39
gradient colouring · 5
gradient_tube_top_bottom · 5
H
help file · 2, 3
histogram · 6, 12, 49
horizontal · 6, 8
horizontal bar chart · 6
Hutson, Jack · 28
I
inputBarData · 12, 50
inputTimeGraphData · 28
Installing · 2
interface · 1, 2, 3, 53
internet · 3
K
key figure · 21
L
legend · 4
logo drawing · 45
M
median · 22
Microsoft Access · 24
moving average · 26
moving averages · 24, 27
MySql · 24
N
newPicture · 5, 16, 18, 33, 37, 49, 50
numeric information · 6
O
object constructors · 5
observationDrawing · 26
ODBC · 24
orientation · 6
P
package · 2
percentage price oscillator · 27
pictureDLL · 2, 24, 41
pictureDLL.dll · 2, 3
pictureDLL.hlp · 2, 3
pictureDLL.lib · 2
pie chart · 14, 41
PPO · 27
Price oscillators · 27
project · 2, 3, 49, 52
Prolog Development Center · 1
Q
quarter · 22, 24
quartile · 22
R
radar chart · 34
random · 49, 50
Relative Strength Index · 27, 42
removeSliceDisplacementForSlice · 15
RSI · 27
S
scatter plot · 16
setBarChartType · 8, 10, 49, 50
setDisplacementRatio · 15
setHistogramClassRange · 12
setInnerGraphAreaDimensions · 5, 15, 16, 18, 33, 37, 49, 50
setLogoAndMaskParameters/5 · 45
setLogoParameters/4 · 45
setLogoParameters/5 · 46
setSerieAreaColor · 18, 33
setSerieBar · 19
setSeriePoint · 20
setTextBox · 16, 17, 38
setTimeGraphSpace · 19
setTimeGraphType · 28
setTimeScale · 25
setValueScale · 25
showDataLabels · 7, 15
showLegend · 49
showRightMarginLabels · 30
special predicates · 3
Speed dial · 39
SQL database · 42
stacked · 8
Stacked Bar · 6
stacked horizontal chart · 8
stacked percentage bar · 6
stacked percentage chart · 8
stackedPercentage · 8
standard deviation · 30
stock exchange · 24
T
timers · 50
timeserie chart · 18
timeseries · 53
TR · 27
trend · 16, 26
trend line · 24, 26
TRIX · 28
true range · 27
V,W
vertical · 6, 10
vertical bar charts · 10
Visual Prolog · 1, 2, 5, 24
X
XY chart · 16, 18
[1] Any feedback related to the use and functionality of this graphics library is welcome (Email:
k.j.rastas@gmail.com ).
[2] Common here means, that the predicates have the same name in each class and which perform the same function.
[3] Actually these constructors in this DLL made with Visual Prolog 7.1 are predicates that call a constructor, because in DLL’s made with VP 7.1 it is not possible to use constructors.
[4] Only positive values can be used in stacked bars.
[5] These predicates can be used in all chart classes.