So I'm using the awesome MPAndroid Chart library to make a simple LineChart. I was able to customize it heavily using the example project on GitHub.
The problem is, when I move it to my own code, certain methods are no longer able to be resolved:
mLineChart.setExtraOffsets() and mLineChart.setAutoScaleMinMaxEnabled() in particular. There might be others but these are the only two I've noticed.
Everything else works fine though. Any idea why I can't access these two methods? What should I dig into to find out more about why this is the case?
public class MyFragment extends Fragment {
private LineChart mLineChart;
// stuff here
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// stuff here
// Creating numbers line chart for candidate
LineChart numChart = (LineChart)view.findViewById(R.id.numbersLineChart);
setNumChart(numChart, mObject.getNums());
// stuff here
}
public void setNumChart(LineChart lineChart, List<Integer> nums){
mLineChart = lineChart;
mLineChart.setDrawGridBackground(false);
// no description text
mLineChart.setDescription("");
mLineChart.setNoDataTextDescription("You need to provide data for the chart.");
// enable value highlighting
mLineChart.setHighlightEnabled(true);
// enable touch gestures
mLineChart.setTouchEnabled(true);
// enable scaling and dragging
mLineChart.setDragEnabled(false);
mLineChart.setScaleEnabled(false);
// if disabled, scaling can be done on x- and y-axis separately
mLineChart.setPinchZoom(false);
// create a custom MarkerView (extend MarkerView and specify the layout to use for it)
MyMarkerViewv2 mv = new MyMarkerViewv2(getActivity(), R.layout.custom_marker_view, mLineChart);
// set the marker to the chart
mLineChart.setMarkerView(mv);
// disable all axes lines and labels
YAxis leftAxis = mLineChart.getAxisLeft();
leftAxis.setEnabled(false);
mLineChart.getAxisRight().setEnabled(false);
XAxis bottomAxis = mLineChart.getXAxis();
bottomAxis.setEnabled(false);
// add data
setLineChartData(nums);
//THIS METHOD CANNOT BE RESOLVED********************
mLineChart.setExtraOffsets(30f,50f,30f,0f);
// get the legend (only possible after setting data)
Legend l = mLineChart.getLegend();
l.setEnabled(false);
mLineChart.invalidate();
}
public void setLineChartData(List<Integer> nums){
//create xVariables aka strings of the months
ArrayList<String> xVals = new ArrayList<String>();
for (int i = 0; i < nums.size(); i++) {
xVals.add(Month.getMonthfromIndex(i).getAbbrev());
}
//add corresponding numbers
ArrayList<Entry> yVals = new ArrayList<Entry>();
for (int i = 0; i < nums.size(); i++) {
yVals.add(new Entry(nums.get(i), i));
}
// create a dataset and give it a type
LineDataSet set1 = new LineDataSet(yVals, "DataSet");
set1.setColor(Color.BLACK);
set1.setCircleColor(Color.BLACK);
set1.setLineWidth(0.75f);
set1.setDrawCircles(true);
set1.setDrawValues(false);
set1.setCircleSize(1.75f);
set1.setDrawCircleHole(false);
ArrayList<LineDataSet> dataSets = new ArrayList<LineDataSet>();
dataSets.add(set1); // add the datasets
// create a data object with the datasets
LineData data = new LineData(xVals, dataSets);
// set data
mLineChart.setData(data);
}
// stuff here
class MyMarkerViewv2 extends MarkerView {
private TextView markerContent;
private LineChart mChart;
public MyMarkerViewv2(Context context, int layoutResource, LineChart lChart) {
super(context, layoutResource);
mChart = lChart;
markerContent = (TextView) findViewById(R.id.markerContent);
}
// callbacks everytime the MarkerView is redrawn, can be used to update the
// content (user-interface)
#Override
public void refreshContent(Entry e, int dataSetIndex) {
if (e instanceof CandleEntry) {
CandleEntry ce = (CandleEntry) e;
List<String> months = mChart.getLineData().getXVals();
markerContent.setText(months.get(e.getXIndex() % 12) + "\n" + Utils.formatNumber(ce.getHigh(), 0, true) + "%");
} else {
List<String> months = mChart.getLineData().getXVals();
markerContent.setText(months.get(e.getXIndex() % 12) + "\n" + Utils.formatNumber(e.getVal(), 0, true) + "%");
}
}
#Override
public int getXOffset() {
// this will center the marker-view horizontally
return -(getWidth() / 2);
}
#Override
public int getYOffset() {
// this will cause the marker-view to be above the selected value
return -getHeight();
}
}
I also have the LineChart wrapped inside a vertical LinearLayout with other elements and that whole thing wrapped inside a ScrollView. Not sure if that's what's causing the problem or not.
Nevermind, I figured it out. It's because the library downloaded by Maven and Gradle is not exactly the same as the one included in the example project on the website.
Related
I am trying to highlight the LimiteLine (upper and lower limits) just like shown in GitHub Pull Request: Highlight Axis #4477.
Below is the image used as an example:
And not only that, I would like to custom the rectangle black box that contains the highlighted values.
I would also like them to be fixed, I mean: I don't want them to disappear when the chart is touched, while showing the MarkerView for the other points on the graph.
But it's not clear to me how to achieve this result.
I am using MPAndroid version 3.1.0 and LineChart
I am creating my LineChart from the example shown in https://blog.csdn.net/a8688555/article/details/80344159:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_settings, container, false);
mLineChart = view.findViewById(R.id.settings_graph);
List<Entry> entries = new ArrayList<>();
for (int i = 0; i < 12; i++)
entries.add(new Entry(i, new Random().nextInt(300)));
LineDataSet dataSet = new LineDataSet(entries, "Label"); // add entries to dataset
dataSet.setDrawCircles(false);
dataSet.setColor(Color.parseColor("#7d7d7d"));
dataSet.setCircleColor(Color.parseColor("#7d7d7d"));
dataSet.setLineWidth(3f);
mLineChart.setScaleEnabled(false);
mLineChart.setExtraRightOffset(15f);
mLineChart.setExtraLeftOffset(30f);
LimitLine upper_limit = new LimitLine(dataSet.getYMax(), "Preco maximo");
upper_limit.setLineWidth(2f);
upper_limit.enableDashedLine(10f, 10f, 0f);
upper_limit.setLabelPosition(LimitLine.LimitLabelPosition.RIGHT_TOP);
upper_limit.setTextSize(15f);
LimitLine lower_limit = new LimitLine(dataSet.getYMin(), "Preco minimo");
lower_limit.setLineWidth(2f);
lower_limit.enableDashedLine(10f, 10f, 0f);
lower_limit.setLabelPosition(LimitLine.LimitLabelPosition.RIGHT_BOTTOM);
lower_limit.setTextSize(15f);
// Setup Y-Axis
YAxis rightAxis = mLineChart.getAxisRight();
// Disable Y-axis on the right
rightAxis.setEnabled(true);
// Disable Y grid lines
rightAxis.setDrawGridLines(false);
rightAxis.setValueFormatter(new ValueFormatter() {
#Override
public String getFormattedValue(float value) {
return super.getFormattedValue(value);
}
});
YAxis leftAxis = mLineChart.getAxisLeft();
// Disable Y-axis on the left
leftAxis.setEnabled(false);
leftAxis.setDrawGridLines(false);
rightAxis.setAxisMaximum(dataSet.getYMax() + (float) (dataSet.getYMax() * 0.1));
leftAxis.setAxisMaximum(dataSet.getYMax() + (float) (dataSet.getYMax() * 0.1));
// Set max and min values
rightAxis.removeAllLimitLines();
rightAxis.addLimitLine(upper_limit);
rightAxis.addLimitLine(lower_limit);
rightAxis.setDrawLimitLinesBehindData(true);
// Setup X-Axis
XAxis xAxis = mLineChart.getXAxis();
xAxis.setTextColor(Color.parseColor("#333333"));
xAxis.setTextSize(11f);
xAxis.setAxisMinimum(0f);
xAxis.setDrawAxisLine(true);
xAxis.setDrawGridLines(false);
xAxis.setDrawLabels(true);
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setGranularity(1f);
String[] mValues = {"Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"};
xAxis.setValueFormatter(new ValueFormatter() {
#Override
public String getFormattedValue(float value) {
return mValues[(int) value];
}
});
// Transparent legend
Legend legend = mLineChart.getLegend();
legend.setForm(Legend.LegendForm.NONE);
legend.setTextColor(Color.WHITE);
mLineChart.setOnChartValueSelectedListener(new OnChartValueSelectedListener() {
#Override
public void onValueSelected(Entry e, Highlight h) {
Log.i(TAG, "onValueSelected: highlight is: "+h);
if (mLineChart.isMarkerAllNull()) {
Log.i(TAG, "onValueSelected: isMarkerAllNull()");
// adding the markers
createMakerView();
// highlight the custom marker
mLineChart.highlightValue(h);
}
}
#Override
public void onNothingSelected() {
}
});
// text on X-axis
Description description = new Description();
description.setEnabled(false);
mLineChart.setDescription(description);
// create objects on the chart
createMakerView();
//3. setup data
LineData lineData = new LineData(dataSet);
// Draw text over line
lineData.setDrawValues(false);
mLineChart.setData(lineData);
mLineChart.animateXY(1000, 500);
mLineChart.invalidate(); // refresh
// Inflate the layout for this fragment
return view;
}
public void createMakerView() {
DetailsMarkerView detailsMarkerView = new DetailsMarkerView(getContext());
detailsMarkerView.setChartView(mLineChart);
mLineChart.setDetailsMarkerView(detailsMarkerView);
mLineChart.setPositionMarker(new PositionMarker(getContext()));
mLineChart.setRoundMarker(new RoundMarker(getContext()));
}
The image below shows the result tha I am trying to achieve:
I appreciate any help!
I am trying to combine multiple line charts in a single view but i cannot solve problem with different data types. I've tried to use min-max normalization to scale values from different data sets but when i want to show selected value in custom marker view, i cannot convert it back to initial format.
I've tried to use different ValueFormatters for all my data sets but i have not achieved anything.
Normalization code:
private List<Entry> normalizeEntry(List<Entry> entries, int min, int max) {
for (int i = 0; i < entries.size(); i++) {
float lastValue = entries.get(i).getY();
float newValue = normalize(lastValue, min, max, 0, 100);
entries.set(i, new Entry(i, newValue));
}
return entries;
}
Picture which show what i want to achieve:
I was able to solve my problem by adding a parameter corresponding to the value before normalization to the constructor of the Entry object.
before:
new Entry(xValue, normalizedValue);
after:
new Entry(xValue, normalizedValue, initialValueWithOutputFormat);
Example:
entries.add(new Entry(i, normalizedValues.get(i), String.format("%.2f m", inputValues.get(i))));
Then, I can easily update custom marker like in following code:
public class CustomMarkerView extends MarkerView {
private TextView tvContent;
public CustomMarkerView(Context context, int layoutResource) {
super(context, layoutResource);
// this markerview only displays a textview
tvContent = findViewById(R.id.tvContent);
}
#Override
public void refreshContent(Entry e, Highlight highlight) {
tvContent.setText(String.valueOf(e.getData()));
super.refreshContent(e, highlight);
}
#Override
public MPPointF getOffset() {
return new MPPointF(-(getWidth() / 2), -getHeight());
}
}
I am developing a chart based application, I am using MPAndroidChart library, I need to place the text value inside of circle, i tried to display,Thanks for if any suggestions related this,
i attached a screenshot related to that issue. I need to be do like this
but i get like this image:
Thanks Again for helping this issue,
ArrayList<Entry> e1 = new ArrayList<Entry>();
float[] values = new float[]{48, 59, 79, 29, 39, 50, 60};
for (int i = 0; i < values.length; i++) {
e1.add(new Entry(values[i], i, "line3"));
}
int[] color = {Color.parseColor("#D13385"), Color.parseColor("#37D04E"), Color.parseColor("#33D1D1"), Color.parseColor("#D1C933")};
LineDataSet d1 = new LineDataSet(e1, "" + cnt);
d1.setColors(color);
d1.setLineWidth(3.0f);
d1.setCircleSize(7.0f);
d1.setDrawValues(true);
d1.setCircleColor(Color.parseColor("#891e9a"));
d1.setCircleColorHole(Color.parseColor("#891e9a"));
d1.setDrawHighlightIndicators(false);
d1.setDrawFilled(false);
d1.setFillAlpha(20);
d1.setHighlightLineWidth(50f);
d1.setValueTextSize(10f);
Currently it is not possible to change the position where the values are drawn by default. You will have to modify the library to get that behaviour.
It is a bit "hacky", but I've managed to achieve such layout You've provided by creating two sets of data and attaching them to same chart. One set (lets call it "dots") contains your data needed to be displayed as dots. The second one ("lines") is a bit offset downwards (y value minus some experimentally picked value). Now you can set no line displaying for "lines" and a lines for "dots", no values labels for "dots" and white labels for "lines" and by experimentally moving your y values back and forth you can achieve overlaying values labels from one chart on top of another ("dots" will be covered by "lines" values).
UPDATE:
Actually, I've an answer more elegant, that I've provided! Use Highlight[] and create array of highlights.
highlihts = new Highlight[values_dots.size()];
for (int i = 0; i < values_dots.size(); i++) {
Highlight h = new Highlight(values_dots.get(i).getX(),values_dots.get(i).getY(), 0);
highlihts[i] = h;
}
chart.highlightValues(highlihts);
In CustomMarkerView class position marker like so:
#Override
public MPPointF getOffset() {
return new MPPointF(-(getWidth() / 2), -(getHeight() / 2));
}
Boom
P.S. Philipp Jahoda, awesome library!
there was an easy way to do this
custom maker view
Marker view
public class MyMarkerView extends MarkerView {
private final TextView tvContent;
public MyMarkerView(Context context, int layoutResource) {
super(context, layoutResource);
tvContent = findViewById(R.id.tvContent);
}
// runs every time the MarkerView is redrawn, can be used to update the
// content (user-interface)
#SuppressLint("SetTextI18n")
#Override
public void refreshContent(Entry e, Highlight highlight) {
if (e instanceof CandleEntry) {
CandleEntry ce = (CandleEntry) e;
tvContent.setText(Utils.formatNumber(ce.getHigh(), 0, true)+(ce.getData()));
} else {
tvContent.setText(Utils.formatNumber(e.getY(), 0, true)+"\n "+(e.getData()));
}
super.refreshContent(e, highlight);
}
#Override
public MPPointF getOffset() {
return new MPPointF(-(getWidth() / 2), -getHeight());
}
}
and lastly in your activity
values.add(new Entry(i, val,"Custom message per value"));
Preview be like
example screen shot
there was an easy way to do this
custom maker view
<TextView
android:id="#+id/tvContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="7dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:text=""
android:textSize="12sp"
android:textColor="#android:color/white"
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall" />
Marker view class
public class MyMarkerView extends MarkerView {
private final TextView tvContent;
public MyMarkerView(Context context, int layoutResource) {
super(context, layoutResource);
tvContent = findViewById(R.id.tvContent);
}
// runs every time the MarkerView is redrawn, can be used to update the
// content (user-interface)
#SuppressLint("SetTextI18n")
#Override
public void refreshContent(Entry e, Highlight highlight) {
if (e instanceof CandleEntry) {
CandleEntry ce = (CandleEntry) e;
tvContent.setText(Utils.formatNumber(ce.getHigh(), 0, true)+(ce.getData()));
} else {
tvContent.setText(Utils.formatNumber(e.getY(), 0, true)+"\n "+(e.getData()));
}
super.refreshContent(e, highlight);
}
#Override
public MPPointF getOffset() {
return new MPPointF(-(getWidth() / 2), -getHeight());
}
}
and lastly in your activity
values.add(new Entry(i, val,"Custom message per value"));
Preview be like
example screen shot
There are two possibilities:
(1) Not so good: Shift the y-value of the label position
Two Data sets one for text and one for the line (including circles)
Modifiy the y-position for the text value with a constant offset
Pro: Easy
Con: The offset is not always constant (see offset is not always similar)
(2) Better: Override the drawValues method from LineChartRenderer
In LineChartRenderer.java -> drawValues the text is vertically shifted by this line:
drawValue(c, formatter.getPointLabel(entry), x, y - valOffset, dataSet.getValueTextColor(j / 2));
So to get rid of the "- valOffset":
1.Override the drawValues method
Create a new java file "CenteredTextLineChartRenderer.java" and override method drawValues from LineChartRenderer
2.Modify the y-valOffset to y+textHeight*0.35f
Add float textHeight = dataSet.getValueTextSize();
public class CenteredTextLineChartRenderer extends LineChartRenderer {
public CenteredTextLineChartRenderer(LineDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler) {
super(chart, animator, viewPortHandler);
}
//Modified drawValues Method
// Center label on coordinate instead of applying a valOffset
#Override
public void drawValues(Canvas c) {
if (isDrawingValuesAllowed(mChart)) {
List<ILineDataSet> dataSets = mChart.getLineData().getDataSets();
for (int i = 0; i < dataSets.size(); i++) {
ILineDataSet dataSet = dataSets.get(i);
float textHeight = dataSet.getValueTextSize();
if (!shouldDrawValues(dataSet) || dataSet.getEntryCount() < 1)
continue;
// apply the text-styling defined by the DataSet
applyValueTextStyle(dataSet);
Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());
// make sure the values do not interfear with the circles
int valOffset = (int) (dataSet.getCircleRadius() * 1.75f);
if (!dataSet.isDrawCirclesEnabled())
valOffset = valOffset / 2;
mXBounds.set(mChart, dataSet);
float[] positions = trans.generateTransformedValuesLine(dataSet, mAnimator.getPhaseX(), mAnimator
.getPhaseY(), mXBounds.min, mXBounds.max);
ValueFormatter formatter = dataSet.getValueFormatter();
MPPointF iconsOffset = MPPointF.getInstance(dataSet.getIconsOffset());
iconsOffset.x = Utils.convertDpToPixel(iconsOffset.x);
iconsOffset.y = Utils.convertDpToPixel(iconsOffset.y);
for (int j = 0; j < positions.length; j += 2) {
float x = positions[j];
float y = positions[j + 1];
if (!mViewPortHandler.isInBoundsRight(x))
break;
if (!mViewPortHandler.isInBoundsLeft(x) || !mViewPortHandler.isInBoundsY(y))
continue;
Entry entry = dataSet.getEntryForIndex(j / 2 + mXBounds.min);
if (dataSet.isDrawValuesEnabled()) {
//drawValue(c, formatter.getPointLabel(entry), x, y - valOffset, dataSet.getValueTextColor(j / 2));
drawValue(c, formatter.getPointLabel(entry), x, y+textHeight*0.35f, dataSet.getValueTextColor(j / 2));
}
if (entry.getIcon() != null && dataSet.isDrawIconsEnabled()) {
Drawable icon = entry.getIcon();
Utils.drawImage(
c,
icon,
(int)(x + iconsOffset.x),
(int)(y + iconsOffset.y),
icon.getIntrinsicWidth(),
icon.getIntrinsicHeight());
}
}
MPPointF.recycleInstance(iconsOffset);
}
}
}
}
3.Set your own LineChart renderer to your modified drawValues class
LineChart mChart = (LineChart) mainActivity.findViewById(R.id.LineChart);
mChart.setRenderer(new CenteredTextLineChartRenderer(mChart,mChart.getAnimator(),mChart.getViewPortHandler()));
Run your code and manually adapt the 0.35f offset in your CenteredTextLineChartRenderer class
Now your text is always vertically centered!
IMPORTANT: With deleting the valOffset your label is not vertically centered as the text anchor is not in the center of your text label. So you have to insert a manual offset "textHeight*0.35f" (just try it out). But the big advantage of method (2) is that the text is always centered with the same offset also for example in landscape mode and on other screen sizes...
I have the following chart which is displaying some values.
I would like to hide/ remove values on the right side, because on the left side are enough.
See image below:
And code is following:
public class MainActivity extends AppCompatActivity implements
OnChartValueSelectedListener{
private LineChart mDataLineChart;
private RelativeLayout mRelativeLayout;
private LineChart mChart;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_linechart);
// Set chart
setChart();
// add data
setData2(3, 155);
// ANIMATE CHART
animateChart();
}
private void setChart() {
mChart = (LineChart) findViewById(R.id.chart1);
mChart.setOnChartValueSelectedListener(this);
////////////////////////////////
// SET DESCRIPTION COLOR
////////////////////////////////
mChart.setDescriptionColor(getResources().getColor(R.color.chart_desc_color));
////////////////////////////////
// BORDERS SURROUNDING THE CHART
////////////////////////////////
mChart.setDrawBorders(true);
mChart.setBorderColor(getResources().getColor(R.color.chart_border));
mChart.setBorderWidth(2);
////////////////////////////////
// CHART BG COLOR
////////////////////////////////
mChart.setBackgroundColor(getResources().getColor(R.color.chart_bg));
////////////////////////////////
// GRID BG COLOR
////////////////////////////////
mChart.setDrawGridBackground(true);
mChart.setGridBackgroundColor(getResources().getColor(R.color.chart_bg));
////////////////////////////////
// OTHER SETTINGS
////////////////////////////////
mChart.setDescription("");
mChart.setNoDataTextDescription("You need to provide data for the chart.");
// enable touch gestures
mChart.setTouchEnabled(true);
mChart.setDragDecelerationFrictionCoef(0.9f);
// enable scaling and dragging
mChart.setDragEnabled(true);
mChart.setScaleEnabled(true);
mChart.setHighlightPerDragEnabled(true);
// if disabled, scaling can be done on x- and y-axis separately
mChart.setPinchZoom(true);
}
private void setData2(int count, float range) {
////////////////////////////////
// X axis values (labels)
////////////////////////////////
ArrayList<String> xVals = new ArrayList<String>();
for (int i = 0; i < count; i++) {
xVals.add((i) + " day");
}
////////////////////////////////
// Y axis values (value in linechart)
////////////////////////////////
ArrayList<Entry> yVals1 = new ArrayList<Entry>();
for (int i = 0; i < count; i++) {
float mult = range / 2f;
float val = (float) (Math.random() * mult) + 50;// + (float)
// ((mult *
// 0.1) / 10);
yVals1.add(new Entry(val, i));
}
////////////////////////////////
// SETTING FOR LINEAR LINE
////////////////////////////////
LineDataSet set1 = new LineDataSet(yVals1, "Pressure mm/Hg");
set1.setAxisDependency(AxisDependency.LEFT);
set1.setLineWidth(2f);
set1.setCircleSize(5f);
set1.setColor(getResources().getColor(R.color.chart_line_color));
set1.setCircleColor(getResources().getColor(R.color.chart_line_color));
set1.setFillColor(getResources().getColor(R.color.chart_line_color));
set1.setDrawCircleHole(true);
ArrayList<LineDataSet> dataSets = new ArrayList<LineDataSet>();
dataSets.add(set1); // add the datasets
////////////////////////////////
// SETTING FOR DATASET (FONT SIZE, )
////////////////////////////////
LineData data = new LineData(xVals, dataSets);
data.setValueTextColor(Color.BLACK);
data.setValueTextSize(9f);
////////////////////////////////
// SET WHOLE DATASET TO CHART
////////////////////////////////
mChart.setData(data);
}
private void animateChart() {
////////////////////////////////
// ANIMATION DURATION
////////////////////////////////
mChart.animateX(1000);
////////////////////////////////
// SET LEGEND BOTTOM DATA TEXT
////////////////////////////////
XAxis xAxis = mChart.getXAxis();
xAxis.setTextSize(12f);
xAxis.setTextColor(Color.BLACK);
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setSpaceBetweenLabels(1);
}
#Override
public void onValueSelected(Entry e, int dataSetIndex, Highlight h) {
Log.i("Entry selected", e.toString());
}
#Override
public void onNothingSelected() {
Log.i("Nothing selected", "Nothing selected.");
}
}
I tried to search in documentation on Github:
https://github.com/PhilJay/MPAndroidChart/wiki/The-Axis
But without luck.
How can i remove values from right please?
Many thanks for any advice.
YAxis yAxisRight = mChart.getAxisRight();
yAxisRight.setEnabled(false);
put this code on your setChart();
You may want to check example application and corresponding codes. The application includes 2 related examples: Line Chart and Line Chart (Dual YAxis). The first is what you want and the latter is what you have right know.
App link: https://play.google.com/store/apps/details?id=com.xxmassdeveloper.mpchartexample
Code: https://github.com/PhilJay/MPAndroidChart/tree/master/MPChartExample
I am using Android Graph View to display line graphs. I need to change the horizontal labels to have nice rounded numbers. In the screen shot attached the values are
1
11:15
22:29
33:44
I need to adjust the position of the horizontal labels and the vertical lines that come off of it so the labels read
0
11:00
23:00
33:44
The code for the above screen shot uses this base class
protected TextView text;
protected GraphView graph;
#Override
public View onCreateView(final LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.ride_chart_fragment, null, false);
graph = (GraphView) view.findViewById(R.id.graph);
if (graph==null){
Log.e("Rides","Graph should not ne null");
return view;
}
Series series = linePoints();
if (series==null) return view;
graph.getGridLabelRenderer().setNumHorizontalLabels(4);
graph.addSeries(series);
setViewport(graph, series);
text = (TextView)view.findViewById(R.id.textView);
text.setVisibility(View.INVISIBLE);
graph.getGridLabelRenderer().setLabelFormatter(new DefaultLabelFormatter() {
#Override
public String formatLabel(double value, boolean isValueX) {
if (isValueX) {
// show normal x values
return UnitConverter.secondsToInterval((float) value);
} else {
return super.formatLabel(value, isValueX) + units(new Settings(inflater.getContext()));
}
}
});
graph.getGridLabelRenderer().setLabelVerticalWidth((int)getResources().getDimension(R.dimen.graph_label_vertical_width));
graph.getGridLabelRenderer().setLabelHorizontalHeight((int)getResources().getDimension(R.dimen.graph_label_vertical_height));
graph.getGridLabelRenderer().setGridColor(Color.parseColor("#20000000"));
graph.getGridLabelRenderer().setGridStyle(GridLabelRenderer.GridStyle.BOTH);
//graph.getGridLabelRenderer().
return view;
}
and this child class to render the graph
protected Series linePoints() {
//RideDetailActivity activity = (RideDetailActivity)getActivity();
if (activity==null || activity.isFinishing() || activity.ride==null) return null;
Settings settings = new Settings(activity);
long rideId = activity.ride.sqlRide.getId();
LezyneLinkApplication application = (LezyneLinkApplication)activity.getApplicationContext();
DaoSession session = application.getDaoSession();
RideElevationDao table = session.getRideElevationDao();
List<RideElevation> elevations = table
.queryBuilder()
.where(RideElevationDao.Properties.RideId.eq(rideId))
.orderAsc(RideElevationDao.Properties.Index)
.list();
DataPoint dataPoints[] = new DataPoint[elevations.size()];
int index=0;
boolean isMetric = settings.isMetric();
for (RideElevation elevation : elevations){
double y = elevation.getY();
if (!settings.isMetric()){
y = UnitConverter.convertMetersToFeet(y);
}
DataPoint point = new DataPoint(elevation.getX(),y);
dataPoints[index] = point;
index++;
}
LineGraphSeries series = new LineGraphSeries<DataPoint>(dataPoints);
series.setDrawBackground(true);
series.setColor(Color.argb(0xFF, 0x8e, 0x00, 0xe8));
series.setBackgroundColor(Color.argb(0x3F, 0x47, 0x2c, 0x17));
series.setThickness(6);
return series;
}
#Override
protected void setViewport(GraphView graph,Series series) {
graph.getViewport().setXAxisBoundsManual(true);
graph.getViewport().setMaxX(series.getHighestValueX());
graph.getViewport().setYAxisBoundsManual(true);
double lowest = series.getLowestValueY();
double highest = series.getHighestValueY();
graph.getViewport().setMinY(lowest);
Settings settings = new Settings(context);
if (settings.isMetric()){
if (highest<lowest+121) highest = lowest+121;
}
else {
if (highest<lowest+400) highest = lowest+400;
}
graph.getViewport().setMaxY(highest);
}
Im not seeing any way of doing this with the library as is so I am considering changing the source code. Did I miss something in the API? Anybody have any suggestions about where in the code to add this functionality.
you have two ways:
1) (difficult) with dynamic viewport take a look into the source code and find the point where the humanRound is done (GridLabelRenderer.java)
understand it, and modify ;)
2) use a fixed viewport and calculate on your own the min and max bounds and you can change the numberOfHorizontalLabels to get the best match.