No legends appears in my bar and pie charts.
I tried several arguments for setLegendPlacement and setLegendPosition methods but it was without results.
Where I went wrong ?
This is my config for the bar chart :
BarChartModel model = new BarChartModel();
model.setZoom(true);
model.setLegendPlacement(LegendPlacement.INSIDE);
model.setLegendPosition("ne");
model.setAnimate(true);
model.setMouseoverHighlight(true);
model.setShowPointLabels(true);
ChartSeries myChartSeries = new ChartSeries();
bank.setLabel("myChatSeries");
for (String key : datas.keys()) {
bank.set(key, datas.get(key));
}
model.addSeries(myChartSeries);
Axis yAxis = model.getAxis(AxisType.Y);
yAxis.setLabel(status.name());
yAxis.setMin(0);
yAxis.setMax(maxCount+1);
yAxis.setTickInterval("2");
Axis xAxis = model.getAxis(AxisType.X);
xAxis.setTickAngle(-20);
This is my config for the pie chart :
PieChartModel model = new PieChartModel();
model.setLegendPosition("ne");
model.setLegendPlacement(LegendPlacement.INSIDE);
model.setTitle("Informations général");
model.setMouseoverHighlight(true);
model.setShowDataLabels(true);
model.set("type1", 3);
model.set("type2", 6);
model.set("type3", 8);
My stack : java 8, jsf 2.1.28, primefaces 5.1, primefaces-themes 1.0.10
Resolved by setting the property legend.show to true on a hook before drawing :
$.jqplot.preDrawHooks.push(function () {
this.legend.show = true;
});
A little trashy hack somehow, Primefaces 5.1 doesn't seem to set this property by default.
Related
As we have upgraded to net core 6 we are rewriting some of our code base. We have a tag helper in AspNet Core which generates a barcode. This currently uses System.Drawing and ZXing.
TagHelper Old version using System.Drawing - working (top barcode)
public override void Process(TagHelperContext context, TagHelperOutput output)
{
var margin = 0;
var qrCodeWriter = new ZXing.BarcodeWriterPixelData
{
Format = ZXing.BarcodeFormat.PDF_417,
Options = new ZXing.Common.EncodingOptions
{
Height = this.Height > 80 ? this.Height : 80,
Width = this.Width > 400 ? this.Width : 400,
Margin = margin
}
};
var pixelData = qrCodeWriter.Write(QRCodeContent);
// creating a bitmap from the raw pixel data; if only black and white colors are used it makes no difference
// that the pixel data ist BGRA oriented and the bitmap is initialized with RGB
using (var bitmap = new Bitmap(pixelData.Width, pixelData.Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb))
using (var ms = new MemoryStream())
{
var bitmapData = bitmap.LockBits(new Rectangle(0, 0, pixelData.Width, pixelData.Height),
System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
try
{
// we assume that the row stride of the bitmap is aligned to 4 byte multiplied by the width of the image
System.Runtime.InteropServices.Marshal.Copy(pixelData.Pixels, 0, bitmapData.Scan0,
pixelData.Pixels.Length);
}
finally
{
bitmap.UnlockBits(bitmapData);
}
// save to stream as PNG
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
output.TagName = "img";
output.Attributes.Clear();
output.Attributes.Add("width", Width);
output.Attributes.Add("height", Height);
output.Attributes.Add("alt", Alt);
output.Attributes.Add("src",
$"data:image/png;base64,{Convert.ToBase64String(ms.ToArray())}");
}
}
TagHelper new version using ImageSharp - almost working but not exactly (bottom barcode)
public override void Process(TagHelperContext context, TagHelperOutput output)
{
var margin = 0;
var barcodeWriter = new ZXing.ImageSharp.BarcodeWriter<SixLabors.ImageSharp.PixelFormats.La32>
{
Format = ZXing.BarcodeFormat.PDF_417,
Options = new ZXing.Common.EncodingOptions
{
Height = this.Height > 80 ? this.Height : 80,
Width = this.Width > 400 ? this.Width : 400,
Margin = margin
}
};
var image = barcodeWriter.Write(QRCodeContent);
output.TagName = "img";
output.Attributes.Clear();
output.Attributes.Add("width", Width);
output.Attributes.Add("height", Height);
output.Attributes.Add("alt", Alt);
output.Attributes.Add("src", $"{image.ToBase64String(PngFormat.Instance)}");
}
The issue is as mentioned the 2nd barcode is very slightly different at the end seems to extend the last bar.
What am I missing?
That is a bug in the renderer implementation of the ZXing.Net binding to ImageSharp.
https://github.com/micjahn/ZXing.Net/issues/422
It is fixed in the newest nuget package of the bindings.
https://www.nuget.org/packages/ZXing.Net.Bindings.ImageSharp/
https://www.nuget.org/packages/ZXing.Net.Bindings.ImageSharp.V2/
I need to change the background color of the currently tabbed page in my UITabBarController. I've searched through every stackoverflow post I could find but nothing worked for me. I thought there would be something like UITabBar.Appearance.SelectedImageTintColor, just for the background color but it doesn't seem so.
For example, I want to change the color of that part when I am on the right tab:
Does someone know how to do that?
You could invoked the following code in your UITabBarController
public xxxTabBarController()
{
//...set ViewControllers
this.TabBar.BarTintColor = UIColor.Red;
}
Update
//3.0 here is if you have three child page in tab , set it as the current value in your project
//
var size = new CGSize(TabBar.Frame.Width / 3.0, IsFullScreen());
this.TabBar.SelectionIndicatorImage = ImageWithColor(size,UIColor.Green);
double IsFullScreen()
{
double height = 64;
if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
{
if (UIApplication.SharedApplication.Delegate.GetWindow().SafeAreaInsets.Bottom > 0.0)
{
height = 84;
}
}
return height;
}
UIImage ImageWithColor(CGSize size, UIColor color)
{
var rect = new CGRect(0, 0, size.Width, size.Height);
UIGraphics.BeginImageContextWithOptions(size, false, 0);
CGContext context = UIGraphics.GetCurrentContext();
context.SetFillColor(color.CGColor);
context.FillRect(rect);
UIImage image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return image;
}
The trick is to use the SelectionIndicatorImage Property of the UITabBar and generate a completely filled image with your desired color using the following method:
private UIImage ImageWithColor(CGSize size)
{
CGRect rect = new CGRect(0, 0, size.Width, size.Height);
UIGraphics.BeginImageContext(size);
using (CGContext context = UIGraphics.GetCurrentContext())
{
context.SetFillColor(UIColor.Green); //change color if necessary
context.FillRect(rect);
}
UIImage image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return image;
}
To initialize everything we override ViewWillLayoutSubviews() like this:
public override void ViewWillLayoutSubviews()
{
base.ViewWillLayoutSubviews();
// The tabbar height will always be 49 unless we force it to reevaluate it's size on runtime ...
myTabBar.InvalidateIntrinsicContentSize();
double height = myTabBar.Frame.Height;
CGSize size = new CGSize(new nfloat(myTabBar.Frame.Width / myTabBar.Items.Length, height));
// Now get our all-green image...
UIImage image = ImageWithColor(size);
// And set it as the selection indicator
myTabBar.SelectionIndicatorImage = image;
}
As mentioned in this article (google translating it step by step when necessary lol) calling InvalidateIntrinsicContentSize() will force the UITabBar to reevaluate it's size and will get you the actual runtime height of the tab bar (instead of the constant 49 height value from XCode).
The solution for centering any subview within a parent is usually simple, however, it doesn't seem to work in my case.
I'm working with a UICollectionView and have added a Header class programmatically. I have this constructor, where I also try to center the label within the screen:
[Export("initWithFrame:")]
public Header(System.Drawing.RectangleF frame) : base(frame)
{
label = new UILabel
{
Frame = new System.Drawing.RectangleF(frame.Size.Width / 2, 50, 200, 50),
BackgroundColor = UIColor.Clear,
TextColor = UIColor.White,
Font = UIFont.FromName("HelveticaNeueLTStd-ThCn", 35f),
Text = DateTime.Now.ToString("Y")
};
AddSubview(label);
}
And I initialize the class inside the UICollectionViewSource 's constructor like this:
public MyCollectionViewDataSource(MainController mainController, DateTime currentDate)
{
try
{
controller = mainController;
new Header(new RectangleF(0, 0, (float)mainController.View.Frame.Size.Width, 200));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message + ex.StackTrace);
}
}
What exactly am I missing because this usually works in other instances but seems to fail here?
This is what it looks like :
I found an explanation here iOS Layout Gotchas by Adam Kemp which helped me resolve this issue.
The first solution
One very common mistake I made was adding the layout definition code in the constructor, instead of doing it in the rightful place : the LayoutSubviews override in this case.
Giving the label the frame size in the constructor assumes a static size set at the time of construction, which may later change depending on the screen size.
The second solution
He explains that :
Frame sets the position of a view within its parent while Bounds is in the coordinate system of the view itself (not its parent).
So, to center the UILabel, I used bounds and center together and this worked for me.
[Export("initWithFrame:")]
public Header(CGRect bounds) : base(bounds)
{
label = new UILabel
{
BackgroundColor = UIColor.Clear,
TextColor = UIColor.White,
Font = UIFont.FromName("HelveticaNeueLTStd-ThCn", 35f),
Text = DateTime.Now.ToString("Y"),
TextAlignment = UITextAlignment.Center
};
rectangle = bounds;
AddSubview(label);
}
public override void LayoutSubviews()
{
base.LayoutSubviews();
label.Bounds = new CGRect (rectangle.Size.Width / 2, 50, 200, 50);
label.Center = new PointF((float)rectangle.Size.Width/2,50);
}
I am developing an application in which i am showing a image followed by text followed by image again horizontally in table layout.
I am creating the table layout programmatically as:
for(i = 0; i < arrayList.size(); i++){
/* Find Tablelayout defined in main.xml */
TableLayout tableLayout = (TableLayout) findViewById(R.id.tableLayout);
tableLayout.setStretchAllColumns(true);
/* Create a new row to be added. */
TableRow tableRow = new TableRow(this);
tableRow.setId(i);
tableRow.setClickable(true);
tableRow.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
v.setBackgroundColor(Color.GRAY);
}
});
tableRow.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.MATCH_PARENT));
/* Create a Button to be the row-content. */
ImageView imageView1 = new ImageView(this);
if(arrayList.get(i).getImage().equalsIgnoreCase("Y")){
// setImage
}
imageView1.setPadding(5, 5, 5, 5);
imageView1.setLayoutParams(new TableRow.LayoutParams(100, 100));
tableRow.addView(imageView1);
TextView textViewName = new TextView(this);
textViewName.setText(arrayList.get(i).getName());
textViewName.setPadding(5, 5, 5, 5);
textViewName.setGravity(Gravity.CENTER_VERTICAL);
textViewName.setTextSize(15);
textViewName.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.MATCH_PARENT,7));
tableRow.addView(textViewName);
ImageView imageView2 = new ImageView(this);
imageView2.setImageDrawable(getResources().getDrawable(R.drawable.icon));
imageView2.setPadding(25, 25, 25, 25);
imageView2.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.MATCH_PARENT,1));
tableRow.addView(imageView2);
tableLayout.addView(tableRow, new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.MATCH_PARENT));
View horizontalLine = new View(this);
horizontalLine.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, 1));
horizontalLine.setBackgroundColor(Color.rgb(50, 50, 50));
tableLayout.addView(horizontalLine);
}
With the help of this i am getting the out put as image 1.
But i need the out put as image 2.
The difference between image 1 and 2 is the red line. I am getting the line with the help of drawing view but that covers whole width. I need a line which is as same as red in image 2. In center and of fix width.
Please suggest me what changes or steps i follow. Need your valuable suggestion.
You can set the color using setBackgroundColor method.
horizontalLine.setBackgroundColor(Color.RED);
Edit :
You can horizontal line of fixed length and in center.
Add the TableRow
Define layout weight for View
Add the View in TableRow
Add the tableRow in Table layout
View horizontalLine = new View(this);
// Set weight
TableRow.LayoutParams params = new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, 10,0.7f);
horizontalLine.setLayoutParams(params);
TableRow tr = new TableRow(this);
TableLayout.LayoutParams tableRowParams= new TableLayout.LayoutParams
(TableLayout.LayoutParams.MATCH_PARENT,TableLayout.LayoutParams.WRAP_CONTENT);
// Set margin
int leftMargin=20;
int topMargin=2;
int rightMargin=20;
int bottomMargin=2;
tableRowParams.setMargins(leftMargin, topMargin, rightMargin, bottomMargin);
tr.setLayoutParams(tableRowParams);
// Add View in tr
tr.addView(horizontalLine);
//Add tr in Table
tableLayout.addView(tr);
You can see the output :
Hope it helps ツ
I am trying to style my JavaFX linechart but I have some trouble with the legend.
I know how to change the legend color of a line chart in the css file:
.default-color0.chart-series-line { -fx-stroke: #FF0000, white; }
.default-color1.chart-series-line { -fx-stroke: #00FF00, white; }
.default-color2.chart-series-line { -fx-stroke: #0000FF, white; }
.default-color0.chart-line-symbol { -fx-background-color: #FF0000, white; }
.default-color1.chart-line-symbol { -fx-background-color: #00FF00, white; }
.default-color2.chart-line-symbol { -fx-background-color: #0000FF, white; }
But this is not enough for my purposes. I have three or more colored toggle buttons and a series of data for every button. The data should be displayed in the same color the button has after I have selected the button. This should be possible with a multiselection of the buttons, so that more than one series of data can be displayed simultaneously.
For the chart lines I have managed it by changing the style after I clicked the button:
..
dataList.add(series);
..
series.getNode().setStyle("-fx-stroke: rgba(" + rgba + ")");
If I deselect the button I remove the data from the list.
dataList.remove(series);
That is working fine for the strokes, but how can I do the same for the legend?
You can see an example below. First I clicked the red button, thus the stroke and the legend is red (default-color0). After that I clicked the blue button. Here you can see the problem. The stroke is blue but the legend is green, because default color1 is used and I do not know how to change the legend color.
I ran into this issue as well. The issue seems to be that when data series are added to the chart, the legend isn't updated at the same time, so when you lookup components with that seriesN style class they don't exist yet. Came up with a work-around that detects when the legend items are created so that dynamic styling can be added to them.
I added a ListChangeListener to the chart legend's "getChildrenUnmodifiable()" ObservableList, which in turn adds a ListChangeListener to each of the legend's children as they get added. From within this listener, we can tell when new items are being added to the legend (or removed). This allow us to then make the dynamic style changes.
for (Node n : lineChart.getChildrenUnmodifiable())
{
if (n instanceof Legend)
{
final Legend legend = (Legend) n;
// remove the legend
legend.getChildrenUnmodifiable().addListener(new ListChangeListener<Object>()
{
#Override
public void onChanged(Change<?> arg0)
{
for (Node node : legend.getChildrenUnmodifiable())
{
if (node instanceof Label)
{
final Label label = (Label) node;
label.getChildrenUnmodifiable().addListener(new ListChangeListener<Object>()
{
#Override
public void onChanged(Change<?> arg0)
{
//make style changes here
}
});
}
}
}
});
}
}
For future reference, this problem can be solved by wrapping your relevant code in a call to Platform.runLater(). For example:
LineChart<Number, Number> plot;
....
Platform.runLater(() -> {
Node nl = plot.lookup(".default-color0.chart-series-line");
Node ns = plot.lookup(".default-color0.chart-line-symbol");
nl.setStyle("-fx-stroke: #333;");
ns.setStyle("-fx-background-color: #333, white;");
});
It seems that this guy is able to lookup the nodes used for legend using their class, and then calling setStyle() on those nodes. (I don't think his problem is relevant for yours)
This solution is based on #Chris' solution
if (checkCombo.getCheckModel().isChecked(0)) {
lineChart.getData().add(seriesTest1);
changeColorSeries(lineChart.getData().size() - 1, "darkgreen");
}
if (checkCombo.getCheckModel().isChecked(3)) {
lineChart.getData().add(seriesTest2);
changeColorSeries(lineChart.getData().size() - 1, "darkred");
}
private void changeColor(int position, String color) {
Platform.runLater(() -> {
Node nl = lineChart.lookup(".default-color" + position + ".chart-series-line");
Node ns = lineChart.lookup(".default-color" + position + ".chart-line-symbol");
Node nsl = lineChart.lookup(".default-color" + position + ".chart-legend-item-symbol");
nl.setStyle("-fx-stroke: " + color + ";");
ns.setStyle("-fx-background-color: " + color + ", white;");
nsl.setStyle("-fx-background-color: " + color + ", white;");
});
}
After digging a lot through google with no success I finally found a lean way to update the legend colors according line color through this method:
private void setLegendItemColor(String shop, String color, Legend lg) {
for (Node n : lg.getChildren()) {
Label lb = (Label) n;
if (lb.getText().contains(shop)) {
lb.getGraphic().setStyle("-fx-background-color:" + color + ";");
}
}
}
So you just need to call the method setLegendItemColor() when you´re going to update the chart lines to update the legend label symbols to the correspondent color.