I'm loading in Assets from the main game class which extends the libgdx class game. In the create() method of that class i'm calling Assets.loadAtlas(); and this calls:
public static void loadAtlas() {
String textureFile = "data/rubenSprite.txt";
myTextures = new TextureAtlas(Gdx.files.internal(textureFile));
TextureRegion[] walkRightFrames = new TextureRegion[4];
for (int i = 0; i < 5; i++)
{
walkRightFrames[i] = myTextures.findRegion("wframe" + (i + 1));
}
rubenWalkRight = new Animation(0.2f, walkRightFrames[0], walkRightFrames[1],
walkRightFrames[2], walkRightFrames[3], walkRightFrames[4]);
TextureRegion[] walkLeftFrames = new TextureRegion[4];
for (int i = 0; i < 5; i++)
{
walkLeftFrames[i] = new TextureRegion(walkRightFrames[i]);
walkLeftFrames[i].flip(true,false);
}
rubenWalkLeft = new Animation(0.2f, walkLeftFrames[0], walkLeftFrames[1],
walkLeftFrames[2], walkLeftFrames[3], walkLeftFrames[4]);
TextureRegion[] idleRightFrames = new TextureRegion[3];
for (int i = 0; i < 4; i ++)
{
idleRightFrames[i] = myTextures.findRegion("iframe" + (i + 1));
}
rubenIdleRight = new Animation(0.2f, idleRightFrames[0], idleRightFrames[1],
idleRightFrames[2], idleRightFrames[3]);
TextureRegion[] idleLeftFrames = new TextureRegion[3];
for (int i = 0; i < 4; i++)
{
idleLeftFrames[i] = new TextureRegion(idleRightFrames[i]);
idleLeftFrames[i].flip(true,false);
}
rubenIdleLeft = new Animation(0.2f, idleLeftFrames[0], idleLeftFrames[1],
idleLeftFrames[2], idleLeftFrames[3]);
TextureRegion[] jumpRightFrames = new TextureRegion[4];
for (int i = 0; i < 5; i++)
{
jumpRightFrames[i] = myTextures.findRegion("jframe" + (i + 1));
}
rubenJumpRight = new Animation(0.2f, jumpRightFrames[0], jumpRightFrames[1],
jumpRightFrames[2], jumpRightFrames[3], jumpRightFrames[4]);
TextureRegion[] jumpLeftFrames = new TextureRegion[4];
for (int i = 0; i < 5; i++)
{
jumpLeftFrames[i] = new TextureRegion(jumpRightFrames[i]);
jumpLeftFrames[i].flip(true,false);
}
rubenJumpLeft = new Animation(0.2f, jumpLeftFrames[0], jumpLeftFrames[1],
jumpLeftFrames[2], jumpLeftFrames[3], jumpLeftFrames[4]);
TextureRegion fallRight = new TextureRegion();
fallRight = myTextures.findRegion("fall");
rubenFallRight = new Animation(0f, fallRight);
TextureRegion fallLeft = new TextureRegion(fallRight); ;
fallLeft.flip(true,false);
rubenFallLeft = new Animation(0f, fallLeft);
}
From the tutorials I've looked at, it seems correct to me. I've given the player states and drawn the animations within them inside the mainRenderer depending on the state the player is in. This code seems fine also:
private void renderRuben () {
TextureRegion keyFrame;
switch (world.ruben.getState()) {
case Ruben.RUBEN_STATE_HIT:
keyFrame = Assets.bobHit;
break;
case Ruben.RUBEN_STATE_WALKING:
if (Ruben.facingRight == true)
{
keyFrame = Assets.rubenWalkRight.getKeyFrame(world.ruben.getStateTime(), Animation.ANIMATION_NONLOOPING);
break;
}
else
{
keyFrame = Assets.rubenWalkLeft.getKeyFrame(world.ruben.getStateTime(), Animation.ANIMATION_NONLOOPING);
break;
}
case Ruben.RUBEN_STATE_FALL:
if (Ruben.facingRight == true) {
keyFrame = Assets.rubenFallRight.getKeyFrame(world.ruben.getStateTime(), Animation.ANIMATION_NONLOOPING);
break;
}
else {
keyFrame = Assets.rubenFallLeft.getKeyFrame(world.ruben.getStateTime(), Animation.ANIMATION_NONLOOPING);
break;
}
case Ruben.RUBEN_STATE_JUMP:
if (Ruben.facingRight == true) {
keyFrame = Assets.rubenJumpRight.getKeyFrame(world.ruben.getStateTime(), Animation.ANIMATION_NONLOOPING);
break;
}
else {
keyFrame = Assets.rubenJumpRight.getKeyFrame(world.ruben.getStateTime(), Animation.ANIMATION_NONLOOPING);
break;
}
case Ruben.RUBEN_STATE_IDLE:
default:
if (Ruben.facingRight == true) {
keyFrame = Assets.rubenIdleRight.getKeyFrame(world.ruben.getStateTime(), Animation.ANIMATION_LOOPING);
}
else {
keyFrame = Assets.rubenIdleRight.getKeyFrame(world.ruben.getStateTime(), Animation.ANIMATION_LOOPING);
}
}
float side = world.ruben.getVelocity().x < 0 ? -1 : 1;
if (side < 0)
batch.draw(keyFrame, world.ruben.position.x + 0.5f, world.ruben.position.y - 0.5f, side * Ruben.RUBEN_WIDTH, Ruben.RUBEN_HEIGHT);
else
batch.draw(keyFrame, world.ruben.position.x - 0.5f, world.ruben.position.y - 0.5f, side * Ruben.RUBEN_WIDTH, Ruben.RUBEN_HEIGHT);
}
I packed the Atlases using TexturePacker GUI and saved the png and txt file into /assets/data folder.
The overall project has no errors, it just says 'application not responding' when it opens up in the emulator. What am i doing wrong?
Create Method for game class:
public class GameView extends Game {
// used by all screens
public SpriteBatch batcher;
#Override
public void create () {
batcher = new SpriteBatch();
Settings.load();
Assets.loadAtlas();
setScreen(new MainMenuScreen(this));
}
}
Overall it was something to do with the Emulator not the application, The emulator wasn't compatible with Open GL ES 2.0, So I downloaded GenyMotion and now it works fine.
http://www.genymobile.com/en/
Related
I'm currently trying to make a 2D game using VSCode, I am on a MacBook, and keep getting this error whenever trying to load the map. My map for some reason will only appear as all white, without the character, and I get this error in the terminal:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: Index 12 out of bounds for length 12
at tile.TileManager.draw(TileManager.java:102)
at main.GamePanel.paintComponent(GamePanel.java:94)
Here is my TileManager class
package tile;
import main.GamePanel;
import java.io.IOException;
import javax.imageio.ImageIO;
import java.awt.Graphics2D;
import java.io.InputStream;
import java.io.*;
public class TileManager {
GamePanel gp;
Tile[] tile;
int mapTileNum[][];
public TileManager(GamePanel gp) {
this.gp = gp;
tile = new Tile[10];
mapTileNum = new int[gp.maxWorldCol][gp.maxScreenRow];
getTileImage();
loadMap("res/maps/world01.txt");
}
public void getTileImage() {
System.out.println("image loading started");
try {
this.tile[0] = new Tile();
this.tile[0].image = ImageIO.read(new FileInputStream("res/tiles/grass01.png"));
this.tile[1] = new Tile();
this.tile[1].image = ImageIO.read(new FileInputStream("res/tiles/wall.png"));
this.tile[2] = new Tile();
this.tile[2].image = ImageIO.read(new FileInputStream("res/tiles/water01.png"));
this.tile[3] = new Tile();
this.tile[3].image = ImageIO.read(new FileInputStream("res/tiles/earth.png"));
this.tile[4] = new Tile();
this.tile[4].image = ImageIO.read(new FileInputStream("res/tiles/tree.png"));
this.tile[5] = new Tile();
this.tile[5].image = ImageIO.read(new FileInputStream("res/tiles/sand.png"));
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Image loading finished");
}
public void loadMap(String filePath) {
try {
InputStream is = getClass().getResourceAsStream(filePath);
BufferedReader br = new BufferedReader(new InputStreamReader(is));
int col = 0;
int row = 0;
while (col < gp.maxWorldCol && row < gp.maxWorldRow) {
String line = br.readLine();
while (col < gp.maxWorldCol) {
String numbers[] = line.split(" "); // splits up strings at space
int num = Integer.parseInt(numbers[col]);
mapTileNum[col][row] = num;
col++;
}
if (col == gp.maxWorldCol) {
col = 0;
row++;
}
}
br.close();
} catch (Exception e) {
}
}
public void draw(Graphics2D g2) {
int worldCol = 0;
int worldRow = 0;
while (worldCol < gp.maxWorldCol && worldRow < gp.maxWorldRow) {
int tileNum = mapTileNum[worldCol][worldRow];
int worldX = worldCol * gp.tileSize;
int worldY = worldRow * gp.tileSize;
int screenX = worldX - gp.player.worldX + gp.player.screenX;
int screenY = worldY - gp.player.worldY + gp.player.screenY;
if (worldX + gp.tileSize > gp.player.worldX - gp.player.screenX &&
worldX - gp.tileSize < gp.player.worldX + gp.player.screenX &&
worldY + gp.tileSize > gp.player.worldY - gp.player.screenY &&
worldY - gp.tileSize < gp.player.worldY + gp.player.screenY) {
g2.drawImage(tile[tileNum].image, screenX, screenY, gp.tileSize, gp.tileSize, null);
}
g2.drawImage(tile[tileNum].image, screenX, screenY, gp.tileSize, gp.tileSize, null);
worldCol++;
if (worldCol == gp.maxWorldCol) {
worldCol = 0;
worldRow++;
}
}
}
}
In the public tile manager call the getTileImage method to initialize the tiles
public TileManager(GamePanel gp) {
this.gp = gp;
tile = new Tile[10];
getTileImage(); // Call the getTileImage method to initialize the tiles
}
I have a tensorflow lite model which use,
input is {1,320,320,3}
output array dataType is {FLOAT32,FLOAT32,INT32}.
Interpreter#runForMultipleInputsOutputs crashed when resized the input to {1,224,320,3}.
My tensorflow lite version:
implementation('org.tensorflow:tensorflow-lite:0.0.0-nightly') { changing = true }
implementation('org.tensorflow:tensorflow-lite-gpu:0.0.0-nightly') { changing = true }
implementation('org.tensorflow:tensorflow-lite-support:0.0.0-nightly') { changing = true }
Create the input tensor. Prepare the output tensor:
inputImageBuffer = new TensorImage(imageDataType);
outputArr = new TensorBuffer[tflite.getOutputTensorCount()];
resizeOutputArr = new TensorBuffer[tflite.getOutputTensorCount()];
for (int i = 0, count = tflite.getOutputTensorCount(); i < count; i++) {
DataType pDataType = tflite.getOutputTensor(i).dataType();
if (pDataType == DataType.INT32) pDataType = DataType.FLOAT32;
outputArr[i] = TensorBuffer.createFixedSize(i == 0 ? new int[]{imageSizeY, imageSizeX} : new int[]{imageSizeX}, pDataType);
resizeOutputArr[i] = TensorBuffer.createDynamic(pDataType);
}
Resize the input imagebuffer
// Loads bitmap into a TensorImage.
inputImageBuffer.load(bitmap);
float sc = bitmap.getWidth() / 320.0f;
int scaleWid = Math.round(bitmap.getWidth() / sc);
int scaleHei = Math.round(bitmap.getHeight() / sc);
imageSizeY = scaleHei / 32 * 32;
// Creates processor for the TensorImage.
int numRotation = sensorOrientation / 90;
this.processor =
new ImageProcessor.Builder()
.add(new ResizeOp(scaleHei, scaleWid, ResizeOp.ResizeMethod.NEAREST_NEIGHBOR))
.add(new ResizeWithCropOrPadOp(imageSizeY, imageSizeX))
.add(new Rot90Op(numRotation))
.add(new GrayOp(imageSizeY, imageSizeX))
.add(getPreprocessNormalizeOp())
.build();
processor.process(inputImageBuffer);
Run:
int imageTensorIndex = 0;
int[] imageShape = tflite.getInputTensor(imageTensorIndex).shape(); // {1, height, width, 3}
if (imageSizeY != imageShape[1] || imageShape[1] == 0) { // imageSizeY changed
tflite.resizeInput(imageTensorIndex, new int[]{1, imageSizeY, imageSizeX, 3}); //resize inputTensor
for (int i = 0, count = tflite.getOutputTensorCount(); i < count; i++) { //recreate outputTensor
DataType pDataType = tflite.getOutputTensor(i).dataType();
if (pDataType == DataType.INT32) pDataType = DataType.FLOAT32;
outputArr[i] = TensorBuffer.createFixedSize(i == 0 ? new int[]{imageSizeY, imageSizeX} : new int[]{imageSizeX}, pDataType);
}
}
Map<Integer, Object> outputMap = new HashMap<>();
for (int i = 0, cnt = outputArr.length; i < cnt; i++) { //rewind outputBuffer
outputMap.put(i, outputArr[i].getBuffer().rewind());
resizeOutputArr[i].getBuffer().rewind();
}
try {
tflite.runForMultipleInputsOutputs(new Object[]{inputImageBuffer.getBuffer()}, outputMap);
} catch (IllegalArgumentException e) {
e.printStackTrace();
return null;
}
for (int i = 0, count = tflite.getOutputTensorCount(); i < count; i++) { //resize outputArr with new shape
int[] shape = tflite.getOutputTensor(i).shape();
outputArr[i].getBuffer().limit(computeFlatSize(shape) * DataType.FLOAT32.byteSize());
resizeOutputArr[i].loadBuffer(outputArr[i].getBuffer(), shape);
outputArr[i].getBuffer().clear();
if (i == count - 1 && shape != null && shape[0] <= 0) return null;
}
return resizeOutputArr;
protected static int computeFlatSize(#NonNull int[] shape) {
SupportPreconditions.checkNotNull(shape, "Shape cannot be null.");
int prod = 1;
for (int i = 0; i < shape.length; ++i) {
prod *= shape[i];
}
return prod;
}
I got blew Exception when there is no recognized object in the Bitmap:
W: java.lang.IllegalArgumentException: Internal error: Tensor hasn't been allocated.
W: at org.tensorflow.lite.Tensor.buffer(Native Method)
W: at org.tensorflow.lite.Tensor.buffer(Tensor.java:493)
W: at org.tensorflow.lite.Tensor.copyTo(Tensor.java:264)
W: at org.tensorflow.lite.Tensor.copyTo(Tensor.java:254)
W: at org.tensorflow.lite.NativeInterpreterWrapper.run(NativeInterpreterWrapper.java:170)
W: at org.tensorflow.lite.Interpreter.runForMultipleInputsOutputs(Interpreter.java:343)
W: at com.fotric.irdetector.qf.tflite.Classifier.recognizeImage(Classifier.java:283)
This exception reduces the recognition performance, Someone help me, thanks!!!
I am trying to use gdx-bullet stand alone and run the hello world like in the cpp one and I am getting values from 0 to 2 and up.
Why is that in the jbullet and cpp bullet is working fine
any idea why is it maybe is the setToTranslation or the string output
image.
Here is the code:
public static void main(String[] args) {
Bullet.init();
btCollisionConfiguration collisionConfig;
btCollisionDispatcher dispatcher;
btBroadphaseInterface overlappingPairCache;
btSequentialImpulseConstraintSolver solver;
btDiscreteDynamicsWorld dynamicWorld;
ArrayList<btCollisionShape> collisionShapes;
collisionShapes = new ArrayList<btCollisionShape>();
collisionConfig = new btDefaultCollisionConfiguration();
dispatcher = new btCollisionDispatcher(collisionConfig);
overlappingPairCache = new btDbvtBroadphase();
solver = new btSequentialImpulseConstraintSolver();
dynamicWorld = new btDiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfig);
dynamicWorld.setGravity(new Vector3(0, -10f, 0));
{
btCollisionShape groundShape = new btBoxShape(new Vector3(50.f, 50.f, 50.f));
collisionShapes.add(groundShape);
Matrix4 groundTransform = new Matrix4();
groundTransform.setToTranslation(new Vector3(0, -56, 0));
float mass = 0f;
boolean isDynamic = (mass != 0f);
Vector3 localInertia = new Vector3(0, 0, 0);
if (isDynamic)
groundShape.calculateLocalInertia(mass, localInertia);
btDefaultMotionState myMotionState = new btDefaultMotionState(groundTransform);
btRigidBodyConstructionInfo rbInfo = new btRigidBodyConstructionInfo(mass, myMotionState, groundShape,
localInertia);
btRigidBody body = new btRigidBody(rbInfo);
dynamicWorld.addRigidBody(body);
}
{
btCollisionShape colShape = new btSphereShape(1.f);
collisionShapes.add(colShape);
Matrix4 startTransform = new Matrix4();
startTransform.setToTranslation(new Vector3(2, 10, 0));
float mass = 1;
boolean isDynamic = (mass != 0f);
Vector3 localInertia = new Vector3(0, 0, 0);
if (isDynamic)
colShape.calculateLocalInertia(mass, localInertia);
btDefaultMotionState myMotionState = new btDefaultMotionState(startTransform);
btRigidBodyConstructionInfo rbInfo = new btRigidBodyConstructionInfo(mass, myMotionState, colShape,
localInertia);
btRigidBody body = new btRigidBody(rbInfo);
dynamicWorld.addRigidBody(body);
}
for (int i = 0; i < 150; i++) {
dynamicWorld.stepSimulation(1.f / 60.f, 10);
for (int j = dynamicWorld.getNumCollisionObjects() - 1; j >= 0; j--) {
btCollisionObject obj = dynamicWorld.getCollisionObjectArray().atConst(j);
btRigidBody body = (btRigidBody) obj;
if (body != null && body.getMotionState() != null) {
Matrix4 trans = new Matrix4();
body.getMotionState().getWorldTransform(trans);
System.out.println(
"world pos " + j + " = " + trans.val[12] + " , " + trans.val[13] + ", " + trans.val[14]);
}
}
}
collisionShapes.clear();
dynamicWorld.dispose();
overlappingPairCache.dispose();
dispatcher.dispose();
collisionConfig.dispose();
}
How does the second character feel about the protagonist?
Something the protagonist would like to say to the second character
This is the code for this issue for you to check if there is any problem in the code.
Now the problem is when I limit the rows to 45 (this number fits in one page) every row will print in one page.
But, If I don't limit the rows and the row size (approximately 100-200), every row goes to new page in the PDF. The PDF page number goes to approximately equal to row numbers.
I have opened this issue in Boxable's git but it's not active so I came for help here.
Following are the files generated in both conditions:
LimitTemp.pdf
noLimitTemp.pdf
public class CSVtoPDF {
private float marginBetweenYElements = 10;
private float titleFontSize = 18;
private float fontSize = 8;
private float headerFontSize = 12;
private float header1FontSize = 14;
private float header2FontSize = 12;
private float headerCellHeight = 19;
private float dataCellHeight = 12;
private PDFont font = PDType1Font.HELVETICA;
private PDFont headerFont = PDType1Font.TIMES_BOLD;
List filteredData = new ArrayList();
ReportSettings rs = new ReportSettings();
String filePath, destPath, header1, header2, filename;
public CSVtoPDF(List data, Audit audit) throws IOException {
this.filteredData = data;
Date liveDate = new Date();
SimpleDateFormat format= new SimpleDateFormat("YYYY-MM-DD HH:mm:ss");
liveDate = Calendar.getInstance().getTime();
float headerCellHeight = 18;
PDDocument doc = new PDDocument();
PDPage page = new PDPage(PDRectangle.A4);
//page.setMediaBox(new PDRectangle(PDRectangle.A4.getHeight(),
// PDRectangle.A4.getWidth()));
PDPageContentStream cos = new PDPageContentStream(doc, page);
/* Add page to PDDocument */
doc.addPage(page);
System.out.println("Inside Main csvtopdf");
//Draw Header
Preferences prefs = Preferences.userRoot().node(this.getClass().getName());
try {
String[] keys = prefs.keys();
//destPath = prefs.get("destpath", rs.getDestPath());
//filename = prefs.get("file_name", rs.getFileName());
//header1 = prefs.get("header1", rs.getHeader1());
//header2 = prefs.get("header2", rs.getHeader2());
} catch (BackingStoreException ex) {
System.err.println(ex);
}
header1= "Header 1";
header2= "Header 2";
cos.beginText();
cos.moveTextPositionByAmount(220, 810);
cos.setFont(headerFont, header1FontSize);
cos.drawString(header1);
cos.endText();
cos.beginText();
cos.moveTextPositionByAmount(220, 800);
cos.setFont(headerFont, header2FontSize);
cos.drawString(header2);
cos.endText();
cos.beginText();
cos.moveTextPositionByAmount(220, 790);
cos.setFont(headerFont, headerFontSize);
cos.drawString("Report: Filtered Audit Report");
cos.endText();
//cos.beginText();
// cos.moveTo(200, 30);
//cos.setFont(headerFont, headerFontSize);
// cos.drawString(header2);
//cos.endText();
/* Initialize DataTable */
float margin = 20;
float tableWidth = page.getMediaBox().getWidth() - (2 * margin);
float yStartNewPage = page.getMediaBox().getHeight() - (2 * margin);
float yStart = yStartNewPage;
float bottomMargin = -800;
BaseTable table = new BaseTable(yStart, yStartNewPage,
bottomMargin, tableWidth, margin, doc, page, true, true);
Row<PDPage> dataRow = table.createRow(dataCellHeight);
for (int i = 0; i < data.size() - 1; i++) {
System.out.println(data.get(i));
}
drawTableData(table, dataCellHeight, 20, data, 1,doc,page);
table.draw();
File result;
if (Objects.isNull(destPath)) {
cos.close();
result = new File("temp.pdf");
} else {
result = new File(destPath);
}
System.out.println("befor save result");
doc.save(result);
System.out.println("after save result");
}
public void drawTableData(BaseTable table, float dataCellHeight, float
cellWidth, List<Audit> data, int style,PDDocument doc,PDPage page) {
String s;
Cell<PDPage> cell;
// for (int k = 0; k < data.size(); k++) {
System.out.println("inside drawtable for ");
for (int i = 0; i < data.size(); i++) { // add row
System.out.println("inside drawtable for " + i);
Audit atmp = data.get(i);
//if (i==35) {
// doc.addPage(page);
//}
Row<PDPage> sTableRow = table.createRow(dataCellHeight);
for (int j = 0; j <= 2; j++) { //add cell in the rows
if (j == 0) { // normal cells on right
s = atmp.getTimeStamp();
s = s.replaceAll("^\"|\"$", "");
cell = sTableRow.createCell(cellWidth, s, HorizontalAlignment.CENTER, VerticalAlignment.BOTTOM);
setStyle(style, cell);
//k++;
} else if (j == 1) { //big cells on left
s = atmp.getDiscription();
s = s.replaceAll("^\"|\"$", "");
cell = sTableRow.createCell(cellWidth + 50, s, HorizontalAlignment.CENTER, VerticalAlignment.BOTTOM);
setStyle(style, cell);
// k++;
} else if (j == 2) { //top blank cell
//System.out.println("In j null and 0 " + j);
s = atmp.getUserID();
s = s.replaceAll("^\"|\"$", "");
cell = sTableRow.createCell(cellWidth - 10, s, HorizontalAlignment.CENTER, VerticalAlignment.BOTTOM);
//cell.setBottomBorderStyle(null);
setStyle(style, cell);
//k++;
}
}
table.addHeaderRow(sTableRow);
System.out.println(" row added ");
}
//}
}
public void setStyle(int type, Cell cell) {
// type : 0 as header, 1 as table body
if (type == 0) {
cell.setFont(headerFont);
//cell.setHeight(headerCellHeight);
cell.setFontSize(headerFontSize);
cell.setBottomPadding(3);
} else if (type == 1) {
cell.setTopPadding(1);
cell.setFont(font);
cell.setAlign(HorizontalAlignment.LEFT);
//cell.setHeight(dataCellHeight);
cell.setFontSize(fontSize);
cell.setBottomPadding(1);
}
}
I found a silly problem in my code. I am telling this so that someone else must not repeat this.
I treated every row of the data table as header row. So it went to new page.
To be specific. In the function drawTableData I removed table.addHeaderRow(sTableRow)
My stacked bar chart in MPAndroidChart works very well but I'm trying to remove or edit the values inside the bars. But I can't find any code which makes sense to modify.
I don't think that my code is very helpful, but here it is...
private void initStackedBarChartStuff() {
mMonths = dfs.getShortMonths();
mChart = (BarChart) mContext.findViewById(R.id.chart1);
mChart.setOnChartValueSelectedListener(this);
mChart.setDescription("");
// if more than 60 entries are displayed in the chart, no values will be
// drawn
mChart.setMaxVisibleValueCount(30);
// scaling can now only be done on x- and y-axis separately
mChart.setPinchZoom(false);
mChart.setDrawGridBackground(false);
mChart.setDrawBarShadow(false);
mChart.setDrawValueAboveBar(false);
// change the position of the y-labels
YAxis yLabels = mChart.getAxisLeft();
yLabels.setValueFormatter(new MyYAxisValueFormatter());
mChart.getAxisRight().setEnabled(false);
mChart.getAxisLeft().setEnabled(false);
XAxis xLabels = mChart.getXAxis();
xLabels.setPosition(XAxis.XAxisPosition.TOP);
Legend l = mChart.getLegend();
l.setPosition(Legend.LegendPosition.BELOW_CHART_RIGHT);
l.setFormSize(8f);
l.setFormToTextSpace(4f);
l.setXEntrySpace(6f);
// mChart.setDrawLegend(false);
}
fill the stackedBarChart
private void fillStackedBarChart(Vector drawingData, Vector drawingIntervall) {
if (drawingData == null || drawingData == null)
return;
int anzBdata = dataSizes[1];
int intervall = globalIntervall;
ArrayList<String> xVals = new ArrayList<String>();
// Strings über die Blöcke schreiben ###########################################
{
long zeit = 0;
String[] months = new String[12];
String[] days = new String[7];
boolean einmal = true;
for (int i = 0; i < drawingIntervall.size(); i++)
zeit += ((Long) drawingIntervall.get(i)).longValue();
if (bigData) // > 2 Jahre
months = null;
else if (zeit > 31623000) // > 1 Jahre
months = dfs.getShortMonths();
else
months = dfs.getMonths();
days = dfs.getWeekdays();
for (int i = 0; i < drawingData.size(); i++) {
long[] pack = (long[]) drawingData.get(i);
String s = "";
// Sonderfall !! In Monatsansicht den Monat dazu schreiben
if ((einmal) && (intervall == 2)) {
if (etStart.getText().toString().trim().startsWith("01.")) {
Calendar calE = convStringToDate(etEnd.getText().toString().trim(), true, true);
int jahr = calE.get(Calendar.YEAR);
int monat = calE.get(Calendar.MONTH);
Calendar calX = myGetInstance();
calX.set(Calendar.YEAR, jahr);
calX.set(Calendar.MONTH, monat);
calX = getLastDayOfMonth(calX);
if (calE.getTimeInMillis() == calX.getTimeInMillis()) {
einmal = false;
s = months[calE.get(Calendar.MONTH)];
}
}
}
switch (intervall) {
case 0:
s += df.format(convMilliToDate(pack[0] * 1000, false, false).getTime());
break;
case 1:
s += convMilliToString(pack[0] * 1000);
break;
case 2:
s += "KW " + convMilliToDate(pack[0] * 1000, false, false).get(Calendar.WEEK_OF_YEAR);
break;
case 3:
if (bigData)
s += convMilliToDate(pack[0] * 1000, false, false).get(Calendar.YEAR) + "";
else
s += months[convMilliToDate(pack[0] * 1000, false, false).get(Calendar.MONTH)];
break;
}
xVals.add(s);
}
}
// nun alle Balken/Blöcke zeichnen ##########################################
{
// 1 Y-Wert entspricht z.B. 1 Tag, o. 1 Woche,... jeder Y-Wert hat so viele floats wie B-Daten vorhanden sind ###########################################
ArrayList<BarEntry> yVals1 = new ArrayList<BarEntry>();
for (int i = 0; i < drawingData.size(); i++) {
long[] pack = (long[]) drawingData.get(i);
long intervallSek = ((Long) drawingIntervall.get(i)).longValue() + 1;
long pastSek = 0;
float[] f = new float[anzBdata + 1];
int b = 0;
for (int j = 0; j < pack.length; j++) {
if ((j >= dataSizes[0]) && (j <= (anzBdata - 1 + dataSizes[0]))) {
f[b++] = pack[j];
pastSek += pack[j];
}
}
f[b++] = intervallSek - pastSek; // zeichnet einen Block indem "keine Daten" aufgezeichnet wurden. (wenn Maschine ohne Strom o.ä.)
yVals1.add(new BarEntry(f, i));
}
// BarDataSet set1 = new BarDataSet(yVals1, "Statistics Business Data");
BarDataSet set1 = new BarDataSet(yVals1, "");
set1.setColors(getColors());
set1.setStackLabels(barChartLegend);
ArrayList<BarDataSet> dataSets = new ArrayList<BarDataSet>();
dataSets.add(set1);
BarData data = new BarData(xVals, dataSets);
data.setValueFormatter(new MyValueFormatter());
mChart.setData(data);
mChart.invalidate();
}
}
This solution is not really pretty, may somone else find a better one...
The class BarChart extends from BarLineChartBase. There is a line in BarLineChartBase which can be annotated or removed to get the desired solution.
mRenderer.drawValues(canvas);
There are basically two ways:
Use the ValueFormatter to custom format your values (edit or remove)
Use dataSet.setDrawValues(false) to completely remove all values