I was trying to draw a cubic line graph such as this:
using the MPAndroid chart library.
I am able to draw the line but not the fill between the X Axis and the line as shown in the picture.
Have gone through library and many SO questions.
I think you need this:
LineDataSet dataset = new LineDataSet(vals, null);
dataset.setDrawFilled(true);
setDrawFilled(boolean filled)
Set to true if the DataSet should be drawn filled (surface), and not just as a line, disabling this will give great performance boost! default: false
You can also control the transparency:
setFillAlpha(int alpha)
sets the alpha value (transparency) that is used for filling the line surface (0-255), default: 85
And color:
setFillColor(int color)
sets the color that is used for filling the line surface
To remove horizontal grid lines:
chart.getXAxis().setDrawGridLines(false);
For cubic lines:
dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
To Fill area below line, disable displayed values:
dataSet.setDrawFilled(true);
dataSet.setDrawValues(false);
Set fill color and line color:
dataSet.setFillColor(ContextCompat.getColor(contex,R.color.pale_green));
dataSet.setColor(ContextCompat.getColor(contex,R.color.pale_green));
Disable transparency (values range 0-255) and disable drawing circles on the main chart line:
dataSet.setFillAlpha(255);
dataSet.setDrawCircles(false);
Result:
edit1:
To disable legend and hide description:
chart.getDescription().setText("");
chart.getLegend().setEnabled(false);
and:
<color name="pale_green">#6BF3AD</color>
edit2: To disable right axis:
chart.getAxisRight().setEnabled(false);
edit3: Nearly forgot the last thing:
chart.getAxisLeft().setValueFormatter(new IAxisValueFormatter() {
#Override
public String getFormattedValue(float value, AxisBase axis) {
return String.format("%.2f $",value);
}
});
Related
I'm currently working on a project using MPAndroidChart and i want to make a LineChart to represent data per hour. I need this chart to have gradient line depending on values on yAxis.
eg. In the graph above i want the line to change the color when yAxis values are >50.
I didn't find any solution to my problem, so any suggestions or examples are welcome
I've recently had to face the exact same problem, and the solution was to define a linear gradient and apply it as a shader, like this:
(Warning: You'll notice that the code looks funny, and that is because it is xamarin code (i.e: C#, not java nor kotlin), but you'll be able to translate it easily, mostly you have to change the PascalCase for camelCase, and change some properties into setters and getter or vice versa, just use your IDE's intellisense)
[set your line chart, add the dataset, etc]
...
var gradient = new LinearGradient(0f, 0f, 0f, 100f,
[your first color], [your second color],
Shader.TileMode.Clamp);
var paint = vh.Chart.Renderer.PaintRender;
paint.SetShader(gradient);
...
[set axis, labels, grid, etc]
...
lineChart.Invalidate(); //this is to refresh the chart on the screen, you may need it or not depending on your code
In the code above you just have to add your colors, and you may want to change the gradient direction (I'm using a vertical gradient here) by changing the 4 first floats when creating the linearGradient. One typical change is to set the y0 = 0 and y1 = the height of your chart, for example. You have to play with the values according to your layout.
The result for this code is something like:
Of course, I'm showing it with a repeated sample dataset, that's why you are seeing two cards with the same line.
UPDATE:
I understand what you want to achieve, and with the code above you can do it. You will need some calculations, of course, but you can set the "trigger" where the color starts to change at any Y coordinate you want.
For example, in this first picture, I've used the coordinates 0,0,0,100
(Please keep in mind that I'm showing you the last value in dp, but in the real code I am translating it to the equivalent in pixels according to the device's resolution. It is roughly the height of my chart)
And in the following image, I've changed it to 0,0,0,50:
As you can see, you have full control over how the gradient is shown just by changing the 4 values. (or, in my case, just one of them)
(You may notice that I've changed the colors as per my design, it has nothing to do with the threshold)
Lets say you are using for-loop to populate your data. In list you need to populate a list of colors for every value and then use lineDataSet.setColors(listOfColors).
List<Integer> listOfColors = new List<>();
for(i= 0; i<dataEntries.size(); i++){
//Logic for colors
if(i<= dataEntries.size()-1){ //Otherwise app will crash on last index
if(dataEntries.get(i+1).y > 50)
listOfColors.add(Color.GREEN);
else
listOfColors.add(Color.RED);
}
Then in the last
lineDataSet.setColors(listOfColors)
Hope, this will help you.
Mpandroidchart: I am facing the issue with X-axis labels and marker, X-axis last value is not getting display and Marker is misplaced.
chart.getXAxis().setValueFormatter(new ValueFormatter() {
#Override
public String getFormattedValue(float value) {
return TimeUtils.getFormattedDateTime(dateValues.get((int) value), TimeUtils.MMM_DATE_ONLY_FORMAT);
}
});
MyMarkerView mv = new MyMarkerView(this, R.layout.custom_marker_view, getString(R.string.bpm), R.drawable.marker_green);
mv.setChartView(chart);
chart.setMarker(mv);
Can we add padding from the right? so the marker will take its place
Have a look at the attached image to understand the issue:- https://i.stack.imgur.com/GzqOU.png
https://i.stack.imgur.com/cs7Fx.png
After wasting a few hours on it, finally got the answer. I'm posting this answer for anyone else who has faced this issue.
Setting
chart.getXAxis().setSpaceMin(0.5f);
would add space between the X-axis line and the chart itself.
chart.getXAxis().setSpaceMax(0.5f);
for adding space between the last value and the right X-axis of the chart.
Sets the minimum interval between the y-axis values. This can be used to avoid value duplicating when zooming in to a point where the number of decimals set for the axis no longer allows to distinguish between two axis values.
xAxis.setGranularity(1f);
xAxis.setLabelCount(10);
After adding the above lines, the issue resolved! attached screenshot
https://i.stack.imgur.com/IxmWi.png
I've got the following line chart using MPAndroidChart:
Print of the first X position
Print of the last X position
I'm using the following method:
chart.setVisibleXRangeMaximum(5)
Which shows only 5 values on the viewport, the rest of them will be shown by scrolling.
I'm also using this method:
chart.setViewPortOffsets(0,25,0,40);
Which removes the left and right offset to make the chart covers whole screen and sets top and bottom offsets to have a space between the container it's placed in.
The problem is that both, first and last position got hidden into the device border. I think if there was a way to set a padding to these individual values, the problem could be fixed.
I tried to use some methods to change the space or offset of the X-axis, but neither of them worked.
I'm trying to create a chart like this where the entire filled dataset covers whole screen, but the first and last values are placed with a padding between the border of the device and the value itself.
The entire code of my chart is down bellow:
LineChart chart = view.findViewById(R.id.chartCalendar);
// Setting up the data
List<Entry> entries = new ArrayList<Entry>();
entries.add(new Entry(1,1200));
.....
// Creating dataset
LineDataSet dataSet = new LineDataSet(entries, "Label"); // add entries to dataset
// Dataset styling
dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
dataSet.setDrawFilled(true);
dataSet.setFillColor(ContextCompat.getColor(this.getActivity(), R.color.whiteBlue));
dataSet.setColor(ContextCompat.getColor(this.getActivity(), R.color.darkBlue));
dataSet.setLineWidth(2); // Line border thickness
dataSet.setCircleColor(ContextCompat.getColor(this.getActivity(), R.color.darkBlue)); // Border circle values color
// Setting up LineChart
LineData lineData = new LineData(dataSet);
// Styling chart
chart.setData(lineData);
chart.getAxisLeft().setDrawGridLines(false);
chart.getAxisRight().setDrawGridLines(false);
chart.getXAxis().setDrawGridLines(false);
chart.getXAxis().setAxisMaximum(31);
chart.setVisibleXRangeMaximum(5); // Show maximum 10 before scrolling
chart.getLegend().setEnabled(false);
chart.setDrawBorders(false);// Hide the description
chart.getXAxis().setTextColor(ContextCompat.getColor(this.getActivity(), R.color.white)); // Change X-axis label color
YAxis yAxis = chart.getAxisLeft();
yAxis.setTextColor(ContextCompat.getColor(this.getActivity(), R.color.white)); // change Y-axis label color
yAxis.setAxisLineColor(ContextCompat.getColor(this.getActivity(), R.color.darkBlue));
yAxis.setTextColor(ContextCompat.getColor(this.getActivity(), R.color.white));
// remove axis
YAxis leftAxis = chart.getAxisLeft();
leftAxis.setEnabled(false);
YAxis rightAxis = chart.getAxisRight();
rightAxis.setEnabled(false);
// X axis to bottom
chart.getXAxis().setPosition(XAxis.XAxisPosition.BOTTOM);
chart.getLineData().setValueTextColor(ContextCompat.getColor(this.getActivity(), R.color.white)); // Change value color
chart.getXAxis().setGranularity(1);
chart.setViewPortOffsets(0,25,0,40);
chart.getDescription().setEnabled(false);
// Refresh graph
chart.animateX(500);
Do you guys have any idea of how to fix it? Thanks!
To avoid the first and last values from being clipped, use your_chart.xAxis.setAvoidFirstLastClipping(true)
I have a simple linechart with MPAndroidChart library:
chart.setDrawYValues(false);
chart.setDescription("");
chart.setDrawVerticalGrid(true);
chart.setDrawGridBackground(false);
XLabels xl = holder.chart.getXLabels();
xl.setCenterXLabelText(true);
xl.setPosition(XLabelPosition.BOTTOM);
YLabels yl = holder.chart.getYLabels();
yl.setLabelCount(5);
// set data
chart.setData((LineData) mChartData);
chart.setDrawYValues(true);
chart.setValueTextSize(20f);
// zooming on both axis
chart.setPinchZoom(true);
chart.animateX(1000);
But I have a visualization problem. Labels on the X axis aren't under the relative grid line, but between the two lines (on Y axis I don't have this problem). Is there a way to put Y labels exactly under the relative grid line?
Calling this:
XLabels xl = chart.getXLabels();
xl.setCenterXLabelText(true);
will cause the labels to be drawn between the lines. If you call setCenterXLabelText(false); the labels should be exactly above the individual grid-lines.
Also check the example project LineChart. There the labels are exactly above the lines.
Update
There is no getXLabels method in version 3.1.0. Use this:
chart.xAxis.setCenterAxisLabels(true)
While using AChartEngine (JAR 1.0.0) for Android, I see a method that allows me to change the color of text for X-Axis (mRenderer.setXLabelsColor(Color.BLACK))
Unfortunately I am unable to find a corresponding method for the Y-Axis labels!
Also is there a way to set the color of the actual line graph?
I also tried to align the labels to the left of Y-Axis using
mRenderer.setYAxisAlign(Align.LEFT, 0);
mRenderer.setYLabelsAlign(Align.LEFT, 0);
but it does seem to function.
There is renderer.setYLabelsColor(); for setting the Y axis label color.
When you use Align.LEFT, it means they are left aligned, if you want to right align them on the left side of the axis, use Align.RIGHT.
The line graph color is the one from its own renderer.
To align and set a color properlly you need put it as follow:
mRenderer.setYAxisAlign(Align.LEFT, 0);
mRenderer.setYLabelsAlign(Align.RIGHT, 0);
// setYLabelsColor method you need include which the
// int for your YLabel, since this library you can
// use more than one YLabel, so in your case,
// you only have one YLabel and its index is 0.
mRenderer.setYLabelsColor(0, Color.BLACK);
mRenderer.setXLabelsColor(Color.BLACK);