Devexpress: how to add points to Chart Control at runtime? - winforms

i'm trying to build a telemetry software using Winform and Devexpress library. Specifically i'm working on a Line Chart Control and what i would like to do is to configure the chart so that it is able to display a data changing in real time.
The graph is generated reading some external sensors that send informations at a rate of 10 values per second.
This is my code for initialize the chart:
series1 = new Series("test test", ViewType.Line);
chartControl1.Series.Add(series1);
series1.ArgumentScaleType = ScaleType.Numerical;
((LineSeriesView)series1.View).LineMarkerOptions.Kind = MarkerKind.Triangle;
((LineSeriesView)series1.View).LineStyle.DashStyle = DashStyle.Dash;
((XYDiagram)chartControl1.Diagram).EnableAxisXZooming = true;
chartControl1.Legend.Visibility = DefaultBoolean.False;
chartControl1.Titles.Add(new ChartTitle());
chartControl1.Titles[0].Text = "A Line Chart";
chartControl1.Dock = DockStyle.Fill;
And this is the one that add a new point and remove the first point available so that the amount of points in my chart is always the same (after a minimum amount of points is reached) and it keeps updating itself displaying the last X seconds of values and discarding the old values.
series1.Points.RemoveRange(0, 1);
series1.Points.Add(new SeriesPoint(time, value));
...
AxisXRange.SetMinMaxValues(newFirstTime, time);
AxisRange is the following
Range AxisXRange
{
get
{
SwiftPlotDiagram diagram = chartControl1.Diagram as SwiftPlotDiagram;
if (diagram != null)
return diagram.AxisX.VisualRange;
return null;
}
}
**The problem ** is that this code works temporarily. After some seconds, the chart stop working and a big red cross is displayed over it.
Is there something that i'm missing with its configuration?
Do you know any better way to realize my task?
Any help would be appreciated.
Thank you

I think you doing it nearly right. Devexpress has an Article about RealTime-Charts. They doing it the same way but using a timer for updating the data. Maybe this would fix your painting problems.

Related

Displaying Parse Data to ContainerList

I want to display data from Parse in a list from GamesScores class using Container in Codename One, this is what I've tried so far and it's not showing anything nor giving any errors:
Container container = findListCont();
container.setLayout(BoxLayout.y());
container.setScrollableY(true);
ParseQuery<ParseObject> query = ParseQuery.getQuery("GameScore");
List<ParseObject> results = (List<ParseObject>) query.find();
System.out.println("Size: " + results.size());
container.addComponent(results, f);
Please help me out, I'm a new in Codename One. If there tutorials on it, please share or anything to help me achieve the desired results.
I'm actually shocked this isn't failing. You are using the add constraint to place the object result as a constraint and you add the form object into the container...
You need to loop over the results and convert them to components to add into the layout. It also seems that you are using the old GUI builder which I would recommend against.
Generally something like this rough pseudo code should work assuming you are using a box Y layout:
for(ParseObject o : results) {
MultiButton mb = new MultiButton(o.getDisplayValue());
f.add(mb);
}
f.revalidate();

FSharpChart with Windows.Forms very slow for many points

I use code like the example below to do basic plotting of a list of values from F# Interactive. When plotting more points, the time taken to display increases dramatically. In the examples below, 10^4 points display in 4 seconds whereas 4.10^4 points take a patience-testing 53 seconds to display. Overall it's roughly as if the time to plot N points is in N^2.
The result is that I'll probably add an interpolation layer in front of this code, but
1) I wonder if someone who knows the workings of FSharpChart and Windows.Forms could explain what is causing this behaviour? (The data is bounded so one thing that seems to rule out is the display needing to adjust scale.)
2)Is there a simple remedy other than interpolating the data myself?
let plotl (f:float list) =
let chart = FSharpChart.Line(f, Name = "")
|> FSharpChart.WithSeries.Style(Color = System.Drawing.Color.Red, BorderWidth = 2)
let form = new Form(Visible = true, TopMost = true, Width = 700, Height = 500)
let ctl = new ChartControl(chart, Dock = DockStyle.Fill)
form.Controls.Add(ctl)
let z1 = [for i in 1 .. 10000 do yield sin(float(i * i))]
let z2 = [for i in 1 .. 20000 do yield sin(float(i * i))]
plotl z1
plotl z2
First of all, FSharpChart is a name used in an older version of the library. The latest version is called F# Charting, comes with a new documentation and uses just Chart.
To answer your question, Chart.Line and Chart.Points are quite slow for large number of points. The library also has Chart.FastLine and Chart.FastPoints (which do not support as many features, but are faster). So, try getting the latest version of F# Charting and using the "Fast" version of the method.

Need to figure out how to use DeepZoomTools.dll to create DZI

I am not familiar with .NET coding.
However, I must create DZI sliced image assets on a shared server and am told that I can instantiate and use DeepZoomTools.dll.
Can someone show me a very simple DZI creation script that demonstrates the proper .NET coding technique? I can embellish as needed, I'm sure, but don't know where to start.
Assuming I have a jpg, how does a script simply slice it up and save it?
I can imagine it's only a few lines of code. The server is running IIS 7.5.
If anyone has a simple example, I'd be most appreciative.
Thanks
I don't know myself, but you might ask in the OpenSeadragon community:
https://github.com/openseadragon/openseadragon/issues
Someone there might know.
Does it have to be DeepZoomTools.dll? There are a number of other options for creating DZI files. Here are a few:
http://openseadragon.github.io/examples/creating-zooming-images/
Example of building a Seadragon Image from multiple images.
In this, the "clsCanvas" objects and collection can pretty much be ignored, it was an object internal to my code that was generating the images with GDI+, then putting them on disk. The code below just shows how to get a bunch of images from file and assemble them into a zoomable collection. Hope this helps someone :-).
CollectionCreator cc = new CollectionCreator();
// set default values that make sense for conversion options
cc.ServerFormat = ServerFormats.Default;
cc.TileFormat = ImageFormat.Jpg;
cc.TileSize = 256;
cc.ImageQuality = 0.92;
cc.TileOverlap = 0;
// the max level should always correspond to the log base 2 of the tilesize, unless otherwise specified
cc.MaxLevel = (int)Math.Log(cc.TileSize, 2);
List<Microsoft.DeepZoomTools.Image> aoImages = new List<Microsoft.DeepZoomTools.Image>();
double fLeftShift = 0;
foreach (clsCanvas oCanvas in aoCanvases)
{
//viewport width as a function of this canvas, so the width of this canvas is 1
double fThisImgWidth = oCanvas.MyImageWidth - 1; //the -1 creates a 1px overlap, hides the seam between images.
double fTotalViewportWidth = fTotalImageWidth / fThisImgWidth;
double fMyLeftEdgeInViewportUnits = -fLeftShift / fThisImgWidth; ; //please don't ask me why this is a negative numeber
double fMyTopInViewportUnits = -fTotalViewportWidth * 0.3;
fLeftShift += fThisImgWidth;
Microsoft.DeepZoomTools.Image oImg = new Microsoft.DeepZoomTools.Image(oCanvas.MyFileName.Replace("_Out_Tile",""));
oImg.ViewportWidth = fTotalViewportWidth;
oImg.ViewportOrigin = new System.Windows.Point(fMyLeftEdgeInViewportUnits, fMyTopInViewportUnits);
aoImages.Add(oImg);
}
// create a list of all the images to include in the collection
cc.Create(aoImages, sMasterOutFile);

Printing text in Silverlight that measures larger than page

I have a silverlight application that allows people to enter into a notes field which can be printed, the code used to do this is:
PrintDocument pd = new PrintDocument();
Viewbox box = new Viewbox();
TextBlock txt = new TextBlock();
txt.TextWrapping = TextWrapping.Wrap;
Paragraph pg = new Paragraph();
Run run = new Run();
pg = (Paragraph)rtText.Blocks[0];
run = (Run)pg.Inlines[0];
txt.Text = run.Text;
pd.PrintPage += (s, pe) =>
{
double grdHeight = pe.PrintableArea.Height - (pe.PageMargins.Top + pe.PageMargins.Bottom);
double grdWidth = pe.PrintableArea.Width - (pe.PageMargins.Left + pe.PageMargins.Right);
txt.Width = grdWidth;
txt.Height = grdHeight;
pe.PageVisual = txt;
};
pd.Print(lblTitle.Text);
This simply prints the content of the textbox on the page however some of the notes are spanning larger than the page itself causing it to be cut off. How can I change my code to measure the text and add more pages OR is there a better way to do the above where it will automatically create multiple pages for me?
There are several solutions to your problem, all of them under "Multiple Page Printing Silverlight" on Google. I was having a similar problem and tried most of them. The only one that worked for me was this one:
http://www.codeproject.com/Tips/248553/Silverlight-converting-to-image-and-printing-an-UI
But honestly you should look at Google first and see whether there are better solutions to your specific problem.
Answering your question, there is a flag called HasMorePages that indicates you need a new page. Just type pe.HasMorePages and you will see.
Hope it helps
First you need to work out how many pages are needed
Dim pagesNeeded As Integer = Math.Ceiling(gridHeight / pageHeight) 'gets number of pages needed
Then once the first page has been sent to the printer, you need to move that data out of view and bring the new data into view ready to print. I do this by converting the whole dataset into an image/UI element, i can then adjust Y value accordingly to bring the next set of required data on screen.
transformGroup.Children.Add(New TranslateTransform() With {.Y = -(pageIndex * pageHeight)})
Then once the number of needed pages is reached, tell the printer to stop
'sets if there is more than 1 page to print
If pagesLeft <= 0 Then
e.HasMorePages = False
Exit Sub
Else
e.HasMorePages = True
End If
Or if this is too much work, you can simply just scale all the notes to fit onto screen. Again probably by converting to UI element.
Hope this helps

AnyChart 8.1.0 - Resource Gantt - Move periods from one resource to another

I am using the AnyChart 8.1.0 resource Gantt (anychart.ganttResource()) to show and edit planned data (car reservations).
I can edit / move a reservation horizontally to change the time / period of a reservation and also drag the start and/or enddate. But I would like to move a reservation from one car (row) to another - very similar to moving a task from one person to another.
Is that possible - and how?
Thanks!
Roel
I'm having the same issue, and as far as I can see you can use
tree.listen("treeItemMove", function (e) {
// do your stuff
});
Unfortunally, I think this will only work, if you only have one reservation in each row. If you have more than one, all reservations will be moved.
So far I haven't found a solution to get one reservation and move it to another row. But I hope it may help you in the rigth direction..
EDIT:
I have contacted Anychart support and asked if there is a way to move one period from one (child-) row and create a new row under another parent?
Here is the answer:
the current version of AnyGantt 8.1.0 doesn't provide this feature as an out-of-the-box or even with the extra code.
But you can modify the dataTree from the code as you need. This provides full control under the data, but without mouse interactivity.
That's too bad. I can manipulate the tree - even one period, using this code to delete and add a period. You can update a period as well, code should be similar.
function deletePeriod( pItemId, pPeriodId ){
var item = treeData.search("id", pItemId);
var periods = item.get("periods")
var i = periods.findIndex(function(e){ return e.id == pPeriodId; });
periods.splice(i,1);
item.set('periods', periods);
treeData.addChildAt( item, treeData.indexOfChild(item) );
}
and
function addPeriod( pItemId, pPeriodId, start, end){
var period = {
"id": pPeriodId,
"start": start,
"end": end,
"name": "Whatever name you want"
};
var item = treeData.search("id", pItemId);
var periods = item.get("periods");
periods.push(period);
item.set('periods', periods);
treeData.addChildAt( item, treeData.indexOfChild(item) );
}

Resources