I have a barChart :
that looks like this
The bars align to the left of the category, for instance the "Food/Drinks" orange bar is to the left of the "Food/Drinks" Category text on the X-Axis.
I want it to be excatly above it.
I tried to play around with .setCategoryBar() and .setBarGap() methods of the BarChart object but those do not achive wanted result no mater what value i pass to them(even negative ones), they only seem to change the thickness of the bar.
FXML code for the BarChart :
<center>
<BarChart BorderPane.alignment="CENTER" fx:id="barChart">
<xAxis>
<CategoryAxis label="Category" side="BOTTOM" />
</xAxis>
<yAxis>
<NumberAxis label="Money Spent (PLN)" side="LEFT"/>
</yAxis>
</BarChart>
Code that binds data with the BarChart :
public void initialize() {
barChart.setData(DataStorage.getInstance().getChartData());
barChart.setTitle("Expenses: " + DataStorage.getInstance().getTotalExpenses() + " PLN");
}
Ok, so for anyone who has that problem : use StackedBarChart instead. Transitioning to it takes about 30 seconds.
Read this post if u have mentioned problem :
Align bars with bar labels in Jfreechart
Related
Hi i have spend some days searching for the answer how to solve this
This is what i want, just made a image how it should look like
What is the best solution to use to solve this?
I tryed to do this with a Frame but it just allowed be to use 1 content .
Can i use more then one content in some way
( Content can just have one setup of fontcolor and fontsize and so on. )
I just get to this part
Here i try to put a label with margin with - so it go above.
But this is really bad to to. because i need to have the implementation under the frams. like this.
_stack.Children.Add(frame);
_stack.Children.Add(bordertext);
and when i fill the frame with content the lable apear in another position because how it relate to the margin when the Frame get higher.
But if i put the lable implementation above the Frame then it appear in the background of the frame
_stack.Children.Add(bordertext);
_stack.Children.Add(frame);
And the label get weard with the shadow that i cant figure out how to get rid of.
C#
Frame frame = new Frame
{
BorderColor = Color.Brown,
CornerRadius = 10,
HasShadow = false,
Margin = 10,
BackgroundColor = Color.White,
};
Label bordertext = new Label( );
bordertext.Text = "BorderText";
bordertext.Margin = new Thickness(40, -65,0 , 0);
bordertext.BackgroundColor = Color.White;
_stack.Children.Add(frame);
_stack.Children.Add(bordertext);
PART OF THE SOLUTION
#Jason 's solution to put
the Content in a Stacklayout and then put it in a Frame Solves the problem with having more then one text with different font,sizes and stuff.
But i put a text outside the Stacklayout so i can have the Text on the border. But because i put the Bordertext first and then the Frame. Then the Border text gets in the background.
If i put it after the Frame then i gets in the front. But then i have a big problem with dynamic text that the BorderText will appear very strange depending on how much text.
How i cant put the BorderText in front even if i implement in before so i cant move it down a little bit.
_stack.Children.Add(new Label { Text = "Bordertext", Margin = new Thickness(0, 0, 0, -25) });
_stack.Children.Add(_frame);
To compose a layout, first determine what boxes (rectangles) you need inside other boxes. Each "box" is some container (layout) type.
I see one box "A", the size of the parent-container, containing the border lines "B", overlaid by a box "C" that blocks part of one line, and contains a text "D".
I see a second box "E", inset slightly from the parent-container, which contains additional content "F".
To overlay multiple items, use a one-cell Grid, with children at (row,column) of 0,0 - which can be omitted because is default:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="FormsApp1.MainPage">
<Grid BackgroundColor="Violet">
<!-- Border lines formed by one box visually "inside" another, via margins.
Instead use "Rectangle" if need rounded corners. -->
<BoxView BackgroundColor="Red" Margin="10"/>
<BoxView BackgroundColor="LightCoral" Margin="16"/>
<!-- Text "box" given size by putting inside a StackLayout. -->
<!-- Some of these dimensions may not be needed. -->
<StackLayout WidthRequest="300" HeightRequest="30">
<Label Text="Header Text" TextColor="Black" BackgroundColor="White" FontSize="18"
HorizontalOptions="Start"
WidthRequest="150" HeightRequest="30" Margin="20,0" Padding="20,0,0,0"/>
</StackLayout>
<!-- this contains your contents. -->
<StackLayout BackgroundColor="#2196F3" Padding="10" Margin="40">
<Label Text="Content line 1" HorizontalTextAlignment="Center" TextColor="White"/>
<Label Text="Content line 2" HorizontalTextAlignment="Center" TextColor="White"/>
</StackLayout>
</Grid>
</ContentPage>
"Positioning" is done via "Margin" and "Padding" properties.
I've used various colors, so you can see the parts of this layout. "ContentPage" wrapper might not be needed; use whatever your app expects as topmost container.
layout of group' frame' with header text:
You can see from the image below, the chart lines don't go all the way to the edge of the StackLayout container. I've tried adding negative margins on the StackLayout but they're inconsistent depending on how much data I have in the chart and the margins can fluctuate. And between Android & iOS, the margins are always different.
Nativescript Playground sample:
play.nativescript.org/?template=play-ng&id=I8lOBP
This is the bad version:
In the image, you'll notice on the right and left edges, there's dark strips of the emulator window. I'm looking for a way for the red area line to touch those edges. It's hard to see in the image but the bottom also needs to touch the bottom of the StackLayout container.
<StackLayout>
<RadCartesianChart
height="100%"
width="100%"
class="default-background">
<CategoricalAxis
lineColor="#f5f5f5"
hidden="true"
lineHidden="true"
lineThickness="1"
labelLayoutMode="Inner"
tkCartesianHorizontalAxis>
</CategoricalAxis>
<LinearAxis
lineColor="#f5f5f5"
hidden="true"
lineHidden="true"
lineThickness="1"
labelLayoutMode="Inner"
[maximum]="max"
[minimum]="min"
tkCartesianVerticalAxis>
</LinearAxis>
<AreaSeries
tkCartesianSeries
seriesName="Area"
showLabels="false"
categoryProperty="Date"
[items]="areaSource$ | async"
valueProperty="Amount"
selectionMode="None">
</AreaSeries>
<RadCartesianChartGrid
tkCartesianGrid
horizontalLinesVisible="false"
verticalLinesVisible="false"
verticalStripLinesVisible="false"
horizontalStripLinesVisible="false"
horizontalStrokeColor="#181818">
</RadCartesianChartGrid>
<Palette tkCartesianPalette seriesName="Area">
<PaletteEntry
tkCartesianPaletteEntry
opacity="1"
[fillColor]="fillColor"
[strokeColor]="lineColor"
android:strokeWidth="4"
ios:strokeWidth="2">
</PaletteEntry>
<PaletteEntry
tkCartesianPaletteEntry
[fillColor]="fillColor"
strokeColor="#181818"
strokeWidth="0">
</PaletteEntry>
</Palette>
</RadCartesianChart>
</StackLayout>
Here's what I want it to look like (credit: photoshop).
You should be setting the horizontalZoom property, probably upping its current value by about 30%.
const screen = require("tns-core-modules/platform").screen;
let widthDIPs = screen.mainScreen.widthDIPs;
<StackLayout>
<RadCartesianChart
height="100%"
[width]="widthDIPs"
class="default-background">
<CategoricalAxis
(...)
src: https://docs.nativescript.org/angular/ui/styling#supported-measurement-units
I am using gRaphaëlJS pie chart to create some color "buttons" for a color picker.
What I want:
When a pie chart ("button") is clicked I want an image to appear in the middle of that pie chart to indicate to the user that this button/color is selected.
Problem is: I'm failing in adding that image.
What have I tried:
gRaphaëlJS puts a "cover" over each pie chart so I tried to add a paletteObj.covers[0][0].setAttribute('class', palette + ' sliderPalette'); to the cover SVG element.
Tried to add paletteObj.series.items[i].node.setAttribute('style', "background:url('images/selected01.png')"); to the actual pie chart ("button") SVG element.
I tried to use jQuery to dynamically add a CSS style to my button as so:
$('.' + palette).css('background', "url('images/selected01.png')");
$('.' + palette).css('background-repeat', "no-repeat");
$('.' + palette).css('background-position', "center");
$('.' + palette).css('background-attachment', "fixed");
$('.' + palette).css('background-color', "transparent");
I tried to simply use good old CSS:
.sliderPalette { background: url('images/selected01.png'); }
I tried what was written here by robertc about <defs> and <pattern>
Why can't I add a BG image like to any other DOM element?
My code can be found here: http://jsfiddle.net/QBVKy/4/
I appreciate any help on this.
D.
P.S - could anyone with enough reputation (1.5K) please add a tag for RaphaëlJS? I see that snap.svg has one :-)
I have a stacked bar chart with bars that need some custom labeling. Each bar needs to display the bar's value preceeded by a label. To support this, I have created a custom labelFunction for the various BarSeries in the BarChart (see below).
The function is successfully rendering the labels, but in the case of the stacked bars, the label values are not displaying what I want. Instead of showing the bar's value, it is showing the sum of the bars in the stack. For example, if a BarSet contains three bars with values 3, 4, and 5, the labels are being displayed not as "3", "4", and "5", but "3", "7", and "12".
From this example it looks like I can achieve the results I want by creating a separate labelFunction for each individual BarSeries and accessing the specific property (e.g. data.item.#fooCount). However, I'd prefer having just one generic function if possible. Is there another property I can access in place of xNumber that gets me the bar's particular value and not the sum?
Note that the default label behavior (i.e. not setting a labelFunction) displays the individual values, not the sums... So I'm assuming it's possible, hopefully without a lot of extra hoops to jump through. :)
My custom labelFunction:
private function setCustomLabel(item:ChartItem, series:Series):String
{
var data:BarSeriesItem = BarSeriesItem(item);
var currentSeries:BarSeries = BarSeries(series);
return currentSeries.displayName + ": " + data.xNumber;
}
A snippet of some of the BarChart code:
<mx:BarChart id="myChart" showDataTips="true"
height="180" width="100%">
...
<mx:BarSet type="stacked">
<mx:BarSeries displayName="Foo Count" xField="fooCount"
labelFunction="setCustomLabel" />
<mx:BarSeries displayName="Bar Count" xField="barCount"
labelFunction="setCustomLabel" />
</mx:BarSet>
</mx:series>
</mx:BarChart>
Thanks!
I believe what you want to do is use the dataProvider. Right now, your xNumber would be for the stacked series, and not of the data coming in.
So, I would try something like this:
private function setCustomLabel(item:ChartItem, series:Series):String
{
var data:BarSeriesItem = BarSeriesItem(item);
var currentSeries:BarSeries = BarSeries(series);
return currentSeries.displayName + ": " + data.item[currentSeries.xField];
}
This is not tested, but I think you get the idea of getting the raw data instead of using what the item displays.
Please find the below code
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
[Bindable]
public var testAC:Array = [
{date:"without", close:50},
{date:"with", close:45}
];
]]>
</mx:Script>
<mx:ColumnChart id="myChart" dataProvider="{testAC}">
<mx:horizontalAxis>
<mx:CategoryAxis categoryField="date"/>
</mx:horizontalAxis>
<mx:verticalAxis>
<mx:CategoryAxis categoryField="close"/>
</mx:verticalAxis>
<mx:series>
<mx:ColumnSeries dataProvider="{testAC}" xField="date" yField="close"/>
<mx:LineSeries dataProvider="{testAC}" xField="date" yField="close"/>
</mx:series>
</mx:ColumnChart>
</mx:Application>
This code is drawing a colum chart with two columns and drawing a line across the top of both columns. I have two requirements :
the line need to be dashed
as of now the line starts from top right corner of the first column to the same corner of the second column. How can i shift the line to the left, so that it starts from center of first column to center of second column.
Regards, PK
You can draw a line between two values on your Cartesian Chart with
<mx:Script><![CDATA[
private function connectTwoPoints(
month1:String, value1:Number,
month2:String, value2:Number):void
{
// Draw Line
canvas.clear();
canvas.lineStyle(4,
0xCCCCCC,
.75,
true,
LineScaleMode.NORMAL,
CapsStyle.ROUND,
JointStyle.MITER,
2);
canvas.moveTo(month1, value1);
canvas.lineTo(month2, value2);
}
]]></mx:Script>
<mx:annotationElements>
<mx:CartesianDataCanvas id="canvas" includeInRanges="true"/>
</mx:annotationElements>
The line that you draw will be an "Annotation Element" using the "Cartesian Data Canvas". Annotation Elements are drawn in the foreground. Perfect Example:
http://livedocs.adobe.com/flex/3/html/help.html?content=charts_eventsandeffects_13.html
For many of my charts with complex skinning I've been using Axiis. It's very Degrafa-like and would allow you to take a degrafa stroke and put it wherever you'd like on your 'dataCanvas'.
Here's an example that is pretty straight fwd:
http://axiis.org/examples/HClusterStackExample.html
'Tisn't the best answer in the land, but using axiis is so simple, and yet it allows for complex fills and strokes that aren't allowed via mxml with plain-ol' flex charting.
Best of luck,
Jeremy
after a long research i finally completed drawing dashed line chart. I used DashedGraphicUtilities provided by Adobe itself to draw the dashed line. I extender the LineSeries and used this DashedGraphicUtilities to draw the dashed line. That solved my first and mail problem. I will update this whenever i get the solution for the second.
And i got the solution for second problem also. The line chart was displaying perfectly as i needed, when i changed the graph type from ColumnChart to CartesianChart. I used column series and line series inside that and the line and columns were coming perfectly.
Regards,
Anoop