I am trying to integrate highcharts in my android app (inside fragment) but I am getting this error every time:
java.util.NoSuchElementException: HIOptions not found in HIChartView
Here is my onCreateView Method:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
parentView = inflater.inflate(R.layout.bar_layout, null);
return parentView;
}
How I am getting chart view:
chartView = parentView.findViewById(R.id.hc);
I am calling chart API to get to data after getting a response, I am setting options but it is giving me the same error, below is the code snippets how am I setting chart:
HIOptions options = new HIOptions();
HIChart chart = new HIChart();
chart.setType("column");
options.setChart(chart);
HIExporting hiExporting = new HIExporting();
hiExporting.setEnabled(false);
options.setExporting(hiExporting);
List<BarChartSeries> seriesList = barChartModel.getSeries();
if (!seriesList.isEmpty()) {
final HIXAxis xAxis = new HIXAxis();
HITitle xAxisTitle = new HITitle();
xAxisTitle.setText(getString(R.string.year));
xAxis.setTitle(xAxisTitle);
XAxisDto xAxisDto = barChartModel.getxAxis();
List<String> stringList1 = xAxisDto.getCategories();
ArrayList<String> xAxisList = new ArrayList<>();
xAxisList.addAll(stringList1);
xAxis.setCategories(xAxisList);
xAxis.setCrosshair(new HICrosshair());
ArrayList<HIXAxis> axes = new ArrayList<>();
axes.add(xAxis);
options.setXAxis(axes);
HIYAxis yAxis = new HIYAxis();
yAxis.setMin(0);
HITitle yAxisTitle = new HITitle();
yAxisTitle.setText(getString(R.string.no_of_cases));
yAxis.setTitle(yAxisTitle);
ArrayList<HIYAxis> yaxes = new ArrayList<>();
yaxes.add(yAxis);
options.setYAxis(yaxes);
HITooltip tooltip = new HITooltip();
tooltip.setHeaderFormat("<span style=\"font-size:10px\">{point.key}</span><table>");
tooltip.setPointFormat("<span style=\"font-size:10px\">{point.key}</span><table>");
tooltip.setFooterFormat("</table>");
tooltip.setShared(true);
tooltip.setUseHTML(true);
options.setTooltip(tooltip);
HIPlotOptions plotOptions = new HIPlotOptions();
HIColumn hiColumn = new HIColumn();
hiColumn.setPointPadding(0.2);
hiColumn.setBorderWidth(0);
plotOptions.setColumn(hiColumn);
options.setPlotOptions(plotOptions);
ArrayList<HISeries> dataSetList = new ArrayList<>();
if (seriesList.size() > 0) {
for (int i = 0; i < seriesList.size(); i++) {
BarChartSeries barChartSeries = seriesList.get(i);
String name = barChartSeries.getName();
List<Data> dataList = barChartSeries.getData();
HIColumn series1 = new HIColumn();
series1.setName(name);
List<String> stringList = xAxisDto.getCategories();
ArrayList<BarEntry> yVals = new ArrayList<BarEntry>();
ArrayList<Long> doubleArrayList = new ArrayList<>();
if (stringList != null) {
for (int j = 0; j < stringList.size(); j++) {
String cat = stringList.get(j);
int count = 0;
for (int ij = 0; ij < dataList.size(); ij++) {
Data data = dataList.get(ij);
if (data.getYear().equalsIgnoreCase(cat)) {
count++;
yVals.add(new BarEntry(ij, data.getCount()));
doubleArrayList.add(data.getCount());
break;
}
}
if (count == 0) {
yVals.add(new BarEntry(yVals.size() + 1, 0));
doubleArrayList.add(0l);
}
}
}
series1.setData(doubleArrayList);
dataSetList.add(series1);
}
}
options.setSeries(dataSetList);
ArrayList<HIColor> hiColors = new ArrayList<>();
hiColors.add(HIColor.initWithHexValue("FF0000"));
hiColors.add(HIColor.initWithHexValue("FFA500"));
hiColors.add(HIColor.initWithHexValue("808080"));
options.setColors(hiColors);
HITitle title = new HITitle();
title.setText("");
options.setTitle(title);
HISubtitle subtitle = new HISubtitle();
subtitle.setText("");
options.setSubtitle(subtitle);
HICredits hiCredits = new HICredits();
hiCredits.setEnabled(false);
options.setCredits(hiCredits);
chartView.setOptions(options);
What am I missing here? Or How to resolve this issue?
I am able to solve the issue.
Follow below steps to resolve the issues:
When you fragment view is visible
Get highchart Id
chartView = parentView.findViewById(R.id.hc);
Set empty options to chartView:
HIOptions options = new HIOptions();
chartView.setOptions(options);
Once you get the data from your API set options to chartView again and call reload method:
chartView.setOptions(options);
chartView.reload();
Add the dependency again
implementation 'com.highsoft.highcharts:highcharts:7.0.3'
in the build.gradle file(app)
In my case It worked Well
Related
I am displaying multiple rows in one header and there is 5 more categories like drama and I am doing the same job for them. My question is when I set the adapter categories displaying randomly.(assuming of request speed).For example I want the display Drama on the first line always. I gave them id of adapter's constructor but didn't work out. Code :
if (response.body().getItems().size() > 0) {
Log.d("Drama",""+response.body().getItems().size());
List<MovieItem> newMovieItems = response.body().getItems();
HeaderItem liveHeader = new HeaderItem("Drama");
LiveChannelPresenter liveChannelPresenter = new LiveChannelPresenter();
ArrayObjectAdapter liveRowAdapter = new ArrayObjectAdapter(liveChannelPresenter);
for (int i = 0; i < newMovieItems.size(); i++) {
movieItem2 = response.body().getItems().get(i);
liveRowAdapter.add(movieItem2);
}
mRowsAdapter.add(new ListRow(0,liveHeader,liveRowAdapter));
}
}
if (response.body().getItems().size() > 0) {
Log.d("Drama",""+response.body().getItems().size());
List<MovieItem> newMovieItems = response.body().getItems();
//sorted:
Arrays.sort(newMoviewItems, new Comparator() { some condition to sort });
HeaderItem liveHeader = new HeaderItem("Drama");
LiveChannelPresenter liveChannelPresenter = new LiveChannelPresenter();
ArrayObjectAdapter liveRowAdapter = new ArrayObjectAdapter(liveChannelPresenter);
for (int i = 0; i < newMovieItems.size(); i++) {
//note the change here \|/
movieItem2 = newMoviewItems.get(i);
liveRowAdapter.add(movieItem2);
}
mRowsAdapter.add(new ListRow(0,liveHeader,liveRowAdapter));
}
I have an activity in which there are many card views which when clicked should fetch the data from firebase firestore and plot the data in a histogram format using highcharts in android.On each card view click event the d of that cardview is passed in the firestore query and the related data is retrieved.But in my case, the card view works only on second click and also when a different card view is clicked it retains the value of the previous query and only on second click it shows the correct data.
Below is my code for the adapter view which has the cardviews.
DocumentReference docRef = rootRef.collection("Users").document(tId).collection("Subjects")
.document(subId).collection("Marks").document(testList.get(position).getMarksID());
holder.show_graph.setOnClickListener(v -> {
docRef.get().addOnSuccessListener(documentSnapshot -> {
mMarks = new HashSet<>();
if (documentSnapshot != null && documentSnapshot.exists()) {
Map<String, Object> hm = documentSnapshot.getData();
Set<String> a = hm.keySet();
for (String b : a) {
try {
holder.marks_obtained.setText((String)documentSnapshot.get(email));
if(!b.equals("Max_marks")){
Log.e( "onComplete: ", documentSnapshot.get(b+".com") + " " +documentSnapshot.getId() );
mMarks.add(Float.parseFloat((String)documentSnapshot.get(b+".com")));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
v = LayoutInflater.from(context).inflate(R.layout.graph_plot,null);
final View alertLayout = v;
try{
//HICharts
HIChartView chartView = alertLayout.findViewById(R.id.hc);
chartView.plugins = new ArrayList<>(Arrays.asList("histogram-bellcurve"));
HIOptions options = new HIOptions();
HIChart chart = new HIChart();
chart.setType("variwide");
options.setChart(chart);
HITitle title = new HITitle();
title.setText("Score Division");
options.setTitle(title);
HIXAxis xaxis1 = new HIXAxis();
HITitle ht = new HITitle();
ht.setText("Count");
xaxis1.setTitle(ht);
HIXAxis xaxis2 = new HIXAxis();
xaxis2.setTitle(new HITitle());
xaxis2.setOpposite(true);
options.setXAxis(new ArrayList<>(Arrays.asList(xaxis1, xaxis2)));
HIYAxis yaxis1 = new HIYAxis();
HITitle ht2 = new HITitle();
ht2.setText("Marks");
yaxis1.setTitle(ht2);
HIYAxis yaxis2 = new HIYAxis();
yaxis2.setTitle(new HITitle());
yaxis2.setOpposite(true);
options.setYAxis(new ArrayList<>(Arrays.asList(yaxis1, yaxis2)));
HILegend legend = new HILegend();
legend.setEnabled(true);
options.setLegend(legend);
HIHistogram series1 = new HIHistogram();
series1.setType("histogram");
series1.setName("Histogram");
series1.setXAxis(1);
series1.setYAxis(1);
series1.setBaseSeries("s1");
series1.setZIndex(-1);
HIScatter series2 = new HIScatter();
series2.setType("scatter");
series2.setName("Data");
Number[] series2_data = new Number[mMarks.size()];
int i = 0;
for(float m : mMarks){
series2_data[i] = m;
i++;
}
series2.setId("s1");
series2.setData(new ArrayList<>(Arrays.asList(series2_data)));
series2.setMarker(new HIMarker());
series2.getMarker().setRadius(2.5);
options.setSeries(new ArrayList<>(Arrays.asList(series1, series2)));
options.setExporting(new HIExporting());
options.getExporting().setEnabled(false);
chartView.setOptions(options);
AlertDialog.Builder alertBox = new AlertDialog.Builder(v.getRootView().getContext());
alertBox.setTitle("Graph");
alertBox.setView(alertLayout);
alertBox.setCancelable(false);
alertBox.setPositiveButton("Done", (dialog, which) -> dialog.dismiss());
AlertDialog dialog = alertBox.create();
dialog.show();
}
catch (NullPointerException e){
Log.e("",e.getLocalizedMessage());
}
finally {
if(mMarks != null){
mMarks.clear();
}
}
});
}
As #daniel_s mentioned its not the problem with the highcharts. And Its not the problem with the firebase too. Its in the way in which you have put your code.
Now I am not the right person to say anything about firebase but lets understand this.
Firebase works on asynchronous mechanism and all the methods of the firebase are of asynchronous type. So when you click on the Cardview both firebase method and highchart methods runs together and not one after the other.
To make this work according to your way you should do something like this:
holder.show_graph.setOnClickListener(v -> {
docRef.get().addOnSuccessListener(documentSnapshot -> {
mMarks = new HashSet<>();
if (documentSnapshot != null && documentSnapshot.exists()) {
Map<String, Object> hm = documentSnapshot.getData();
Set<String> a = hm.keySet();
for (String b : a) {
try {
holder.marks_obtained.setText((String)documentSnapshot.get(email));
if(!b.equals("Max_marks")){
Log.e( "onComplete: ", documentSnapshot.get(b+".com") + " " +documentSnapshot.getId() );
mMarks.add(Float.parseFloat((String)documentSnapshot.get(b+".com")));
}
} catch (Exception e) {
e.printStackTrace();
}
}
// All of your highcharts code here.....
v = LayoutInflater.from(context).inflate(R.layout.graph_plot,null);
final View alertLayout = v;
try{
//HICharts
HIChartView chartView = alertLayout.findViewById(R.id.hc);
chartView.plugins = new ArrayList<>(Arrays.asList("histogram-bellcurve"));
HIOptions options = new HIOptions();
HIChart chart = new HIChart();
chart.setType("variwide");
options.setChart(chart);
HITitle title = new HITitle();
title.setText("Score Division");
options.setTitle(title);
HIXAxis xaxis1 = new HIXAxis();
HITitle ht = new HITitle();
ht.setText("Count");
xaxis1.setTitle(ht);
HIXAxis xaxis2 = new HIXAxis();
xaxis2.setTitle(new HITitle());
xaxis2.setOpposite(true);
options.setXAxis(new ArrayList<>(Arrays.asList(xaxis1, xaxis2)));
HIYAxis yaxis1 = new HIYAxis();
HITitle ht2 = new HITitle();
ht2.setText("Marks");
yaxis1.setTitle(ht2);
HIYAxis yaxis2 = new HIYAxis();
yaxis2.setTitle(new HITitle());
yaxis2.setOpposite(true);
options.setYAxis(new ArrayList<>(Arrays.asList(yaxis1, yaxis2)));
HILegend legend = new HILegend();
legend.setEnabled(true);
options.setLegend(legend);
HIHistogram series1 = new HIHistogram();
series1.setType("histogram");
series1.setName("Histogram");
series1.setXAxis(1);
series1.setYAxis(1);
series1.setBaseSeries("s1");
series1.setZIndex(-1);
HIScatter series2 = new HIScatter();
series2.setType("scatter");
series2.setName("Data");
Number[] series2_data = new Number[mMarks.size()];
int i = 0;
for(float m : mMarks){
series2_data[i] = m;
i++;
}
series2.setId("s1");
series2.setData(new ArrayList<>(Arrays.asList(series2_data)));
series2.setMarker(new HIMarker());
series2.getMarker().setRadius(2.5);
options.setSeries(new ArrayList<>(Arrays.asList(series1, series2)));
options.setExporting(new HIExporting());
options.getExporting().setEnabled(false);
chartView.setOptions(options);
AlertDialog.Builder alertBox = new AlertDialog.Builder(v.getRootView().getContext());
alertBox.setTitle("Graph");
alertBox.setView(alertLayout);
alertBox.setCancelable(false);
alertBox.setPositiveButton("Done", (dialog, which) -> dialog.dismiss());
AlertDialog dialog = alertBox.create();
dialog.show();
}
catch (NullPointerException e){
Log.e("",e.getLocalizedMessage());
}
finally {
if(mMarks != null){
mMarks.clear();
}
}
}
});
Hope I was clear. If it worked then do accept my answer by clicking on the tick mark:)
I am using MPAndroidChart2.2.5 to draw charts in my project,which contains 2 group of BarDataand 1 group of LineData.When I use the BarData in Barchart,the bars shows well.But when I use the same BarData in CombinedChart,the position of the bars differs.Here's my activity.
Here's a screenshot:
.
public class CombinedChartActivity extends BaseActivity {
private CombinedChart combinedChart;
private BarChart barChart;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_combined_chart);
combinedChart = (CombinedChart) findViewById(R.id.chart);
barChart = (BarChart) findViewById(R.id.barChart);
initChart(combinedChart);
initChart(barChart);
barChart.setData(getBarData());
CombinedData combinedData = new CombinedData();
combinedData.setXVals(getXVals());
combinedData.setData(getLineData());
combinedData.setData(getBarData());
combinedChart.setData(combinedData);
}
private void initChart(BarLineChartBase barLineChartBase) {
barLineChartBase.setDescription("");
barLineChartBase.getAxisLeft().setEnabled(false);
barLineChartBase.getAxisRight().setEnabled(false);
barLineChartBase.getXAxis().setPosition(XAxis.XAxisPosition.BOTTOM);
barLineChartBase.getXAxis().setGridColor(R.color.white);
barLineChartBase.getXAxis().setAvoidFirstLastClipping(true);
barLineChartBase.setBackgroundColor(Color.WHITE);
}
private BarData getBarData() {
List<IBarDataSet> iBarDataSets = new ArrayList<>();
ArrayList<BarEntry> barEntries = new ArrayList<>();
for (int i = 0; i < 7; i++) {
BarEntry barEntry = new BarEntry(i + 1, i);
barEntries.add(barEntry);
}
BarDataSet barDataSet = new BarDataSet(barEntries, "Bar1");
barDataSet.setColor(Color.rgb(60, 220, 78));
barDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
ArrayList<BarEntry> barEntries2 = new ArrayList<>();
for (int i = 0; i < 7; i++) {
BarEntry barEntry = new BarEntry((float) (i + Math.random() * 10), i);
barEntries2.add(barEntry);
}
BarDataSet barDataSet1 = new BarDataSet(barEntries2, "Bar2");
barDataSet1.setColor(R.color.level_3);
barDataSet1.setAxisDependency(YAxis.AxisDependency.RIGHT);
iBarDataSets.add(barDataSet);
iBarDataSets.add(barDataSet1);
BarData barData = new BarData(getXVals(), iBarDataSets);[![enter image description here][1]][1]
return barData;
}
private LineData getLineData() {
ArrayList<Entry> entries = new ArrayList<>();
for (int i = 0; i < 7; i++) {
Entry entry = new Entry((float) (Math.random() * 10), i);
entries.add(entry);
}
List<ILineDataSet> iLineDataSets = new ArrayList<>();
LineDataSet lds1 = new LineDataSet(entries, "Line");
lds1.setLineWidth(0.2f);
lds1.setColor(R.color.level_3);
lds1.setDrawFilled(true);
lds1.setFillAlpha(150);
lds1.setFillColor(R.color.level_2);
lds1.setDrawValues(false);
lds1.setHighlightEnabled(true);
lds1.setDrawHorizontalHighlightIndicator(false);
lds1.setHighLightColor(R.color.white);
lds1.setDrawCubic(true);
lds1.setDrawCircles(true);
lds1.setCircleColor(R.color.white);
lds1.setCircleColorHole(R.color.theme_orange);
lds1.setAxisDependency(YAxis.AxisDependency.LEFT);
iLineDataSets.add(lds1);
LineData lineData = new LineData(getXVals(), iLineDataSets);
return lineData;
}
private List<String> getXVals() {
ArrayList<String> xVals = new ArrayList<>();
xVals.add("Monday");
xVals.add("Tuesday");
xVals.add("Wednesday");
xVals.add("Thursday");
xVals.add("Friday");
xVals.add("Saturday");
xVals.add("Sunday");
return xVals;
}
}
I use same BarData in both charts.What causes the difference.How can I make the bars in Combinedchart show as in the Barchart?
I'm building an Android TV app for which I've rewritten the loadRows() method as such:
private void loadRows(String[] CATEGORY_LIST) {
mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
int i;
for (i = 0; i < NUM_ROWS; i++) {
ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new ListRowPresenter());
HeaderItem header = new HeaderItem(i, CATEGORY_LIST[i]);
mRowsAdapter.add(new ListRow(header, listRowAdapter));
}
setAdapter(mRowsAdapter);
}
My problem is that the CATEGORY_LIST is being drawn twice: once when the app is launched, and once on a right arrow press.
When it is drawn on the right arrow press, the spaces between the items are a little bit bigger, so I assume that is a "feature" from ArrayObjectAdapter.
HeaderItem header1 = new HeaderItem(1, getString(R.string.pontos_title));
ArrayObjectAdapter listRowAdapter1 = new ArrayObjectAdapter(cardPresenter);
for (int z = 0; z < pontos.size() ; z++) {
listRowAdapter1.add(pontos.get(z));
}
mRowsAdapter.add(new ListRow(header1,listRowAdapter1));
ObjectAdapter mAdapter = getAdapter();
mAdapter.notifyItemRangeChanged(1, NewObjects.size()); //Line 1
If you want to update the item on the same line use, but remove first.
mRowsAdapter.removeItems(1, LastedObjects.size());// Line 1
how to implement expandalbelistview with not any child
I am new in android I want to implement and expandalbelistview in which some groups have children and some have none.
Try This
It works for me
mExpandableListView = (ExpandableListView) findViewById(R.id.grouplist);
groupCollection = new LinkedHashMap<>();
List<String> newsCategories = new ArrayList<>();
List<String> nullcats = new ArrayList<>();
nullcats.add(null);
ArrayList<Categories> categories1 = new ArrayList<>();
//dataSource is my DBOpen helper class
categories1 = dataSource.findAllCategories();
if (categories1 != null) {
for (int i = 0; i < categories1.size(); i++) {
newsCategories.add(categories1.get(i).getCatagory_name_en());
}
} else {
newsCategories.add(null);
}
groupCollection.put(groupList.get(0), nullcats);
groupCollection.put(groupList.get(1), newsCategories);
expandableListAdapter = new ExpandableListAdapter(this, groupList, groupCollection);
mExpandableListView.setAdapter(expandableListAdapter);