问题
If have an SQLite which stores 3 values names,credits,bunks. I have an mpandroid bar chart with x-axis:names,y-axis:bunks. I want to change the individual bar color or add limitline based on their credits for each entry,stored in SQLite. Is this possible? I am new to this please help me out.
public class Myhelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME="mydatabase.db";
public static final String TABLE_NAME="mytable";
public static final String COLUMN_ID="_id";
public static final String COL_1="NAME";
public static final String COL_2="CREDIT";
public static final String COL_3="BUNKS";
public static final String[] COLUMNS ={COLUMN_ID,COL_1,COL_2,COL_3};
Context con;
public Myhelper(Context context) {
super(context, DATABASE_NAME, null, 1);
con = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
String createTable= "CREATE TABLE " + TABLE_NAME + " (" + COLUMN_ID +" INTEGER PRIMARY KEY AUTOINCREMENT, " + " NAME TEXT, CREDIT TEXT, BUNKS INTEGER )";
db.execSQL(createTable);
Toast.makeText(con,"table created",Toast.LENGTH_SHORT).show();
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS "+ TABLE_NAME);
onCreate(db);
}
public boolean insertData(String x,String y,int z){
SQLiteDatabase db=this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL_1, String.valueOf(x));
contentValues.put(COL_2,String.valueOf(y));
contentValues.put(COL_3,z);
long result = db.insert(TABLE_NAME, null, contentValues);
if (result == -1) {
return false;
} else {
return true;
}
}
public ArrayList<String> queryXdata(){
ArrayList<String> xnewdata= new ArrayList<String>();
String query = "SELECT "+ COL_1 + " FROM " + TABLE_NAME;
SQLiteDatabase db=this.getWritableDatabase();
Cursor cursor= db.rawQuery(query,null);
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()){
xnewdata.add(cursor.getString(cursor.getColumnIndex(COL_1)));
}
cursor.close();
return xnewdata;
}
public ArrayList<Integer> queryYdata(){
ArrayList<Integer> ynewdata= new ArrayList<Integer>();
String query = "SELECT "+ COL_3+ " FROM " + TABLE_NAME;
SQLiteDatabase db=this.getWritableDatabase();
Cursor cursor= db.rawQuery(query,null);
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()){
ynewdata.add(cursor.getInt(cursor.getColumnIndex(COL_3)));
}
cursor.close();
return ynewdata;
}
public ArrayList<Integer> queryZdata(){
ArrayList<Integer> znewdata= new ArrayList<Integer>();
String query = "SELECT "+ COL_2+ " FROM " + TABLE_NAME;
SQLiteDatabase db=this.getWritableDatabase();
Cursor cursor= db.rawQuery(query,null);
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()){
znewdata.add(((cursor.getColumnIndex(COL_2))));
}
cursor.close();
return znewdata;
}
public attendence getdetails(long id){
SQLiteDatabase db = this.getWritableDatabase();
String query= "SELECT" + COL_2+" FROM " + TABLE_NAME +" WHERE _id=" + id;
Cursor cursor= db.rawQuery(query,null);
attendence attendence1= new attendence();
if (cursor.getCount()>0){
cursor.moveToFirst();
attendence1.setSubname(cursor.getString(cursor.getColumnIndex(COL_1)));
attendence1.setCredit(cursor.getString(cursor.getColumnIndex(COL_2)));
attendence1.setBunks(cursor.getInt(cursor.getColumnIndex(COL_3)));
}
return attendence1;
}
public void delete(long id,Context context){
SQLiteDatabase db=this.getWritableDatabase();
db.execSQL("DELETE FROM "+TABLE_NAME+" WHERE _id='"+id+"'");
Toast.makeText(context,"delted",Toast.LENGTH_SHORT).show();
}
public List<attendence> list(String filter){
String query;
if (filter.equals("")){
query = "SELECT * FROM " + TABLE_NAME ;
}
else {
query= " SELECT * FROM " + TABLE_NAME ;
}
List<attendence> linkedlist = new LinkedList<>();
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query,null);
attendence attendence;
if (cursor.moveToFirst()){
do {
attendence = new attendence();
attendence.setId(cursor.getLong(cursor.getColumnIndex(COLUMN_ID)));
attendence.setSubname(cursor.getString(cursor.getColumnIndex(COL_1)));
attendence.setCredit(cursor.getString(cursor.getColumnIndex(COL_2)));
attendence.setBunks(cursor.getInt(cursor.getColumnIndex(COL_3)));
linkedlist.add(attendence);
}
while (cursor.moveToNext());
}
return linkedlist;
}
public int getbunk(long id) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_NAME + " WHERE " + COLUMN_ID + " = " + String.valueOf(id), null);
int output = -1;
if (cursor != null) {
if (cursor.moveToFirst()) {
output = cursor.getInt(cursor.getColumnIndex(COL_3));
}
cursor.close();
}
return output;
}
public int updatebunk(long id){
SQLiteDatabase db = this.getWritableDatabase();
int bunk = getbunk(id);
if (bunk<0){
Log.i("error", "updatebunk:below 0 ");
}
int bunkinc= ++bunk;
ContentValues contentValues= new ContentValues();
contentValues.put(COL_3, bunkinc);
db.update(TABLE_NAME,contentValues,COLUMN_ID+ "=?",new String[]{String.valueOf(id)});
db.close();
return bunkinc;
}
public int updatebunkdelete(long id){
SQLiteDatabase db = this.getWritableDatabase();
int bunk = getbunk(id);
int bunkdec= --bunk;
ContentValues contentValues= new ContentValues();
contentValues.put(COL_3,bunkdec);
db.update(TABLE_NAME,contentValues,COLUMN_ID+ "=?",new String[]{String.valueOf(id)});
db.close();
return bunkdec;
}
}
my activity(bar chart)
public void addData(){
ArrayList<BarEntry> yVals = new ArrayList<>();
for (int i=0; i<myhelper.queryYdata().size(); i++){
yVals.add(new BarEntry((((myhelper.queryYdata().get(i)))),i));
}
ArrayList<String> xvals= new ArrayList<>();
for (int i=0;i<myhelper.queryXdata().size();i++){
xvals.add(myhelper.queryXdata().get(i));
}
MyBarDataset dataSet= new MyBarDataset(yVals,"");
dataSet.setColors(new int[]{ContextCompat.getColor(mcontext,R.color.green),
ContextCompat.getColor(mcontext,R.color.yellow),
ContextCompat.getColor(mcontext,R.color.red)});
BarData data = new BarData(xvals,dataSet);
mychart.setData(data);
//bar custamization
mychart.animateY(1000);
mychart.setDrawGridBackground(false);
mychart.setBackgroundColor(Color.WHITE);
mychart.getXAxis().setPosition(XAxis.XAxisPosition.BOTTOM);
mychart.getAxisRight().setEnabled(false);
mychart.setDescription("");
mychart.getLegend().setEnabled(false);
mychart.getXAxis().setDrawGridLines(false);
mychart.getAxisLeft().setDrawGridLines(false);
mychart.getAxisLeft().setStartAtZero(true);
mychart.getAxisLeft().setAxisMinValue(0);
}
public class MyBarDataset extends BarDataSet{
public MyBarDataset(List<BarEntry> yVals, String label) {
super(yVals, label);
}
@Override
public int getColor(int index){
if (getEntryForXIndex(index).getVal()<8){
return mColors.get(0);
}
else if (getEntryForXIndex(index).getVal()<13)
return mColors.get(1);
else
return mColors.get(2);
}
}
回答1:
As I understand it, you want to plot the bars based on bunk
but color them based on credits
. Using the custom bar dataset is the right approach, just need to modify it a bit. The code below gets what you're describing.
Changes I made:
- Cannot pass list of names to
BarData
, use an axis value formatter instead - Changed custom bar dataset to also hold the
credits
array. Not sure if yourgetEntryForXIndex
method is defined elsewhere, but it's not in the code you posted. - Removed deprecated calls and invalid syntax (can't call
setDescription("");
)
If this isn't what you're looking for, update the question with more detail about what you're seeing etc... As far as I could tell the question was about the chart and not about the SQL database.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BarChart chart = findViewById(R.id.test_chart);
// Some made up data - replace these with your
// queryYdata, queryXdata, and queryZdata methods
String[] names = new String[]{"foo","bar","fiz","bam","boo"};
List<Float> credits = new ArrayList<>(Arrays.asList(1f,9f,2.5f,15f,50f));
float[] bunks = new float[]{10f,15f,16f,20f,5f};
List<BarEntry> entries = new ArrayList<>();
for(int i = 0; i < bunks.length; ++i) {
entries.add(new BarEntry(i, bunks[i]));
}
float textSize = 16f;
MyBarDataset dataSet = new MyBarDataset(entries, "data", credits);
dataSet.setColors(ContextCompat.getColor(this,R.color.green),
ContextCompat.getColor(this,R.color.yellow),
ContextCompat.getColor(this,R.color.red));
BarData data = new BarData(dataSet);
data.setDrawValues(false);
data.setBarWidth(0.9f);
chart.setData(data);
chart.setFitBars(true);
chart.getXAxis().setValueFormatter(new IndexAxisValueFormatter(names));
chart.getXAxis().setPosition(XAxis.XAxisPosition.BOTTOM);
chart.getXAxis().setTextSize(textSize);
chart.getAxisLeft().setTextSize(textSize);
chart.setExtraBottomOffset(10f);
chart.getAxisRight().setEnabled(false);
Description desc = new Description();
desc.setText("");
chart.setDescription(desc);
chart.getLegend().setEnabled(false);
chart.getXAxis().setDrawGridLines(false);
chart.getAxisLeft().setDrawGridLines(false);
chart.invalidate();
}
public class MyBarDataset extends BarDataSet{
private List<Float> credits;
MyBarDataset(List<BarEntry> yVals, String label, List<Float> credits) {
super(yVals, label);
this.credits = credits;
}
@Override
public int getColor(int index){
float c = credits.get(index);
if (c < 8){
return mColors.get(0);
}
else if (c < 13) {
return mColors.get(1);
}
else {
return mColors.get(2);
}
}
}
EDIT: An aside about the SQL database - don't call queryXData
and queryYData
inside the loop! This will extract the entire data array every loop iteration, then again inside the loop itself (very expensive). Just use something like this instead:
ArrayList<BarEntry> yVals = new ArrayList<>();
ArrayList<Integer> yData = myhelper.queryYdata();
for (int i=0; i<yData.size(); i++){
yVals.add(new BarEntry(i,yData.get(i)));
}
ArrayList<String> xData = myhelper.queryXdata();
来源:https://stackoverflow.com/questions/51618305/how-to-change-bar-color-in-mpandroidcharts-based-on-some-individual-value-stored