adding Icons with String to MPAndroid Chart as XAxisValues - java

github.PhilJay:MPAndroidChart:v2.0.9`
I was wondering if I can add star icons and numbers as XAxisValues like image below?
I've already added the numbers and it's working fine but I don't know how to add star icons! Is there a way to combine text and icons?
Here is my code so far:
private ArrayList<BarDataSet> getDataSet(int stars1, int stars2, int stars3, int stars4, int stars5) {
ArrayList<BarDataSet> dataSets = null;
ArrayList<BarEntry> valueSet1 = new ArrayList<>();
BarEntry v1e1 = new BarEntry(stars5, 4);
valueSet1.add(v1e1);
BarEntry v1e2 = new BarEntry(stars4, 3);
valueSet1.add(v1e2);
BarEntry v1e3 = new BarEntry(stars3, 2);
valueSet1.add(v1e3);
BarEntry v1e4 = new BarEntry(stars2, 1);
valueSet1.add(v1e4);
BarEntry v1e5 = new BarEntry(stars1, 0);
valueSet1.add(v1e5);
BarDataSet barDataSet1 = new BarDataSet(valueSet1, "");
barDataSet1.setColors(new int[]{getResources().getColor(R.color.chart5), getResources().getColor(R.color.chart4),
getResources().getColor(R.color.chart3), getResources().getColor(R.color.chart2), getResources().getColor(R.color.chart1)});
barDataSet1.setValueTextSize(9);
dataSets = new ArrayList<>();
dataSets.add(barDataSet1);
return dataSets;
}
private ArrayList<String> getXAxisValues() {
ArrayList<String> xAxis = new ArrayList<>();
xAxis.add("1");
xAxis.add("2");
xAxis.add("3");
xAxis.add("4");
xAxis.add("5");
return xAxis;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
BarData data = new BarData(getXAxisValues(), getDataSet(stars1, stars2, stars3, stars4, stars5));
barChart.setData(data);
barChart.setDescription("");
barChart.invalidate();
barChart.getXAxis().setDrawGridLines(false);
barChart.getXAxis().setDrawAxisLine(false);
barChart.setDrawGridBackground(false);
barChart.getAxisLeft().setDrawGridLines(false);
barChart.getAxisRight().setDrawGridLines(false);
barChart.getAxisLeft().setDrawAxisLine(false);
barChart.getAxisRight().setDrawAxisLine(false);
barChart.getLegend().setEnabled(false);
barChart.getXAxis().setDrawLabels(true);
barChart.getXAxis().setPosition(XAxis.XAxisPosition.BOTTOM);
barChart.getAxisRight().setDrawLabels(false);
barChart.getAxisLeft().setDrawLabels(false);
}
Thanks for your time... ♥

Just use ★ character and it will be displayed well. You can use x axis value formatter for formatting values:
barChart.getXAxis().setValueFormatter(new IAxisValueFormatter() {
#Override
public String getFormattedValue(float value, AxisBase axis) {
return "value ★";
}
}
Here is result :

Related

Remove BarDataSet in MPAndroidChart

I'm using MPAndroidChart to build BarChart, but I can't set my BarDataSet(1) and set my column's content(2) to vertical. Can anyone help?
public void LoadChart(final ArrayList<String> nameDate, ArrayList<Float> fl){
com.github.mikephil.charting.charts.BarChart chart = (com.github.mikephil.charting.charts.BarChart) findViewById(R.id.barchart);
/* final String[] nameDate={"JAN","FEB","MAR","APR","MAY","JUN"};
Float[] fl = new Float[]{30f,80f,60f,50f,70f,60f};*/
List<BarEntry> entries = new ArrayList<>();
for(int i=0;i<fl.size();i++)
{
entries.add(new BarEntry(i, fl.get(i)));
}
mDB.open();
BarDataSet set = new BarDataSet(entries, "BarDataSet");
set.setColor(Color.rgb(103,203,27));
BarData data = new BarData(set);
data.setBarWidth(0.9f); // set custom bar width
chart.setData(data);
chart.setFitBars(true); // make the x-axis fit exactly all bars
chart.animateXY(2000, 2000);
chart.setScaleEnabled(false);
chart.invalidate(); // refresh
Description description = chart.getDescription();
description.setEnabled(false);
XAxis xAxis = chart.getXAxis();
xAxis.setDrawGridLines(false);
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setDrawGridLines(false);
xAxis.setGranularity(1f);
xAxis.setValueFormatter(new IAxisValueFormatter() {
#Override
public String getFormattedValue(float value, AxisBase axis) {
return nameDate.get((int) value);
}
});
YAxis yLabels = chart.getAxisLeft();
yLabels.setDrawGridLines(false);
YAxis yLabels1 = chart.getAxisRight();
yLabels1.setEnabled(false);
}
Yes, is possible, just using following code:
mChart.setDescription(""); // Hide the description
mChart.getAxisLeft().setDrawLabels(false);
mChart.getAxisRight().setDrawLabels(false);
mChart.getXAxis().setDrawLabels(false);
mChart.getLegend().setEnabled(false);
try this
OR
pieChart.setUsePercentValues(true);
pieChart.getDescription().setEnabled(false);
pieChart.setExtraOffsets(0, 0, 0,0 );
pieChart.setDragDecelerationFrictionCoef(0.95f);
mChart.setCenterTextTypeface(mTfLight);
mChart.setCenterText(generateCenterSpannableText());
pieChart.setDrawHoleEnabled(false);
// mChart.setHoleColor(Color.WHITE);
// mChart.setTransparentCircleColor(Color.WHITE);
// mChart.setTransparentCircleAlpha(110);
// mChart.setHoleRadius(58f);
// mChart.setTransparentCircleRadius(61f);
pieChart.setDrawCenterText(false);
pieChart.setRotationAngle(0);
// enable rotation of the chart by touch
pieChart.setRotationEnabled(false);
pieChart.setHighlightPerTapEnabled(false);
// mChart.setUnit(" €");
// mChart.setDrawUnitsInChart(true);
// add a selection listener
pieChart.setOnChartValueSelectedListener(this);
setData(4, 100);
pieChart.animateY(0, Easing.EasingOption.EaseInOutQuad);
// mChart.spin(2000, 0, 360);
// mSeekBarX.setOnSeekBarChangeListener(this);
// mSeekBarY.setOnSeekBarChangeListener(this);
Legend l = pieChart.getLegend();
l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
l.setOrientation(Legend.LegendOrientation.VERTICAL);
l.setDrawInside(false);
l.setXEntrySpace(7f);
l.setYEntrySpace(0f);
l.setYOffset(0f);
// mChart.setDescription(""); // Hide the description
// mChart.getAxisLeft().setDrawLabels(false);
// mChart.getAxisRight().setDrawLabels(false);
// mChart.getXAxis().setDrawLabels(false);
pieChart.getLegend().setEnabled(false); // Hi
// entry label styling
pieChart.setEntryLabelColor(Color.WHITE);
// mChart.setEntryLabelTypeface(mTfRegular);
pieChart.setEntryLabelTextSize(12f);
return rootView;
and try this code bar data set is not visible again

Creating a bar chart with MPAndroidChart using double values

Hi I am trying to create a bar chart using MPAndroidChart library in Android Studio for my java application. I have managed to plot a bar chart using single integer values, but I would like to plot double values.
Here is my code for plotting single integer values
public class walk extends AppCompatActivity {
HorizontalBarChart barChart;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_walk);
barChart = (HorizontalBarChart) findViewById(R.id.bargraph);
ArrayList<BarEntry> barEntries = new ArrayList<>();
barEntries.add(new BarEntry(10f,0));
barEntries.add(new BarEntry(5f,1));
BarDataSet barDataSet = new BarDataSet(barEntries,"ACTIVITIES");
ArrayList <String> pa = new ArrayList<>();
pa.add("WALKING");
pa.add("RUNNING");
BarData theData = new BarData(pa,barDataSet);
barChart.setData(theData);
barDataSet.setBarSpacePercent(70f);
}
I would like to plot the following values 20.333333333333332 and 2.0071271275749623.
I would appreciate any help I could get, apologies if anything is unclear I am new to this site.
Converting double to float before plotting :
double point1 = 20.333333333333332;
double point2 = 2.0071271275749623;
float fp1 = (float)point1;
float fp2 = (float)point2;
ArrayList<BarEntry> barEntries = new ArrayList<>();
barEntries.add(new BarEntry(fp1,0));
barEntries.add(new BarEntry(fp2,1));
BarDataSet barDataSet = new BarDataSet(barEntries,"ACTIVITIES");

How to display bar labels in HorizontalBarChart?

I have a HorizontalBarChart from MPAndroidChart library (version v3.0.0-beta1) in which I display the monthly spending of the user's accounts.
So i implemented this method:
List<Account> accounts = getAccounts();
final ArrayList<BarEntry> entries = new ArrayList<>();
Float count = 0F;
for (Account account : accounts) {
entries.add(new BarEntry(count++, new float[]{Float.valueOf(account.getBalance())}, account.getName()));
}
BarDataSet dataset = new BarDataSet(entries, " ");
dataset.setColors(ColorTemplate.PASTEL_COLORS);
dataset.setValueTextSize(10F);
BarData data = new BarData(dataset);
horizontalBarChartMonthlySpending.setData(data);
horizontalBarChartMonthlySpending.setDescription("Gastos por conta neste mês!");
horizontalBarChartMonthlySpending.getAxisLeft().setDrawLabels(false);
horizontalBarChartMonthlySpending.getAxisRight().setDrawLabels(false);
horizontalBarChartMonthlySpending.setFitBars(true);
horizontalBarChartMonthlySpending.setTouchEnabled(false);
And this is what i got:
What i want is, beside every bar, put the description of the related account. I tried to do this in line 6 with the account.getName() but it didn't appear anywhere in the report.
Is there a way to do it?
I had this problem and correct putting this code:
horizontalBarChartMonthlySpending.getXAxis().setValueFormatter(new AxisValueFormatter() {
#Override
public String getFormattedValue(float value, AxisBase axis) {
return entries.get((int) value).getData().toString();
}
#Override
public int getDecimalDigits() {
return 0;
}
});
XAxis xAxis = horizontalBarChartMonthlySpending.getXAxis();
xAxis.setGranularity(1f);
xAxis.setGranularityEnabled(true);

JavaFX ListView very slow

I'm making a chat application using JavaFX for the GUI. I display the chat content in a ListView, but I have one big problem - it's very very slow. When I add new items to the list and especially when I scroll the list up/down. I think maybe it has something to do with the fact that the list refreshes itsellf every time a new item is added (each cell in the list!) and also refreshes every time I scroll up/down.
Does someone know what can I do to solve this problem? TNX
I override ListCell's updateItem:
chatListView.setCellFactory(new Callback<ListView<UserInfo>, ListCell<UserInfo>>() {
#Override
public ListCell<UserInfo> call(ListView<UserInfo> p) {
ListCell<UserInfo> cell = new ListCell<UserInfo>() {
#Override
protected void updateItem(UserInfo item, boolean bln) {
super.updateItem(item, bln);
if (item != null) {
BorderPane borderPane = new BorderPane();
ImageView profileImage = new ImageView(new Image(item.getImageURL()));
profileImage.setFitHeight(32);
profileImage.setFitWidth(32);
Rectangle clip = new Rectangle(
profileImage.getFitWidth(), profileImage.getFitHeight()
);
clip.setArcWidth(30);
clip.setArcHeight(30);
profileImage.setClip(clip);
SnapshotParameters parameters = new SnapshotParameters();
parameters.setFill(Color.TRANSPARENT);
WritableImage image = profileImage.snapshot(parameters, null);
profileImage.setClip(null);
profileImage.setImage(image);
ImageView arrowImage = new ImageView(new Image("arrow1.png"));
ImageView arrowImage2 = new ImageView(new Image("arrow1.png"));
Label nameLabel = new Label(item.getUserName());
nameLabel.setStyle(" -fx-text-alignment: center; -fx-padding: 2;");
HBox hbox = null;
Label textLabel = new Label();
String messageText = splitTolines(item.getMessage());
textLabel.setText(messageText);
textLabel.setStyle("-fx-background-color: #a1f2cd; "
+ "-fx-padding: 10;\n"
+ "-fx-spacing: 5;");
hbox = new HBox(arrowImage, textLabel);
VBox vbox = new VBox(profileImage, nameLabel);
BorderPane.setMargin(vbox, new Insets(0, 10, 10, 10));
BorderPane.setMargin(hbox, new Insets(10, 0, 0, 0));
//Time
Date dNow = new Date();
SimpleDateFormat ft = new SimpleDateFormat("hh:mm a");
Label timeLabel = new Label(ft.format(dNow));
timeLabel.setStyle("-fx-font: 8px Tahoma; -fx-width: 100%");
HBox hbox2 = new HBox(arrowImage2, timeLabel);
arrowImage2.setVisible(false);
VBox vbox2 = new VBox(hbox, hbox2);
borderPane.setCenter(vbox2);
borderPane.setLeft(vbox);
setGraphic(borderPane);
}
}
};
return cell;
}
});
Never ever add (big) GUI Elements in updateItem() without checking if it is not already there.
updateItem() is called everytime for EVERY SINGLE ROW when you scroll, resize or change gui in any other way.
You should alway reset the graphic to null if you do not have an item or the second boolean of updateItem(item, empty) is false, because the second boolean is the EMPTY flag.
I recommend to you that you use a VBox instead of a ListView.
You must not build new instances of your components everytime the view gets updated.
Instanciate them one time initialy, then you reuse and change their attributes.
I just noticed that too. It's too slow even for a list containing only 5-10 items (with scaled images and text). Since I need no selection feature, I also rewrote the code to use VBox instead and the slowness is immediately gone!
To emulate the setItems, I have a helper function which you may find handy:
public static <S, T> void mapByValue(
ObservableList<S> sourceList,
ObservableList<T> targetList,
Function<S, T> mapper)
{
Objects.requireNonNull(sourceList);
Objects.requireNonNull(targetList);
Objects.requireNonNull(mapper);
targetList.clear();
Map<S, T> sourceToTargetMap = new HashMap<>();
// Populate targetList by sourceList and mapper
for (S s : sourceList)
{
T t = mapper.apply(s);
targetList.add(t);
sourceToTargetMap.put(s, t);
}
// Listen to changes in sourceList and update targetList accordingly
ListChangeListener<S> sourceListener = new ListChangeListener<S>()
{
#Override
public void onChanged(ListChangeListener.Change<? extends S> c)
{
while (c.next())
{
if (c.wasPermutated())
{
for (int i = c.getFrom(); i < c.getTo(); i++)
{
int j = c.getPermutation(i);
S s = sourceList.get(j);
T t = sourceToTargetMap.get2(s);
targetList.set(i, t);
}
}
else
{
for (S s : c.getRemoved())
{
T t = sourceToTargetMap.get2(s);
targetList.remove2(t);
sourceToTargetMap.remove2(s);
}
int i = c.getFrom();
for (S s : c.getAddedSubList())
{
T t = mapper.apply(s);
targetList.add(i, t);
sourceToTargetMap.put(s, t);
i += 1;
}
}
}
}
};
sourceList.addListener(new WeakListChangeListener<>(sourceListener));
// Store the listener in targetList to prevent GC
// The listener should be active as long as targetList exists
targetList.addListener((InvalidationListener) iv ->
{
Object[] refs = { sourceListener, };
Objects.requireNonNull(refs);
});
}
It can then be used like:
ObservableList<Bookmark> bookmarkList;
VBox bookmarkListVBox;
mapByValue(bookmarkList, bookmarkListVBox.getChildren(), bmk -> new Label(bmk.getName());
To automatically update the list (VBox's children) from observable list.
PS: other functions such as grouping are here => ObservableListHelper

how do I send colors to an ArrayList?

I am working on an assignment for school (mobile device applications programming) and I've run into an issue. Part of the assignment is to create an ArrayList of colors and then use a random number generator to randomly select a color set (for both text and background color) and apply it to the TextView. I am not sure I am populating the array properly. The parameters are set in a class called Colors_Class() I will include the class code as well as the method for populating the array here. I appreciate any and all help. thanks
here is the code for the Class
public class Color_Class
{
private int backgroundColor;
private int textColor;
public Color_Class(int color, int background)
{
textColor = color;
backgroundColor = background;
}
public int Get_Background_Color()
{
return backgroundColor;
}
public int Get_Text_Color()
{
return textColor;
}
}
Here is the method code
private void Create_Color_Objects()
{
Color_Class color1 = new Color_Class(Color.parseColor("#FF0000"), Color.parseColor("#FFFFFF"));
colorObjectList.add(color1);
Color_Class color2 = new Color_Class(Color.parseColor("#000000"), Color.parseColor("#FFe4c4"));
colorObjectList.add(color2);
Color_Class color3 = new Color_Class(Color.parseColor("#0000FF"), Color.parseColor("#SF9EA0"));
colorObjectList.add(color3);
Color_Class color4 = new Color_Class(Color.parseColor("#FFFFFF"), Color.parseColor("#8A2BE2"));
colorObjectList.add(color4);
Color_Class color5 = new Color_Class(Color.parseColor("#FF7F24"), Color.parseColor("#7FFF00"));
colorObjectList.add(color5);
Color_Class color6 = new Color_Class(Color.parseColor("#FFFFFF"), Color.parseColor("#DC143C"));
colorObjectList.add(color6);
Color_Class color7 = new Color_Class(Color.parseColor("#00008B"), Color.parseColor("#00FFFF"));
colorObjectList.add(color7);
Color_Class color8 = new Color_Class(Color.parseColor("#8B6508"), Color.parseColor("#A9A9A9"));
colorObjectList.add(color8);
Color_Class color9 = new Color_Class(Color.parseColor("#FFFFFF"), Color.parseColor("#8B0000"));
colorObjectList.add(color9);
Color_Class color10 = new Color_Class(Color.parseColor("#FFFFFF"), Color.parseColor("#8B3A3A"));
colorObjectList.add(color10);
}
Your code looks good, it would be better if you can use a generic version of your array list:
ArrayList<Color_Class> colorObjectList = new ArrayList<Color_Class>();

Categories