Visifire 2.3.0 Released!

vivek

Hi,

This release contains fix for the following bug:

  • In Area chart, if value of AxisMinimum property of x-axis is greater than the minimum XValue in DataPoints, Area was going out of PlotArea.

Current release also contains the following enhancements:

  • Tag property for all visual elements of chart has been implemented. Tag property of any visual elements can be accessed as ElementData using managed code.
  • Label placement has been improved for StackedColumn, StackedColumn100, StackedBar, StackedBar100 charts.

Download Visifire v2.3.0 here.

Cheers,
Team Visifire


Visifire 2.2.9 goes GA

vivek

This release contains fix for the following bug:

  • In Line chart, if MovingMarkerEnabled property was set to True for an empty DataSeries, chart threw exception.

Current release also contains the following enhancements:

  • Performance has been improved for the initial render of Chart.
  • In Pie/Doughnut/Funnel chart, if MouseLeftButtonDown or MouseLeftButtonUp events are attached to any DataPoint or DataSeries, default exploding won’t work on click over a DataPoint. User can explode a Pie/Doughnut/Funnel segment by setting Exploded property of DataPoint to true at real time.
  • Label placement algorithm for Line, Point and Area charts has been optimized.
  • A new property TickLength has been introduced in Ticks. For more info, please check documentation.

Download Visifire v2.2.9 here.

Cheers,
Team Visifire


Step by step breakdown of Visifire rendering logic

admin

Introduction

Since the release of Visifire, we have got a lot of positive response from users on the simplicity, looks, customizability of Visifire over other Charting Controls in the market. What made it possible is, Visifire’s underlying set of algorithms that determine the best Visualization for a given set of parameters. So even when you provide bare minimum data required for rendering, Visifire renders a nice looking Chart which has tooltips, default interactivity like explode in Pie Chart, auto font-color for labels depending on the Chart Background color, auto indexing of DataPoints when XValue is not provided, etc.

Though Visifire makes effort to find the best visualization for any given case, its not always enough for all the applications. So we do have relevant properties for making it possible to customize according to individual needs. In this blog am going to explain the default rendering behavior of Visifire and how one can override them according to his needs.

1. Pictorial representation of Various elements/regions in a Chart

Silverlight Chart Control

2. A Minimal Chart

Below is a Minimal Chart and the XAML required to create it.

Img2

<vc:Chart xmlns:vc="clr-namespace:Visifire.Charts;assembly=SLVisifire.Charts"
          Width="500" Height="300">            
    <vc:Chart.Series>
 
        <vc:DataSeries>
            <vc:DataSeries.DataPoints>
                <vc:DataPoint YValue="207349" />
                <vc:DataPoint YValue="274316" />
                <vc:DataPoint YValue="318845" />
                <vc:DataPoint YValue="345254" />
                <vc:DataPoint YValue="351139" />
            </vc:DataSeries.DataPoints>
        </vc:DataSeries>
 
    </vc:Chart.Series>
</vc:Chart>

 

In the above XML we have defined YValue for all the DataPoints. When we look at the rendered chart, we can observe that the DataPoints have been numbered from 1 to 5. DataPoints are numbered automatically in the order of their appearance. If you want to override this default behavior, you can either set XValue for numbers or AxisXLabel in case you want to display string. Note that setting XValue will place DataPoints according to the position of XValue on X-Axis. Chart also shows ToolTip by default.

So by default the Chart adds

  1. XValue – index values
  2. ToolTip
  3. Comma for every thousandth digit on YAxis

3. Customizing Visifire

Chart in the previous section is Minimal in the sense we have not set any property required to customize the Chart. Below are few of the common stuff that you might want to add to the Chart.

  1. Title
  2. XValue/AxisXLabel for each DataPoint
  3. Prefix a symbol to the labels on YAxis – $ for example to make Label to look like $50,000
  4. Customize Values shown in the Tooltip

Below is how the Chart looks after customization

Img3

<vc:Chart xmlns:vc="clr-namespace:Visifire.Charts;assembly=SLVisifire.Charts"
           Width="500" Height="300">
     
     <vc:Chart.Titles>
         <vc:Title Text="Product Sales by Month"></vc:Title>    
     </vc:Chart.Titles>
     
     <vc:Chart.AxesY>
         <vc:Axis Prefix="$"></vc:Axis>
     </vc:Chart.AxesY>
     
     <vc:Chart.Series>
         <vc:DataSeries ToolTipText="#AxisXLabel, Y = #YValue">
             <vc:DataSeries.DataPoints>
                 <vc:DataPoint AxisXLabel="Jan" YValue="207349" />
                 <vc:DataPoint AxisXLabel="Feb" YValue="274316" />
                 <vc:DataPoint AxisXLabel="Mar" YValue="318845" />
                 <vc:DataPoint AxisXLabel="Apr" YValue="345254" />
                 <vc:DataPoint AxisXLabel="May" YValue="351139" />
             </vc:DataSeries.DataPoints>
         </vc:DataSeries>
     </vc:Chart.Series>
 </vc:Chart>

In the above example I’ve used AxisXLabel, as the Labels on the XAxis are strings. If the values are numeric, then you can use XValue. In case you set both the properties, then the DataPoints are placed according to XValue and XValues are replaced by AxisXLabels wherever available. Below is an example.

Img4

<vc:Chart xmlns:vc="clr-namespace:Visifire.Charts;assembly=SLVisifire.Charts"
          Width="500" Height="300">
    
    <vc:Chart.Series>
        <vc:DataSeries ToolTipText="#AxisXLabel, Y = #YValue">
            <vc:DataSeries.DataPoints>
                <vc:DataPoint XValue="1" YValue="207349" />
                <vc:DataPoint XValue="3" YValue="274316" />
                <vc:DataPoint XValue="4" YValue="318845" />
                <vc:DataPoint XValue="5" AxisXLabel="Five" YValue="345254" />
                <vc:DataPoint XValue="6" YValue="351139" />
            </vc:DataSeries.DataPoints>
        </vc:DataSeries>                
    </vc:Chart.Series>
 
</vc:Chart>

4. How the PlotArea width is calculated and how to control it

While allocating region for various elements in the Chart, PlotArea viewport width is determined at the end after allocating region for Title, Legend, AxisX, AxisY. So for example, if we place Legend to the right, then the viewport size reduces depending on the Legend Size. Below is an illustration.

Img5

You can see that the PlotArea "Viewport" width has reduced because of the Legend. But at the same time, the Actual PlotArea Size can extend further resulting in a ScrollBar. This can happen whenever ScrollingEnabled is set to true.

Through some trials, we have determined the relation between the DataPoint Width and Chart Size which makes the Chart to look good/readable and accordingly we are setting the PlotArea Width. Below is the algorithm.

If, ( Max Difference of XValues / Min Difference of XValues ) > MagicNumber, that means PlotArea width needs to be more than that of the viewport width – which results in ScrollBar. We found the equation for MagicNumber through trials with varying chart sizes and varying number of DataPoints. Below is how we calculate it.

MagicNumber = Current PlotArea width * 35 / 550

Now, PlotArea width can be calculated as below.

PlotArea width = ( Max Difference of XValues / Min Difference of XValues ) * 550 / 34

For multi series Column and Bar Charts, we need to multiply 550 with appropriate number of series that get rendered side by side.

5. How Datapoint width is calculated and how to control it

In case of Column and Bar Charts, DataPointWidth is determined based on the two closest DataPoints. Say, the XValues of 4 DataPoints are {1, 4, 5, 7, 9}, then the closest two DataPoints are 2nd and 3rd with difference in XValue of 1. So, in order to be able to draw both the DataPoints without overlap, we need to divide the available space between the two. As a result of which, Maximum Width of DataPoints will be equal to the minimum difference between XValues.

Now, we also need to give some spacing between the two DataPoints which is determined as .1 * ( Minimum Difference of XValues ). So, the DataPoint width finally comes down to .9 * ( Minimum Difference of XValues ) . In case the Chart is MultiSeries, then we need to place multiple columns within the same region. So, the column width calculated as above is divided by the number of series needed to be drawn.

Img6

Img7

In certain cases, the calculated width can go below 1px which will make Columns invisible. So, Visifire sets a lower limit of 2px to DataPoint width. You can also control the width of DataPoint by setting DataPointWidth property as a percentage of PlotArea ViewPort width. For example, setting the DataPointWidth to 5 will result in a Chart as below.

Img8

Please note that increasing/decreasing the Width of DataPoints will not change the relative position of DataPoints. So, if you increase the DataPointWidth over a certain range, columns will actually overlap. In the next section I’ll explain how you can overcome this limitation.

6. How Axis, Interval and AxisLabels work

Whenever you create a chart, by default Visifire tries to calculate the best possible Range and interval for Axis so that it is easier for the Humans to grasp/read. Human readable in the sense, it tries to make the interval a multiple of 1,2,5 or 10 and tries to keep the number of intervals around 8. So, whenever the interval is not 1, it might skip some of the AxisXLabel if you have defined.

Img10

<vc:DataSeries.DataPoints>
     <vc:DataPoint XValue="1" YValue="207349" />
     <vc:DataPoint XValue="3" YValue="274316" />
     <vc:DataPoint XValue="4" AxisXLabel="Four" YValue="318845" />
     <vc:DataPoint XValue="5" YValue="345254" />
     <vc:DataPoint XValue="6" YValue="351139" />
     <vc:DataPoint XValue="7" YValue="217349" />
     <vc:DataPoint XValue="9" YValue="224316" />
     <vc:DataPoint XValue="10" YValue="298845" />
     <vc:DataPoint XValue="11" YValue="335254" />
     <vc:DataPoint XValue="13" YValue="371139" />
 </vc:DataSeries.DataPoints>

Note that I’ve skipped all other elements apart from DataPoints collection just to keep the xaml compact. In the above example you can see that the interval is 2. So, if in case you set AxisXLabel for 3rd DataPoint, then it’ll not be shown. You can override this default behavior by setting the interval property of Axis to 1 as shown below.

Img11

<vc:Chart.AxesX>
    <vc:Axis Interval="1"></vc:Axis>
</vc:Chart.AxesX>
 
<vc:Chart.Series>
    <vc:DataSeries ToolTipText="#AxisXLabel, Y = #YValue">
        <vc:DataSeries.DataPoints>
            <vc:DataPoint XValue="1" YValue="207349" />
            <vc:DataPoint XValue="3" YValue="274316" />
            <vc:DataPoint XValue="4" AxisXLabel="Four" YValue="318845" />
            <vc:DataPoint XValue="5" YValue="345254" />
            <vc:DataPoint XValue="6" YValue="351139" />
            <vc:DataPoint XValue="7" YValue="217349" />
            <vc:DataPoint XValue="9" YValue="224316" />
            <vc:DataPoint XValue="10" YValue="298845" />
            <vc:DataPoint XValue="11" YValue="335254" />
            <vc:DataPoint XValue="13" YValue="371139" />
        </vc:DataSeries.DataPoints>
    </vc:DataSeries>          
</vc:Chart.Series>

While rendering the Axis, Visifire tries to automatically place AxisLabels in such a way that they don’t overlap. Say, if we change the AxisXLabel from "Four" to "XValue is Four", then it is obvious that the Label is long and it’ll overlap the neighboring AxisLabels. So, Visifire starts showing labels in 2 rows as shown below.

Img12

Now if we further increase the AxisXLabel to "DataPoint XValue is Four", then it becomes difficult to show Labels in two rows. So the next alternative will be to rotate the AxisLabel so that it doesn’t overlap the neighboring AxisXLabels.

Img13

You can customize Axis by setting Interval, MinimumValue, MaximumValue, etc as mentioned in the following document.

7. How Labels are placed

Below is an image showing Labels in Visifire. In order to show Label, one needs to enable them by setting LabelEnabled to True in DataSeries.

Img14

<vc:DataSeries LabelEnabled="True" ToolTipText="#AxisXLabel, Y = #YValue">
    <vc:DataSeries.DataPoints>
        <vc:DataPoint YValue="207349" />
        <vc:DataPoint YValue="274316" />
        <vc:DataPoint YValue="318845" />
        <vc:DataPoint LabelText="Label" YValue="345254" />
        <vc:DataPoint YValue="351139" />
        <vc:DataPoint YValue="217349" />
        <vc:DataPoint YValue="224316" />
        <vc:DataPoint YValue="298845" />
        <vc:DataPoint YValue="335254" />
        <vc:DataPoint YValue="371139" />                           
    </vc:DataSeries.DataPoints>
</vc:DataSeries>

See that Labels and AxisLabels are different. AxisLabel is one which is shown below the Axis and Labels are shows on/above the DataPoints.

You can observe that few of the Labels are outside the DataPoint and few are inside. Few have Black font color and few have White. Though the placement seems random at first place, it is not. Below I’ll explain the flow.

While placing Label for a DataPoint, Visifire first tries to place it horizonatally outside DataPoint. If the DataPoint width is more than the Label’s width, then Label is placed horizontally as in case of 4th DataPoint. If the DataPoint width is less than that of Label’s, then the Label is placed vertically. Now, whether the Label is placed on top of columns or inside the columns is determined by the availability of space outside the Column. If there is enough space outside the column, then the Labels are placed outside of DataPoint. If not, then the Labels are placed inside DataPoint.


Visifire 2.2.9 beta 2 Released

vivek

Hi,

This release contains fix for the following bugs:

  • Property binding was not working for the following properties.
    FontSizeProperty, FontFamilyProperty, FontStyleProperty, FontWeightProperty, BorderThicknessProperty, BackgroundProperty, HorizontalAlignmentProperty, VerticalAlignmentProperty, PaddingProperty and OpacityProperty.
  • Chart was not behaving as expected if Color property for a DataPoint was set through Style.
  • StartFromZero property of x-axis and y-axis was not working as expected if CandleStick or Stock chart is combined with one or more than one DataSeries without any DataPoints.

Current release also contains the following enhancements:

  • Label placement algorithm has been improved for multiline AxisXLabel. Previously AxisXLabel was going out of the region if AxisXLabel is rotated to a certain degree.
  • Label placement algorithm for StackedColumn, StackedBar and StackedArea charts has been improved.

Download Visifire v2.2.9 beta 2 here.

Cheers,
Team Visifire


Visifire 2.2.9 beta Released

vivek

Hi,

This release contains fix for the following bug:

  • In practice YValue property for CandleStick and Stock chart types is ignored while drawing. Visifire was taking YValue into account while drawing these chart types.

Current release also contains the following enhancement:

  • DataPoint label positioning has been improved.

Download Visifire v2.2.9 beta here.

Cheers,
Team Visifire


Visifire 2.2.8 goes GA

vivek

This release contains fix for the following bugs:

  • If ScrollBarOffset property is set, chart did not behave as expected at initial render.
  • In Pie/Doughnut charts, if DataPoint’s LabelText is long then while exploding, label line was not positioning properly.

Download Visifire v2.2.8 here.

Cheers,
Team Visifire