I am using an HorizontalBarChart I want to draw a Label (the name of the vendor) inside or in the middle of the Bar, in the BarDaset there is something called setLabel but it's not working.
Here is my code:
private BarDataSet createLineChart(String storeName, List<String> listofcompanies){
ArrayList<BarEntry> entries= new ArrayList<BarEntry>();
for (int j = 0; j < listofcompanies.size(); j++) {
entries.add(new BarEntry(Float.parseFloat(listofcompanies.get(j)),j));
}
Random rd = new Random();
setComp1 = new BarDataSet(entries,storeName);
setComp1.setColor(Color.argb(255,rd.nextInt(256),rd.nextInt(256),rd.nextInt(256)));
setComp1.setDrawValues(true);
setComp1.setLabel(storeName);
setComp1.setHighlightEnabled(true);
setComp1.setDrawValues(true);
// LineData data =new LineData(labels,dataset);
return setComp1;
}
Try to use:
chart.getXAxis().setPosition(XAxisPosition.BOTTOM_INSIDE);
Or
chart.getXAxis().setPosition(XAxisPosition.TOP_INSIDE);
This will solve your problem.
Related
So i have a barchart in MPandroid, and i need to put the names on the chart, but there is no space where i want them, the solution is to put them on top of the chart. Like this:
can someone help me achieve this ?
There isn't a built-in way of putting the text in a non-standard location, but you can do it by writing a custom renderer for your chart. If you extend the HorizontalBarChartRenderer class and override the drawValues method (making just a few modifications to the original version in the code linked) you can change where the label gets drawn.
Custom Renderer
Code copied from drawValues in HorizontalBarChartRenderer and simplified to only include required parts for this use-case (removed logic for stacked charts, icons, toggling values on and off, etc). The only change is to the x,y values passed to drawValue()
private static class MyRenderer extends HorizontalBarChartRenderer {
public MyRenderer(BarDataProvider chart, ChartAnimator animator,
ViewPortHandler viewPortHandler) {
super(chart, animator, viewPortHandler);
}
#Override
public void drawValues(Canvas c) {
List<IBarDataSet> dataSets = mChart.getBarData().getDataSets();
final float valueOffsetPlus = Utils.convertDpToPixel(5f);
for (int i = 0; i < mChart.getBarData().getDataSetCount(); i++) {
IBarDataSet dataSet = dataSets.get(i);
// apply the text-styling defined by the DataSet
applyValueTextStyle(dataSet);
ValueFormatter formatter = dataSet.getValueFormatter();
// get the buffer
BarBuffer buffer = mBarBuffers[i];
for (int j = 0; j < buffer.buffer.length * mAnimator.getPhaseX(); j += 4) {
if (!mViewPortHandler.isInBoundsTop(buffer.buffer[j + 1]))
break;
if (!mViewPortHandler.isInBoundsX(buffer.buffer[j]))
continue;
if (!mViewPortHandler.isInBoundsBottom(buffer.buffer[j + 1]))
continue;
BarEntry entry = dataSet.getEntryForIndex(j / 4);
String formattedValue = formatter.getBarLabel(entry);
// Modify the x, y position here to control where the
// text is. The "buffer" array gives the positions of
// the current bar (in pixels)
drawValue(c,
formattedValue,
buffer.buffer[j] + valueOffsetPlus,
buffer.buffer[j+1] - valueOffsetPlus,
dataSet.getValueTextColor(j / 2));
}
}
}
}
Example Use
To use the custom renderer, set it on the chart and modify the bar widths to leave room for the text.
HorizontalBarChart chart = findViewById(R.id.chart);
List<Float> values = Arrays.asList(3f, 2f, 2.2f);
List<Integer> colors = Arrays.asList(Color.CYAN, Color.RED, Color.GREEN);
List<String> labels = Arrays.asList("Pickled Horses", "Horses", "Pickles");
List<BarEntry> entries = new ArrayList<>();
for(int i = 0; i < values.size(); ++i) {
entries.add(new BarEntry(i+1, values.get(i), labels.get(i)));
}
BarDataSet ds = new BarDataSet(entries, "Values");
ds.setColors(colors);
ds.setValueTextSize(14f);
ds.setValueFormatter(new ValueFormatter() {
#Override
public String getBarLabel(BarEntry barEntry) {
return (String)barEntry.getData();
}
});
ds.setAxisDependency(YAxis.AxisDependency.RIGHT);
BarData data = new BarData(ds);
// Reduce bar width to leave room for text
data.setBarWidth(0.75f);
// Use the custom renderer
chart.setRenderer(new MyRenderer(chart, chart.getAnimator(), chart.getViewPortHandler()));
// Misc formatting & setup
chart.setData(data);
chart.getAxisLeft().setEnabled(false);
chart.getAxisRight().setAxisMinimum(0f);
chart.getAxisRight().setAxisMaximum(4f);
chart.getAxisRight().setGranularity(1f);
chart.getAxisRight().setTextSize(14f);
chart.getAxisRight().setDrawGridLines(false);
chart.getXAxis().setDrawLabels(false);
chart.getXAxis().setDrawGridLines(false);
chart.getXAxis().setAxisMaximum(3.6f);
chart.getDescription().setEnabled(false);
chart.getLegend().setEnabled(false);
chart.setBorderColor(Color.BLACK);
chart.setBorderWidth(1f);
chart.setDrawBorders(true);
I am having problem creating LineChart it's just showing the last Line when I need to show all Lines can you please help? here's the code:
Collections.addAll(labels,` column);
dataSets = new ArrayList<ILineDataSet>();
for (monthlysales company : companieslist) {
entries.clear();
for (int j = 0; j < listofcompanies.Total.size(); j++) {
entries.add(new Entry(Float.parseFloat(listofcompanies.Total.get(j)), j));
}
setComp1 = new LineDataSet(entries, company.StoreName);
setComp1.setAxisDependency(YAxis.AxisDependency.LEFT);
setComp1.setColor(Color.BLUE);
dataSets.add(setComp1);
}
LineData data = new LineData(column,dataSets);
linechart.setData(data);
linechart.setDescription("Sales");
linechart.animateXY(5000,5000);
linechart.setPinchZoom(true);
linechart.setDoubleTapToZoomEnabled(true);
linechart.setDragDecelerationEnabled(true);
linechart.notifyDataSetChanged();
linechart.invalidate();
}
Thank you
This actually makes sense. You are adding data to the entries list, and then add it to the DataSet correctly. The problem is, you are clearing the entries list every time after you add it. you should use a separate list for each dataset.
replace the line:
entries.clear();
with
List<Entry> entries = new ArrayList<>();
it's now solved by creating a Function and call it as below :
**dataSets.add(createLineChart(company,company.StoreName,company.Total));**
data = new LineData(column,dataSets);
linechart.setData(data);
linechart.invalidate();
linechart.setDescription("Sales");
and this is the function:
private LineDataSet createLineChart(monthlysales company,String storeName,List<String> listofcompanies){
// LineData data=new LineData();
ArrayList<Entry> entries= new ArrayList<Entry>();
for (int j = 0; j < listofcompanies.size(); j++) {
entries.add(new Entry(Float.parseFloat(listofcompanies.get(j)),j));
linechart.notifyDataSetChanged();
}
Random rd = new Random();
setComp1 = new LineDataSet(entries,storeName);
setComp1.setColor(Color.argb(255,rd.nextInt(256),rd.nextInt(256),rd.nextInt(256)));
// LineData data =new LineData(labels,dataset);
return setComp1;
}
it seems that the LineDataSet was used the last time it was called displaying just one line.
I have an assignment where I am to create a chutes and ladder game using JavaFX.
What I am currently stuck on is once the user selects how many players they want, the method I run pushes an error.
I have run it through the debugger and I know what line is the problem, but I have no idea where to go from here.
The exception is:
Exception in thread "JavaFX Application Thread"
java.lang.ArrayIndexOutOfBoundsException: 0
I found that if I change the zero in private Players [] players = new Players[0]; to a 4, it works. However, I get another error if I try to change the 0 in private Circle [] c = new Circle[0];
public class Main extends Application {
private final int BOARD_DIM = 10;
private Players [] players = new Players[0];
private Circle [] c = new Circle[0];
public static void main(String[]args){
launch();
}
public void start(Stage pStage) throws Exception{
//ROOT PANE
BorderPane root = new BorderPane();
//MENUBAR
//BOARD CREATION
//PLAYER SELECTION/RESUME PREVIOUS GAME
//Drop down menu
HBox players = new HBox();
Label intro = new Label("Select # of players");
ChoiceBox<String> p = new ChoiceBox<>();
p.getItems().addAll("2","3","4");
p.setPadding(new Insets(6));
//Button to start new game
Button startGame = new Button("Start Game");
startGame.setOnAction(e -> getChoice(p));
startGame.setPadding(new Insets(10));
players.getChildren().addAll(intro,p,startGame);
root.setRight(players);
Scene scene = new Scene(root, 900, 650);
pStage.setTitle("Chutes and Ladders");
pStage.setScene(scene);
pStage.show();
}
private void getChoice(ChoiceBox<String> p) {
int numOfPlayers = Integer.parseInt(p.getValue());
for(int i = 0; i < numOfPlayers; i++){
players[i] = new Players("p"+(i+1),9,0, false);
c[i] = new Circle(25);
}
c[0].setFill(Color.GREEN);
c[1].setFill(Color.YELLOW);
if(numOfPlayers >= 3){
c[2].setFill(Color.RED);
}
if(numOfPlayers == 4){
c[3].setFill(Color.BLACK);
}
}
You are initalizing players and c as arrays with length 0. And in the loop you are iterating over the elements from 0 to numOfPlayers. That's what is causing the exception.
First just declare your arrays:
private Players [] players;
private Circle [] c;
Then in the your method, initalize the arrays with the length you need (If you need to alter the length later I would suggest to switch to ArrayLists).
private void getChoice(ChoiceBox<String> p) {
int numOfPlayers = Integer.parseInt(p.getValue());
c = new Circle[numOfPlayers]; //add these lines
players = new Players[numOfPlayers]; //add these lines
for(int i = 0; i < numOfPlayers; i++){
players[i] = new Players("p"+(i+1),9,0, false);
c[i] = new Circle(25);
}
...
}
I'm trying to create a complete menubar using multidimensional ararys.
So far I have this code:
private JMenuBar menuBar = new JMenuBar();
private JMenuItem[][] menuItem = new JMenuItem[5][5];
private String[] menuBarItemNames = {"File", "Edit", "Database", "View", "Help"};
private String[] menuBarFileItemNames = {"Save", "Refresh", "Next", "Previous","Exit"};
view() {
setJMenuBar(menuBar);
for(int u = 0; u < menuItem.length; u++){
menuItem[u][0] = new JMenu(menuBarItemNames[u]);
for(int t = 0; t < menuBarFileItemNames.length; t++){
//Code to add 'File' child items to the 'File' MenuBarItem
}
menuBar.add(menuItem[u][0]);
}
I'm struggling to figure out how to add the menuBarFileItems to the File menu.
I have this code to add to the second for loop:
menuItem[0][t] = new JMenuItem(menuBarFileItemNames[t]);
but it just causes the first item on the menuBar to be replaced by 'Save'.
Any ideas?
Also, is it not possible to have private JMenuItem[][] menuItem = new JMenuItem[5][]; so that I don't have to set the size of each menuBar item, e.g. File = 5 items, Edit = 5 items etc
Thanks
Try it:
...
menuItem[u][0] = new JMenu(menuBarItemNames[u]);
for(int t = 0; t < menuBarFileItemNames.length; t++){
menuItem[0][t].add(new JMenuItem(menuBarFileItemNames[t]));
}
...
Att: This is only for "FILE" menu item (on zero position).
I think what you want is this:
private void view()
{
setJMenuBar(menuBar);
for (int u = 0; u < menuItem.length; u++)
{
menuItem[u][0] = new JMenu(menuBarItemNames[u]);
if (u == 0)
{
for (int t = 1; t <= menuBarFileItemNames.length; t++)
{
// Code to add 'File' child items to the 'File' MenuBarItem
menuItem[0][t] = new JMenuItem(menuBarFileItemNames[t-1]);
menuItem[0][0].add(menuItem[0][t]);
}
}
menuBar.add(menuItem[u][0]);
}
}
If you're replacing the first item on the menu bar, then you're adding to the menu bar, not the menu item.
And no, Java needs to know the sizes of both dimensions of the array you're declaring, you can't leave one of them open.
i wanna create button 1 to 9 and i want to do that in loop. But in each 3 count, i want to create a new LinearLayout.
final LinearLayout[] ll2 = new LinearLayout[10]; // create an empty array;
for(int i=1; i<=9;i++)
{
Button btnNums = new Button(this);
final LinearLayout[] ll2 = new LinearLayout[10]; // create an empty array;
for(int i=1; i<=9;i++)
{
Button btnNums = new Button(this);
btnNums.setText(i+"");
ll.addView(btnNums);
if(i%3==0){
ll2[i] = ll;
ll = null;
}
}
layout.addView(ll2[0]);
btnNums.setText(i+"");
ll.addView(btnNums);
if(i%3==0){
ll2[i] = ll;
ll = null;
}
}
layout.addView(ll2[0]);
This does not work. I get no error but when o run the app, it is stopped to work. What's the problem?
I used it in my Project and it worked for me, i used it like this. Hope it helps
Declare empty array at class level:
LinearLayout[] imageLayoutContainers = new LinearLayout[10];
And then in on onCreate methord :
for (int i = 0; i < imageLayoutContainers.length; i++) {
imageLayoutContainers[i] = new LinearLayout(this);
imageLayoutContainers[i].setOrientation(LinearLayout.VERTICAL);
imageLayoutContainers[i].setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
imageLayoutContainers[i].setBackgroundResource(imagesIds[i]);
}
It worked, thanks