By refreshing the items within a grid sometimes it happen that the grid shows completely crazy:
That's how I update the data every time. The instance of the Grid stays the same:
dataProvider = new ListDataProvider<>(newItems);
grid.setItems(dataProvider);
Does someone have an idea whether I do something wrong or there is a bug within Vaadin?
Complete code:
if (!columnsIntialized) {
for (Method method : gridProperties) {
Column<T> column = grid.addColumn(data -> {
Object value = method.invoke(data);
return getFormattedValue(value, method.getReturnType());
});
String resourceKey = method.getDeclaredAnnotation(GridProperties.class).resourceKey();
column.setKey(resourceKey);
column.setHeader(AppResources.getString(resourceKey));
int width = method.getDeclaredAnnotation(GridProperties.class).width();
if (width == -1) {
column.setAutoWidth(true);
} else {
column.setWidth(width + "px");
}
}
columnsIntialized = true;
}
dataProvider = new ListDataProvider<>(items);
grid.setItems(dataProvider);
grid.recalculateColumnWidths();
Vaadin 22.0.3 is scheduled to be released on Monday with the fix.
I need to remove property in Text (setRise) , if t.setRise(+-) gets out of fields paper.
PdfDocument pdfDoc = new PdfDocument(pdfWriter);
Document doc = new Document(pdfDoc, PageSize.A5);
doc.setMargins(0,0,0,36);
for (int i = 0; i <50 ; i++) {
Text t = new Text("hello " + i);
if(i ==0){
t.setTextRise(7);
}
if(i==31){
t.setTextRise(-35);
}
Paragraph p = new Paragraph(t);
p.setNextRenderer(new ParagraphRen(p,doc));
p.setFixedLeading(fixedLeading);
doc.add(p);
}
doc.close();
}
class ParagraphRen extends ParagraphRenderer{
private float heightDoc;
private float marginTop;
private float marginBot;
public ParagraphRen(Paragraph modelElement, Document doc) {
super(modelElement);
this.heightDoc =doc.getPdfDocument().getDefaultPageSize().getHeight();
this.marginTop = doc.getTopMargin();
this.marginBot = doc.getBottomMargin();
}
#Override
public void drawChildren(DrawContext drawContext) {
super.drawChildren(drawContext);
Rectangle rect = this.getOccupiedAreaBBox();
List<IRenderer> childRenderers = this.getChildRenderers();
//check first line
if(rect.getTop()<=heightDoc- marginTop) {
for (IRenderer iRenderer : childRenderers) {
if (iRenderer.getModelElement().hasProperty(72)) {
Object property = iRenderer.getModelElement().getProperty(72);
float v = (Float) property + rect.getTop();
//check text more AreaPage
if(v >heightDoc){
iRenderer.getModelElement().deleteOwnProperty(72);
}
}
}
}
//check last line
if(rect.getBottom()-marginBot-rect.getHeight()*2<0){
for (IRenderer iRenderer : childRenderers) {
if (iRenderer.getModelElement().hasProperty(72)) {
Object property = iRenderer.getModelElement().getProperty(72);
//if setRise(-..) more margin bottom setRise remove
if(rect.getBottom()-marginBot-rect.getHeight()+(Float) property<0)
iRenderer.getModelElement().deleteOwnProperty(72);
}
}
}
}
}
Here i check if first lines with setRise more the paper area I remove setRise property.
And if last lines with serRise(-35) more then margin bottom I remove it.
But it doesn't work. Properties don't remove.
Your problem is as follows: drawChildren method gets called after rendering has been done. At this stage iText usually doesn't consider properties of any elements: it just places the element in its occupied area, which has been calculated before, at layout() stage.
You can overcome it with layout emulation.
Let's add all your paragraphs to a div rather than directly to the document. Then emulate adding this div to the document:
LayoutResult result = div.createRendererSubTree().setParent(doc.getRenderer()).layout(new LayoutContext(new LayoutArea(0, PageSize.A5)));
In the snippet above I've tried to layout our div on a A5-sized document.
Now you can consider the result of layout and change some elements, which will be then processed for real with Document#add. For example, to get the 30th layouted paragraph one can use:
((DivRenderer)result.getSplitRenderer()).getChildRenderers().get(30);
Some more tips:
split renderer represent the part of the content which iText can place on the area, overflow - the content which overflows.
I have created one graph which shows strings at x axis and dollars at y axis. I am able to see the values on graph but my data is too much to show on graph.
Graph is scrollable so I want to show minimun number of values on bar like below graph.
But now I am getting too much bars in graph like this:
This is my code:
public void setGraph() {
if (sessionData.getString("graphType", "").equals("d") || sessionData.getString("graphType", "").equals("m"))
{
int index = 0;
String[] dates = new String[totalOrdersList.size()];
mChart.setDrawBarShadow(false);
mChart.setDrawValueAboveBar(false);
mChart.getDescription().setEnabled(false);
mChart.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.lightGrey));
// mChart.setScaleEnabled(false);
// if more than 60 entries are displayed in the chart, no values will be
// drawn
mChart.setMaxVisibleValueCount(60);
// scaling can now only be done on x- and y-axis separately
mChart.setPinchZoom(false);
mChart.setDrawGridBackground(false);
// mChart.setDrawYLabels(false);
IndexAxisValueFormatter xAxisFormatter = new IndexAxisValueFormatter(dates);
XAxis xAxis = mChart.getXAxis();
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setDrawGridLines(false);
xAxis.setLabelCount(3);
xAxis.setValueFormatter(xAxisFormatter);
xAxis.setGranularity(1f);
com.github.mikephil.charting.formatter.IAxisValueFormatter custom = new MyAxisValueFormatter();
YAxis leftAxis = mChart.getAxisLeft();
leftAxis.setLabelCount(8, false);
leftAxis.setValueFormatter(custom);
leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
leftAxis.setSpaceTop(15f);
leftAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true)
YAxis rightAxis = mChart.getAxisRight();
rightAxis.setDrawGridLines(false);
rightAxis.setLabelCount(8, false);
rightAxis.setValueFormatter(custom);
rightAxis.setSpaceTop(15f);
rightAxis.setAxisMinimum(0f);
rightAxis.setEnabled(false);
// this replaces setStartAtZero(true)
Legend l = mChart.getLegend();
l.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
l.setOrientation(Legend.LegendOrientation.HORIZONTAL);
l.setDrawInside(false);
l.setForm(Legend.LegendForm.SQUARE);
l.setFormSize(9f);
l.setTextSize(11f);
l.setXEntrySpace(4f);
ArrayList<BarEntry> barEntries = new ArrayList<>();
for (Order o : totalOrdersList) {
dates[index] = o.getDate();
barEntries.add(new BarEntry(index, Float.parseFloat(o.getAmount())));
index++;
}
BarDataSet set1 = new BarDataSet(barEntries, "Months");
set1.setValues(barEntries);
set1.setColor(ContextCompat.getColor(getActivity(), R.color.orange));
ArrayList<IBarDataSet> dataSets = new ArrayList<IBarDataSet>();
dataSets.add(set1);
BarData data = new BarData(dataSets);
data.setValueTextSize(10f);
data.setBarWidth(0.9f);
mChart.setData(data);
mChart.animateXY(3000, 3000);
}
Please help.. Thank you..
I am coding a simple diagram that parses a .tsv file that has 6 columns and 9 rows. I am attempting to put some text on my diagram that is coloured according to the data existing in the third column. I am able to get all the colours on the screen, but for some reason, the text that ends up red is the text corresponding to the row (in the tsv file) BELOW the row whose text I want to be red. For example, while I want the Liberal candidate to have a fill of (200,60,60), the Parti Quebecois candidate appearing in the row below instead becomes red. Following, the New Dem party candidate ends up with the fill of (155,191,219). The code appears as follows:
PImage mapOfCanada; // background map
Premier[] premiers; // premiers data
void setup() {
size(800, 800);
// modified mapOfCanada from http://www.theblog.ca/map-canada
mapOfCanada = loadImage("bigmapofcanada.png");
// from http://en.wikipedia.org/wiki/List_of_current_Canadian_first_ministers
Table table = new Table("premiers.tsv");
int rows = table.getRowCount();
premiers = new Premier[rows];
// read through each row of the source data to populate our premiers array
for (int i=0; i<rows; i++) {
String name = table.getString(i, 0);
String province = table.getString(i, 1);
String party = table.getString(i, 2);
String imgFile = table.getString(i, 3);
PImage img = loadImage(imgFile);
float x = table.getFloat(i,4);
float y = table.getFloat(i,5);
premiers[i] = new Premier(name, province, party, img, x, y);
}
}
void draw() {
background(255);
// draw the background image with a light tint
tint(255, 25);
image(mapOfCanada, 0, 0);
// draw each premier
noTint();
for (Premier premier : premiers) {
image(premier.img, premier.x, premier.y);
}
//drawing lines for those premier images that cannot fit in the alloted province space
line(158,560,145,460); //Alberta
line(300,560,340,500); //Manitoba
line(650,365,670,410); //Newfoundland
line(750,385,710,535); //PEI
line(730,575,720,550); //Nova Scotia
line(670,595,680,560); //New Brunswick
//adding text labels
for (Premier premier : premiers) { //reading through the source data in a loop
textSize(10); //making the text size small yet readable
textAlign(CENTER); //making sure the text is centered above the image
text(premier.name, premier.x+50, premier.y-10); //positioning the text in relation to the x and y coordinates on the source data
{
String string1 = new String("Liberal");
String string2 = new String("Parti Quebecois");
String string3 = new String("New Democratic");
String string4 = new String ("Progressive Conservative");
String string5 = new String ("Saskatchewan Party");
String string6 = new String ("Yukon Party");
if (premier.party.equals("Liberal")) {
fill(200,60,60);
}
else if (premier.party.equals("Parti Quebecois")) {
fill(155,191,219);
}
else if (premier.party.equals("New Democratic")) {
fill(180,151,107);
}
else if(premier.party.equals("Progressive Conservative")) {
fill(96,104,250);
}
else if(premier.party.equals("Saskatchewan Party")) {
fill (107,180,119);
}
else if(premier.party.equals("Yukon Party")) {
fill (47,85,232);
}
else {
fill (0,0,0);
}
}
}
}
class Premier {
String name, province, party;
PImage img; // this is the thumbnail image
float x, y; // these are the coordinates for the thumbnail
Premier(String name, String province, String party, PImage img, float x, float y) {
this.name = name;
this.province = province;
this.party = party;
this.img = img;
this.x = x;
this.y = y;
}
}
Any help re: what I'm doing wrong would be much appreciated! I've edited the post to feature the full code.
Thank you!
Seems like a one off error in the loop that wraps the code that you have posted.
According to the description of an issue you're having, it may be related to indexing error - i.e. using 0-based indexing where it's actually 1-based or vice versa. But without the loop code and fill() code it will be very hard to pinpoint the problem.
I'm trying to create a graph for each user that is added into my app. This graph will display the day in this format 21 Dec 2012 on the x-axis and numbers from 30 to 30000. Say this is day 1, the user adds their calorie per hour burn rate and I want that info put into the graph. The next day, I want them to be able to calculate their calorie per hour rate and store that into the graph as well. Sort of like appending it to the graph.
public class Graph extends Activity{
private XYMultipleSeriesDataset mDataset;
private XYMultipleSeriesRenderer mRenderer;
List<double[]> values = new ArrayList<double[]>();
private GraphicalView mChartView;
private TimeSeries time_series;
String gotCal;
Double[] thisDou;
Double convert;
Date date;
// chart container
private LinearLayout layout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
layout = (LinearLayout) findViewById(R.id.chart);
SharedPreferences calStuff = getSharedPreferences("Calories", 0);
if (calStuff != null) {
gotCal = calStuff.getString("This Cal", null);
System.out.println(gotCal);
}
convert = Double.parseDouble(gotCal);
// create dataset and renderer
mDataset = new XYMultipleSeriesDataset();
mRenderer = new XYMultipleSeriesRenderer();
//mRenderer.setAxisTitleTextSize(16);
//mRenderer.setChartTitleTextSize(20);
//mRenderer.setLabelsTextSize(15);
//mRenderer.setLegendTextSize(15);
//mRenderer.setPointSize(3f);
XYSeriesRenderer r = new XYSeriesRenderer();
r.setColor(Color.GREEN);
r.setFillPoints(true);
r.setPointStyle(PointStyle.DIAMOND);
//r.fillPoints(true);
r.setFillBelowLine(true);
mRenderer.addSeriesRenderer(r);
mRenderer.setZoomButtonsVisible(true);
mRenderer.setXTitle("Date");
mRenderer.setYTitle("Calories Burned Per Hour");
//mRenderer.setClickEnabled(true);
r.setDisplayChartValues(true);
mRenderer.setSelectableBuffer(20);
mRenderer.setApplyBackgroundColor(true);
mRenderer.setBackgroundColor(Color.BLACK);
mRenderer.setGridColor(Color.CYAN);
//mRenderer.setChartTitle("LOOOOOL");
//mRenderer.setYLabels(12);
mRenderer.setPanEnabled(true, true);
//mRenderer.setPanEnabled(true);
time_series = new TimeSeries("test");
mDataset.addSeries(time_series);
fillData();
//time_series.add(date, Double.parseDouble(gotCal));
mChartView = ChartFactory.getTimeChartView(this, mDataset, mRenderer,
"dd MMM yyyy");
if (mChartView == null)
mChartView.repaint();
layout.addView(mChartView);
}
private void fillData() {
long value = new Date().getTime() - 3 * TimeChart.DAY;
for (int i = 0; i < gotCal.length(); i += convert) {
//date = new Date(value + i * TimeChart.DAY / 31);
time_series.add(new Date(value + i * TimeChart.DAY / 20), i);
}
}
It only works for one user, so when I try to access the graph from a different user which has different info, there's no graph, why is that? Also, how can I save the graph specifically to that user? Any help is highly appreciated, thank you.