Show newest inserted values in chart with TimeSeriesCollection when zoomed - jfreechart

I have such like a live chart realized with JFreeChart. The x-axis shows the time and there are several TimeSeriesCollections in the chart. If the a value is added to the TimeSeries the charts updates and shows the value only if it is not zoomed. Is there a possibility in the zoomed mode to show automatically new values (means to keep the zoom range and jump to the right).
Thanks
Oli

I found a possible solution:
this.chart.addChangeListener((ChartChangeEvent cce) -> {
if (scrollToNewest) {
Number max = DatasetUtilities.findMaximumDomainValue(this.plot.getDataset(0));
ValueAxis va = this.plot.getDomainAxis();
Range r = va.getRange();
double curUpperBound = r.getUpperBound();
double diff = max.doubleValue() - curUpperBound;
Range newR = new Range(r.getLowerBound() + diff, r.getUpperBound() + diff);
va.setRange(newR);
}
});

Related

Exporting TeeChart as Image

We are using TeeChart for .net (Version 4.1.2013.7302) in our forms application.
One of the charts in our product has Y Axis scrolling enabled. This makes some portion of chart visible at a given instance. To see other part of chart, user needs to use the scrollbar. A separate scrollbar is used instead of axis scrollbar, as there will be a adjoining grid control and; both chart & grid are expected to be scrolled using common scrollbar. Following is the sample form image depicting the scenario:
We are using TeeChart's export functionality to export this chart as an image. But since chart has scrolling enabled (i.e. minimum of chart is not visible by default); TeeChart is exporting only visible portion of Chart, and not the entire chart. Following is the image of chart exported:
Please suggest if there exists any way to export the entire chart as an image, and not just the visible portion of it?
Thanks in Advance.
Here's a fuller version of Yeray's code that fills out the exported image to the size of the full, mainly non-visible chart:
private void button11_Click(object sender, EventArgs e)
{
//get zoomed axis min maxes
double xtmpMin = tChart1.Axes.Bottom.Minimum;
double xtmpMax = tChart1.Axes.Bottom.Maximum;
double ytmpMin = tChart1.Axes.Left.Minimum;
double ytmpMax = tChart1.Axes.Left.Maximum;
//how many pixels are plotted for the axes' ranges
int yPixelRange = tChart1.Axes.Left.CalcPosValue(tChart1.Axes.Left.Minimum)-tChart1.Axes.Left.CalcPosValue(tChart1.Axes.Left.Maximum);
int xPixelRange = tChart1.Axes.Bottom.CalcPosValue(tChart1.Axes.Bottom.Maximum) - tChart1.Axes.Bottom.CalcPosValue(tChart1.Axes.Bottom.Minimum);
//get the chart header/footer space to re-apply to chart
int yMargins = tChart1.Bounds.Height - yPixelRange;
int xMargins = tChart1.Bounds.Width - xPixelRange;
//how many pixels are we getting per axis scale
double pixelsPerYAxisInt = yPixelRange / (ytmpMax - ytmpMin);
double pixelsPerXAxisInt = xPixelRange / (xtmpMax - xtmpMin);
//what increment are we at. Note. To get this back we may need to mod font size, min separation
double yInc = tChart1.Axes.Left.CalcIncrement;
double xInc = tChart1.Axes.Bottom.CalcIncrement;
//now reset auto axes before plotting full chart. Could use other criteria here
tChart1.Axes.Left.Automatic = true;
tChart1.Axes.Bottom.Automatic = true;
//Repaint full Chart (necessary for positioning calcs)
tChart1.Draw();
//set increments on full scales (note Chart will try to set them,
//but if it can't you have the last word with label separation, font size, etc)
tChart1.Axes.Left.Increment = yInc;
tChart1.Axes.Bottom.Increment = xInc;
//dimension chart for export
double fullYRange = tChart1.Axes.Left.Maximum - tChart1.Axes.Left.Minimum;
double fullXRange = tChart1.Axes.Bottom.Maximum - tChart1.Axes.Bottom.Minimum;
int fullYSize = (int)((pixelsPerYAxisInt * fullYRange) + yMargins);
int fullXSize = (int)((pixelsPerXAxisInt * fullXRange) + xMargins);
//setup and export image
tChart1.Export.Image.PNG.Width = fullXSize;
tChart1.Export.Image.PNG.Height = fullYSize;
tChart1.Export.Image.PNG.Save(#"c:\mypath\chart.png");
//reset screen chart to where it was
tChart1.Axes.Bottom.SetMinMax(xtmpMin, xtmpMax);
tChart1.Axes.Left.SetMinMax(ytmpMin, ytmpMax);
}
There are many ways to optimise that code, Axis does have an iRange that I haven't tried, and some of the steps can be brought together but I hope they are clear and useful and give you something of what you're looking for.
You can manually adjust your axis scale, export your chart and then restore your axis. Ie (if 0 - 4.25 in the bottom axis is the "entire chart"):
double tmpMin = tChart1.Axes.Bottom.Minimum;
double tmpMax = tChart1.Axes.Bottom.Maximum;
tChart1.Axes.Bottom.SetMinMax(0, 4.25);
tChart1.Export.Image.JPEG.Save(myFileName);
tChart1.Axes.Bottom.SetMinMax(tmpMin, tmpMax);

JFree: Stacked area chart continue painting after last point and before first

I'd like to get stacked area chart with beginning chart in first point and completing in last point like here:
But picture is out of point's range like here:
How can I make stacked area starting exactly from the first point and completing exactly in the last point?
(Different manipulations with dateAxis.setLowerMargin(-0.075D) dateAxis.setUpperMargin(-0.075D) are not helping)
JFreeChart stackedAreaChart = ChartFactory.createStackedAreaChart(name, X_AXIS_TITLE, Y_AXIS_TITLE, dataset,
PlotOrientation.VERTICAL, true, true, false);
CategoryPlot plot = stackedAreaChart.getCategoryPlot();
CategoryAxis dateAxis = plot.getDomainAxis();
dateAxis.setLowerMargin(-0.075D);
dateAxis.setUpperMargin(-0.075D);
dateAxis.setCategoryMargin(0.0D);
StackArea renderer = new StackArea();
dateAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);
...
plot.setRenderer(renderer);
renderer.setBaseItemLabelGenerator(new LabelGenerator());
renderer.setBaseItemLabelsVisible(true);
...
plot.setRenderer(renderer);
plot.setAxisOffset(new RectangleInsets(5.0, 1.0, 5.0, 1.0));
ValueAxis rangeAxis = plot.getRangeAxis();
NumberAxis axis2 = new NumberAxis(Y_AXIS_TITLE);
axis2.setAutoRangeIncludesZero(false);
axis2.setLabelFont(rangeAxis.getLabelFont());
axis2.setTickLabelFont(rangeAxis.getTickLabelFont());
...
plot.setRangeAxis(1, axis2);
plot.setRangeAxisLocation(1, AxisLocation.TOP_OR_RIGHT);
plot.mapDatasetToRangeAxes(0, Arrays.asList(0, 1));
setAxisColor(rangeAxis, axisColor);
rangeAxis.setTickLabelPaint(ColorUtils.VaadinAWTColor(params.getColorParams().getFontSlideColor()));
rangeAxis.setLabelPaint(ColorUtils.VaadinAWTColor(params.getColorParams().getFontSlideColor()));
You can get the effect you want by using the default margins on the chart's CategoryAxis, i.e. don't change them as the demo does.
CategoryAxis categoryaxis = categoryplot.getDomainAxis();
//categoryaxis.setLowerMargin(0.0D);
//categoryaxis.setUpperMargin(0.0D);
//categoryaxis.setCategoryMargin(0.0D);
I need stacked area to start for the first point—exactly from C1 in your picture, not earlier, and stop on C8, not later.
You may need to adjust the values to get closer to the desired result.
categoryaxis.setLowerMargin(-0.075D);
categoryaxis.setUpperMargin(-0.075D);
categoryaxis.setCategoryMargin(0.0D);

xy plot of renderer label points(data points) are overlapping with line chart of TimeSeriesChart of jfreechart

I am using Jfreechart API 1.0.8 to generate the TimeSeriesChart(line chart).
when I am generating the chart, i am facing the problem of overlapping.
Here I am trying to display the rendered points(graph rendered points), by using XYLineAndShapeRenderer with StandardXYItemLabelGenerator.
When the points are displayed, the data-point is overlapping with the generated line chart (graph).
I am taking X-Axis as time, and y-Axis as revenue of organization, and i am using line chart here.
I'm displaying the points as discussed below.
By using "renderer.setBasePositiveItemLabelPosition" method, globally i am setting the position of graph points(data points) inside the xyplot rendered chart while considering the rendered "ItemLabelAnchor".
I am sending my sample code here:
chart = ChartFactory.createTimeSeriesChart("", "", "", newxyseries, false, true, false);
renderer = new XYLineAndShapeRenderer();
renderer = (XYLineAndShapeRenderer) chart.getXYPlot().getRenderer();
renderer.setBaseItemLabelGenerator(new StandardXYItemLabelGenerator("{2}", monthDate, formatSymbol));
renderer.setBaseItemLabelsVisible(true);
renderer.setBasePositiveItemLabelPosition(new ItemLabelPosition(ItemLabelAnchor.OUTSIDE3, TextAnchor.TOP_RIGHT));
chart.getXYPlot().setRenderer(renderer);
But when I am generating the graph chart using Ms-office of Excel tools, there is no problem of overlapping of labels, the points are displayed in an effective manner without any overlapping.
JFreeChart doesn't do any overlap detection for item labels. It would be a great feature to have, but nobody has written the code to do it.
you have to refrain the labels to get overlap by define your own algo or logic because as the graph keep growing sooner the labels will start to get overlap.
the key is to make some or alternative labels transparent so that no overlapping occur
For example in the following P.O.C, only 35 labels will be drawn but the tick of graphs will remai same just the labels will reduce
CategoryAxis domainAxis = plot.getDomainAxis();
CategoryLabelPositions pos = domainAxis.getCategoryLabelPositions();
double size = plot.getCategories().size();
double occurence = Math.ceil(plot.getCategories().size() / 20);
double interval = Math.ceil(plot.getCategories().size() / 20);
for (int i = 1; i <= plot.getCategories().size(); i++) {
if (plot.getCategories().size() > 35) {
if(plot.getCategories().size()>35 && plot.getCategories().size()<250) {
if(i%8==0){
String cat_Name = (String) plot.getCategories().get(i-1);
} else{
String cat_Names = (String) plot.getCategories().get(i-1);
domainAxis.setTickLabelPaint(cat_Names, new Color(0,0,0,0));
}
}else if(plot.getCategories().size()>250){
[![enter image description here][1]][1]
if (i == occurence) {
String cat_Name = (String) plot.getCategories().get(i - 1);
if (occurence + interval >= size) {
// occurence=size;
} else {
occurence = occurence + interval;
}
} else {
String cat_Names = (String) plot.getCategories().get(i - 1);
domainAxis.setTickLabelPaint(cat_Names, new Color(0, 0, 0, 0));
}
}
}
Below line will make label transparent
domainAxis.setTickLabelPaint(cat_Names, new Color(0,0,0,0));

JFreechart: Displaying X axis with values after specific units

I am using jfreechart for displaying line graph.Now, on X axis it shows value for every (x,y) pair on chart.As a result the X axis has huge amount of values getting overlapped.I want to display few values eg after every 5 units or something like that.How is this possible using Jfreechart.
Before the NumberAxis of the chart's plot is drawn, its tick marks are refreshed. The result is a List that includes a NumberTick object for each tick mark of the axis.
By overriding the function NumberAxis.refreshTicks you can control how and if the marks will be shown.
For example, in the following code I get all tick marks and iterate through them looking for TickType.MAJOR. If the value of a major tick mark is not dividable by 5, it gets replaced by a minor tick mark.
As a result, only values dividable by 5 will be shown with their text label.
XYPlot plot = (XYPlot) chart.getPlot();
NumberAxis myAxis = new NumberAxis(plot.getDomainAxis().getLabel()) {
#Override
public List refreshTicks(Graphics2D g2, AxisState state,
Rectangle2D dataArea, RectangleEdge edge) {
List allTicks = super.refreshTicks(g2, state, dataArea, edge);
List myTicks = new ArrayList();
for (Object tick : allTicks) {
NumberTick numberTick = (NumberTick) tick;
if (TickType.MAJOR.equals(numberTick.getTickType()) &&
(numberTick.getValue() % 5 != 0)) {
myTicks.add(new NumberTick(TickType.MINOR, numberTick.getValue(), "",
numberTick.getTextAnchor(), numberTick.getRotationAnchor(),
numberTick.getAngle()));
continue;
}
myTicks.add(tick);
}
return myTicks;
}
};
plot.setDomainAxis(myAxis);

Piemenu for WPF

Are there any working piemenu controls for WPF?
I've found this in my favorite , you can take a look at :
This
have a nice day.
This question is probably long dead, but just a note that the control Thomas M posted, while awesome, has a major issue: You need to mouse over and click on the actual item instead of the pie slice. This means that the pie slices are not completely adjacent and IMO defeats a lot of the clickability (Frits's law) advantages of the control. So while it looks like a pie menu, it really just positions everything radially.
I ended up doing this:
private static Path makeDeliciousKeyLimePieSlice(double innerRadius, double outerRadius,
double startAngle, double endAngle, Vector ofs)
{
Point p1 = new Point(Math.Cos(endAngle) * innerRadius, Math.Sin(endAngle) * innerRadius) + ofs;
Point p2 = new Point(Math.Cos(startAngle) * innerRadius, Math.Sin(startAngle) * innerRadius) + ofs;
Point p3 = new Point(Math.Cos(startAngle) * outerRadius, Math.Sin(startAngle) * outerRadius) + ofs;
Point p4 = new Point(Math.Cos(endAngle) * outerRadius, Math.Sin(endAngle) * outerRadius) + ofs;
PathFigure fig = new PathFigure(p1, new PathSegment[] {
new ArcSegment(p2, new Size(innerRadius, innerRadius), endAngle - startAngle, false, SweepDirection.Counterclockwise, true),
new LineSegment(p3, true),
new ArcSegment(p4, new Size(outerRadius, outerRadius), startAngle - endAngle, false, SweepDirection.Clockwise, true),
}, true).GetAsFrozen();
return new Path { Data = new PathGeometry(new[] { fig }).GetAsFrozen() };
}
This will create a "slice" of the pie. You can style this how you want if you want a true pie menu. Another option is to make it transparent (set the fill to Brushes.Transparent; it must have a fill to be hit-test visible), which looks good for radial context menus. Here's my WIP after about half an hour's work (I know the spacing sucks):
alt text http://public.blu.livefilestore.com/y1pdW5ibqWquKGosMSch9C5KmOTKkiZ35mAI7iFKKUKf3cm7TGSquXhO8hkkL9Ln6Z3tKn74u67C27Qb_AIWQxzhg/radial.png?psid=1
EDIT: ah; the cursor doesn't appear in the shot -- basically, if you use the path overlay, you can have the mouse outside the actual control but still have it highlighted.
This control needs a bit of work still but it's a great starting point and supports multiple levels of items. (ie: a hierarchy) Check it out here

Resources