I am working in project in project that needs implement chart , I decide use MPAndroidChart its work just fine but I need some things done to be perfect to me
First can I change bars to specific image or it takes just images , as I have 3D image as bars in app design .
Second Can I put the legend to the right of chart in two line like image below and change legend text color
my java code
mChart = (BarChart) view.findViewById(R.id.chart);
mChart.setDescription("");
Legend mLegend = mChart.getLegend();
//mLegend.setPosition(Legend.LegendPosition.RIGHT_OF_CHART_CENTER);
FillBarChart(mChart);
}
private void FillBarChart(BarChart barChart) {
ArrayList<BarEntry> entries = new ArrayList<>();
entries.add(new BarEntry(87f, 0));
entries.add(new BarEntry(90f, 1));
ArrayList<String> labels = new ArrayList<>();
labels.add("Omeprazole 20 mg");
labels.add("Esomeprazole 40 mg");
BarDataSet dataSet = new BarDataSet(entries, " ");
dataSet.setBarSpacePercent(40f);
BarData barData = new BarData(labels, dataSet);
dataSet.setColors(new int[]{R.color.omeprazole_color , R.color.esomeprazole_color} , getActivity());
barChart.setData(barData);
barChart.animateY(3000 , Easing.EasingOption.EaseOutBack );
}
You can do that if you create a custom Chart class and overwrite the init().
In this method, the Chart initializes a LegendRenderer and this is the point you need to get in and make changes.
Create a custom LegendRenderer and make sure that all the measurements are in place for those drawable. drawForm() method will allow you to draw the images instead of the default forms (Circle, Square, Line).
Related
What I have done: I have created a pie chart using MPAndroidChart library and ended up having the legend in the left corner. I tried changing the pie chart width but then when the items increase legend tends to wrap to a second line.
What I expect: I want the legend to be in the center every time when it updates. Even legend wrap to the second line, I want it to be in the center. I would appreciate any suggestions on this.
Thank you!
<com.github.mikephil.charting.charts.PieChart
android:id="#+id/chart"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center_horizontal"
>
</com.github.mikephil.charting.charts.PieChart>
Activity Code :
private void setupPieChart(){
//pupulating list of PieEntires
List<PieEntry> pieEntires = new ArrayList<>();
for( int i = 0 ; i<time.length;i++){
pieEntires.add(new PieEntry(time[i],activity[i]));
}
PieDataSet dataSet = new PieDataSet(pieEntires,"");
dataSet.setColors(ColorTemplate.MATERIAL_COLORS);
PieData data = new PieData(dataSet);
//pie slices text value
data.setValueTextSize(10);
//Get the chart
pieChart.setData(data);
pieChart.invalidate();
pieChart.setCenterText("50%");
pieChart.setDrawEntryLabels(false);
pieChart.setContentDescription("");
//pieChart.setDrawMarkers(true);
//pieChart.setMaxHighlightDistance(34);
pieChart.setEntryLabelTextSize(12);
pieChart.setHoleRadius(75);
//to remove bottom left description
pieChart.getDescription().setEnabled(false);
//legend attributes
Legend legend = pieChart.getLegend();
legend.setForm(Legend.LegendForm.CIRCLE);
legend.setTextSize(12);
legend.setFormSize(20);
legend.setFormToTextSpace(2);
//to wrap legend text
legend.setWordWrapEnabled(true);
Log.d("legend " ,legend.getEntries().toString());
}
I was able to center the legend by adding the below line in setupPieChart() mentioned in the question above.
legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
I am working on a fluid simulation application using SWT and want to draw the final calculated density of fluid back to UI. Now I am thinking about using SWT canvas and GC, but GC seems only for drawing shapes and lines, without the ability to draw colored pixels
There are many simulation app in the website but none is implemented by SWT. Below is the expected result for this application:
Use GC.drawPoint to draw a single pixel, the colour will be that set with GC.setForeground.
Jonah's answer is the way to do it if you want to draw everything yourself.
I'm just posting this as an alternative:
There's a library called "JHC (Java Heat Map Control)" that you could use to draw your data.
It would look something like this:
The data is provided in the form of an int[][].
// Define scales
JHCScale<String> xScale = new JHCScale.String(new String[] { "X1", "X2", "X3" });
JHCScale<String> yScale = new JHCScale.String(new String[] { "Y1", "Y2", "Y3" });
// Configure
JHCLayout layout = new JHCLayout(false, 20, true, 20);
JHCConfiguration config = new JHCConfiguration("x-label", "y-label",
JHCGradient.GRADIENT_HEAT, layout);
// Create array
int[][] array = {{0,1,0}, {1,2,1}, {0,1,0}};
// Create data object
JHCData data = JHCData.create(array, Orientation.ROW, xScale, yScale);
// Create JHC widget
JHC jhc = new JHC(shell, SWT.NONE);
jhc.setData(data, config);
i'm trying to make an overlaid plot,
And my problem is that i can't bring the second plot to fit the second one.
Here is my first plot :
And here the second one :
And when i try to fit both, here is what i get :
So basically, i would like to fit the whole second plot between 0 and 30, how can i do this without losing any data?
First I tried using plot.mapDatasetToRangeAxis()
Then i tried with :
domain.setRange(0.00, 30.0);
domain.setTickUnit(new NumberTickUnit(1));
But i couldn't bring neither the first, nor the second one to work as i wish.
Do you have any other ideas? (except buying this - which i can't afford right now as a student).
Any help will be greatly appreciated :)
Oh and by the way the x-axis is a speed (forgot to draw it on the plot).
So here a very ugly photomontage of the kind of result i wish to have (with fitting units on the x and y axis) :
Sorry for my Gimp skills, which are beyond bad.
Here is what i did :
private JFreeChart createOverlaidChart()
{
final NumberAxis domainAxis = new NumberAxis("Speed (m / s)");
final ValueAxis rangeAxis = new NumberAxis("Power (kw)");
// create plot ...
final IntervalXYDataset data0 = createDataset0();
final XYItemRenderer renderer0 = new XYBarRenderer(0.20);
// change "new XYBarRenderer(0.20)" to "StandardXYItemRenderer()" if you want to change type of graph
final XYPlot plot = new XYPlot(data0, domainAxis, rangeAxis, renderer0);
// add a second dataset and renderer...
final IntervalXYDataset data1 = createDataset1();
final XYLineAndShapeRenderer renderer1 = new XYLineAndShapeRenderer(false, true);
// arguments of new XYLineAndShapeRenderer are to activate or deactivate the display of points or line. Set first argument to true if you want to draw lines between the points for e.g.
plot.setDataset(1, data1);
plot.setRenderer(1, renderer1);
// add a third dataset and renderer...
final IntervalXYDataset data2 = createDataset2();
final XYLineAndShapeRenderer renderer2 = new XYLineAndShapeRenderer(true, true);
// arguments of new XYLineAndShapeRenderer are to activate or deactivate the display of points or line. Set first argument to true if you want to draw lines between the points for e.g.
plot.setDataset(2, data2);
plot.setRenderer(2, renderer2);
plot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD);
// return a new chart containing the overlaid plot...
return new JFreeChart("Test", JFreeChart.DEFAULT_TITLE_FONT, plot, true);
}
The Range Axis is the Vertical/Y Axis, you need to add a second Domain Axis (Horizontal/X Axis) to your chart.
I did something similar -- although using same X axis vales but differing Y axis. For this, I use single Domain (you'd want single Range). I convert for you (there may be typos due to my edits):
priceXYPlot.setRangeAxis( new new NumberAxis( "Y" ) );
priceXYPlot.setDomainAxis( 0, new NumberAxis( "X1" ) );
priceXYPlot.setDomainAxis( 1, new NumberAxis("X2") );
and mapDatasetToRangeAxis so that you had two diff X axis along top & bottom, something like:
priceXYPlot.setDataset( 0, data0);
priceXYPlot.mapDatasetToDomainAxis( 0, 0 ); //1st dataset to 1st x-axis
priceXYPlot.setDataset( 1, data1 );
priceXYPlot.mapDatasetToDomainAxis( 1, 1 ); //2nd dataset to 2nd x-axis
Can someone tell me how to change samples of series color in legend in jfreechart. What I have now is small line of series color eg: I would like to have square sample of those colors. Here is an example
Can someone help me?
Ok I found the solution. At least I think. Of course there is no simple way to do this. There is now, you know, setShape(square) method, that will do the trick, at least i haven't found one.
Basicly XY chart and time chart have "line style" legend by default in contrary to bar chart for example (if has square legend by default). So I had to remove current legend and create new one with square samples of color and this new legend add to my time chart.
LegendItemCollection legend = new LegendItemCollection();
for (int i = 0; i < seriecCount; ++i) {
chart.getXYPlot().getRenderer().setSeriesPaint(i, colorPalette.get(i));
LegendItem li = new LegendItem(data.getSeriesName(i), "-", null, null, Plot.DEFAULT_LEGEND_ITEM_BOX, colorPalette.get(i));
legend.add(li);
}
chart.getXYPlot().setFixedLegendItems(legend);
Thanks for attention. I hope it will help someone.
Generating your own legend, as you do above, is a perfectly acceptable way of doing things in JFreeChart. If you didn't want to do it, you can also define your own renderer with the lookupLegendShape() method overridden.
thePlot.setRenderer(new XYLineAndShapeRenderer()
{
public Shape lookupLegendShape(int series)
{
return new Rectangle(15, 15);
}
});
If you use a XYBarRenderer Class XYBarRenderer
(Subclasses: ClusteredXYBarRenderer, StackedXYBarRenderer)
You can use XYBarRenderer.setLegendBar(java.awt.Shape bar);
See: Javadoc
to get nice squares.
Example:
JFreeChart chart = ChartFactory.createXYBarChart(/*...*/);
XYPlot plot = (XYPlot) chart.getPlot();
ClusteredXYBarRenderer renderer = new ClusteredXYBarRenderer();
renderer.setLegendBar(new Rectangle(17, 17));
plot.setRenderer(renderer);
Is it possible to draw a 3D chart using JfreeChart like in the following link.If possible can anyone give some hints and some snippets of code on what parameters of Plot can be used to do this.
link text
It's possible though it won't look exactly the same. The easiest way is to create a dataset (descendant of org.jfree.data.general.PieDataset) and use one of org.jfree.chart.ChartFactory methods:
PieDataset data = new DefaultPieDataset();
data.setValue("Section1", 30);
data.setValue("Section2", 60);
data.setValue("Section3", 120);
JFreeChart pieChart = ChartFactory.createPieChart3D(
"My Pie Chart", // title
data, // data set
true, // draw a legend
true, // show tooltips over sections
false); // do not generate image map with URLs
You can then further customize your chart through pieChart methods. For example, here's how to explode one pie section:
PiePlot plot = (PiePlot) pieChart.getPlot();
plot.setExplodePercent("Section2", 0.25);