Jump to content
JChartFX Community

JuanC

Administrators
  • Posts

    421
  • Joined

  • Last visited

  • Days Won

    3

Posts posted by JuanC

  1. As far as I know, IE needs the page to start with the following tag <!DOCTYPE html> to treat the page in standards mode and support SVG. I would also recommend checking with a small SVG (e.g.)

    <svg width="400" height="300">

      <rect x="0" y="0" width="200" height="200" fill="#AE2000" />

    </svg> 

    If you are able to view the SVG in IE but not the chart, please try posting (or sending us) a small page that reproduces the problem. 

     If you use the developer mode you can also check if IE is using standards mode or quirks mode to render your page.

    Regards,

    JuanC 

  2. Two panes would be a reasonable approach, note that this assumes you can find the "magic" value (50) that breaks the axis, in order to have 2 panes you will need 2 series and with 2 series you will have to make sure you later "hide" this extra series from legend box, tooltips, etc.

        var data = [


                     { "Item": "A1", "Value": 30 },


                     { "Item": "A2", "Value": 5530 },


                     { "Item": "A3", "Value": 50 },


                     { "Item": "A4", "Value": 12 },


                     { "Item": "A5", "Value": 5900 },


                     { "Item": "A6", "Value": 5740 },


                    ];


        


        var break1 = 50;


        var break2 = 3000;


        var maxValue = 6000;


        


        // Translate data to have 3 series, note that this relies on finding break values


        // Value and LargeValue will be used to plot bars in different panes, RealValue used for ToolTips


        var panedData = new Array();


        var n = data.length;


        


        for(var i = 0; i < n; i++) {


            var value = data.Value;


            


            var newObj = new Object();


            newObj["Item"] = data.Item;


            newObj["RealValue"] = value;


            


            if (value <= break1) {


                newObj["Value"] = value;


                newObj["LargeValue"] = cfx.Chart.Hidden;


            } else {


                newObj["Value"] = break1;


                newObj["LargeValue"] = value;


            }


            


            panedData.push(newObj);


        }


        


        // Make sure only Value and LargeValue are plotted


        var fields = chart1.getDataSourceSettings().getFields();


        var field1 = new cfx.FieldMap();


        field1.setName("Value");


        field1.setUsage(cfx.FieldUsage.Value);


        fields.add(field1);


        var field2 = new cfx.FieldMap();


        field2.setName("LargeValue");


        field2.setUsage(cfx.FieldUsage.Value);


        fields.add(field2);


        var field3 = new cfx.FieldMap();


        field3.setName("Item");


        field3.setUsage(cfx.FieldUsage.Label);


        fields.add(field3);


        


        chart1.setDataSource(panedData);


        


        var panes = chart1.getPanes();


        var pane = new cfx.Pane();


        panes.add(pane);


        


        var seriesList = chart1.getSeries();


        var series0 = seriesList.getItem(0);


        var series1 = seriesList.getItem(1);


        series0.setPane(pane);


        


        // Setup Top Pane to start in break value


        chart1.getAxisY().setMin(break2);


        chart1.getAxisY().setMax(maxValue);


        


        // make sure both series have same color


        series0.setColor("#0040E0");


        series1.setColor("#0040E0");


        


        // Hide LargeValue from legend box


        chart1.getLegendBox().getItemAttributes().getItem(seriesList, 1).setVisible(false);


        


        // Hide LargeValue from tooltip


        // Also note that we have to make sure we do not show value 50 for big bars in the bottom pane


        var tipContentTemplate = '<DataTemplate>' +


                                    '<DockPanel Orientation="Horizontal" Margin="3,0,3,0">' +


                                      '<TextBlock Text="Value:" Margin=\"0,0,4,0\"/>' +


                                      '<TextBlock Text="{Binding Path=DataRealValue}" FontWeight="Bold" HorizontalAlignment="Right"/>' +


                                    '</DockPanel>' +


                                  '</DataTemplate>';


        chart1.getToolTips().setContentTemplate(tipContentTemplate);


        chart1.getToolTips().setAllSeries(false);


        


        chart1.setGallery(cfx.Gallery.Bar);

     

    JuanC 

  3. Axis.CustomSteps is currently not supported but it would not help on what you are trying to achieve, imagine an axis that goes from 0 to 100, our algorithm might decide that 20 is a suitable step, if you want to override this you would use setStep to manually set the step to 25. CustomSteps (if supported) would allow you to pass an array of 20 70 10 so the visible labels would be 0, 20, 90, 100.

    Note that in all cases the axis would be linear so two values of 0.2 and 0.25 would indistinguishable.

    There is an option but I am not sure if it would work in your scenario to set the axis to be logarithmic.

    We currently do not have a feature in jChartFX where the axis would be broken up in two segments, e.g. 0-10 and then immediately start at 5000-7000. This is something we are considering supporting in future versions of the product.

    Regards,

    JuanC 

  4. There is no API to assign hyperlinks to bars or markers, you can attach to the click event where you will receive information about the point and series clicked.

    When using jquery you would write

    $("#myDiv").click(function(evt) {

                 doClick(evt);

            });

     

    If you are not using jquery you would write

    var divHolder = document.getElementById('myDiv');

    chart1.create(divHolder);

    divHolder.onclick = doClick;

     

    And the click handler would be something like

    function doClickEvent(evt)

    {

         if ((evt.hitType == cfx.HitType.Point) || (evt.hitType == cfx.HitType.Between)) {

             var s = "Series " + evt.series + " Point " + evt.point;

             alert(s);

          }

    }

     

    JuanC 

  5. You can use the Chart.dateToDouble method to translate a javascript date (note that it expects a date not a string) into a number, e.g.

       var data = [

                     { "Date": "2013-10-01T00:00:00.000Z", "Value": 15 },

                     { "Date": "2013-11-01T00:00:00.000Z", "Value": 9 },

                     { "Date": "2013-12-01T00:00:00.000Z", "Value": 12 },

                     { "Date": "2014-01-01T00:00:00.000Z", "Value": 14 },

                     { "Date": "2014-02-01T00:00:00.000Z", "Value": 18 },

                     { "Date": "2014-03-01T00:00:00.000Z", "Value": 9 },

                     { "Date": "2014-04-01T00:00:00.000Z", "Value": 12 },

                     { "Date": "2014-05-01T00:00:00.000Z", "Value": 15 },

                    ];


        var axisX = chart1.getAxisX();

        axisX.getLabelsFormat().setFormat(cfx.AxisFormat.Date);

        axisX.getLabelsFormat().setCustomFormat("MMM yyyy");

        

        var dateToday = new Date(2014, 2, 12, 0, 0, 0, 0);

        var customGrid = new cfx.CustomGridLine();

        var value = cfx.Chart.dateToDouble(dateToday);

        customGrid.setValue(value);

        axisX.getCustomGridLines().add(customGrid);

        

        chart1.setDataSource(data);

     

    JuanC 

  6. You do not need to use crosstab to create this chart (I suspect you do not need crosstab for your bar chart either), the way we process your json data, we will use the first string field for the labels and each numeric field as a series in your chart, so just passing the data should be enough, e.g.

        var data = [{ "username" : "Tony15", "userid" : "Tony15", "sightings" : 1506},{ "username" : "richard", "userid" : "richard", "sightings" : 551},{ "username" : "carly", "userid" : "carly", "sightings" : 235},{ "username" : "John", "userid" : "John", "sightings" : 138},{ "username" : "flyhellas", "userid" : "flyhellas", "sightings" : 94},{ "username" : "efc123", "userid" : "efc123", "sightings" : 85}];

        chart1.setDataSource(data); 

    If you want to be extra explicit (or you want to use userid instead of username as the label, or you have multiple numeric fields and want to decide which one to use) you could do this.

        var data = [{ "username" : "Tony15", "userid" : "Tony15", "sightings" : 1506},{ "username" : "richard", "userid" : "richard", "sightings" : 551},{ "username" : "carly", "userid" : "carly", "sightings" : 235},{ "username" : "John", "userid" : "John", "sightings" : 138},{ "username" : "flyhellas", "userid" : "flyhellas", "sightings" : 94},{ "username" : "efc123", "userid" : "efc123", "sightings" : 85}];

        

        var fields = chart1.getDataSourceSettings().getFields();

        var field1 = new cfx.FieldMap();

        field1.setName("username");

        field1.setUsage(cfx.FieldUsage.Label);

        fields.add(field1);


        var field2 = new cfx.FieldMap();

        field2.setName("sightings");

        field2.setUsage(cfx.FieldUsage.Value);

        fields.add(field2);

        

        chart1.setDataSource(data);

     

    JuanC 

  7. I see your chart is a gantt chart so if you mean reduce the space between the bars you can use the Volume property to control this spacing, 100% volume will draw bars with no space between them

        chart1.getAllSeries().setVolume(100);

    You can also move the legendbox to the bottom to reduce the wasted space to the right of the chart (or hide the legendbox altogether) if you need your chart to be smaller. 

    JuanC 

  8. Assuming you have the total value you could setup your chart with 3 stacked bars and use markers for the fourth (total) series and only show the labels for this last series, e.g

        var data = [{"Jan":10, "Feb":12, "Mar":8, "Total":30}, {"Jan":7, "Feb":15, "Mar":3, "Total":24}];

        

        chart1.setDataSource(data);

        

        // Global Attributes that will apply to all but last series

        chart1.setGallery(cfx.Gallery.Bar);

        chart1.getAllSeries().setStackedStyle(cfx.Stacked.Normal);

        

        // Attributes for last series

        var series3 = chart1.getSeries().getItem(3);

        series3.setGallery(cfx.Gallery.Scatter);

        series3.getPointLabels().setVisible(true);

        

        // Remove scatters

        series3.setMarkerShape(cfx.MarkerShape.None);

     

    JuanC 

  9. Can you try removing the @{...} tag at the beginning of the page? or moving it? I have seen IE9 will render a page in quirks move if the page does not start with <!DOCTYPE html>. If you use the developer mode you can also check if IE is using standards mode or quirks mode to render your page.

    I also noticed that you are using $(document).ready(... but did not see jQuery in the includes but maybe you were cleaning up the page before posting it here. 

    Regards,

    JuanC 

  10. We only attach ourselves to the jquery click event to push properties such as series, point, etc. If you are handling MouseDown you could call

     chart1.detectEvent(evt)

    where evt is the event argument passed to the event handler, after this call your code can query for evt.hitType, evt.series, evt.point, etc.

    Note that to invoke the method on a mousedown handler when using jQueryUI you would need something like this in your jsfiddle sample

    $("div", ".ChartDiv1").on("mousedown",function doClick(evt){

                    $("div", ".ChartDiv1").chart("detectEvent", evt);

    if ((evt.hitType == cfx.HitType.Point) || (evt.hitType == cfx.HitType.Between))

                   alert(evt.point);

                }) 

    JuanC 

  11. I have not done it myself but I would start with 2 charts, calling the function to create/populate the first chart as soon as the page is loaded, then creating a timer and running the code to create the second chart when the timer "fires".

    The default for our load animation is 1.2 seconds (you can change this if needed) so I would try to time the second animation to either coincide a little with the first chart or a little after the first one ends.

    JuanC 

  12. I tried your code in 3 different browsers and got the expected result (only 1 gridline) in all of them, the only thing strange (but bening) in your code is that customGridLines.add does not return anything so instead of

    var customGridLines = chart1.getAxisY().getCustomGridLines().add(customGrid);

    I would write

    chart1.getAxisY().getCustomGridLines().add(customGrid);

    Can you post a link to an image showing how it looks in your case? Have you tried different browsers? 

    JuanC 

  13. There are 2 ways of doing this, first there is a feature of animations called DataChange which should allow you to animate the data changes in the chart, this works if you only change the data and also if the "shape" of the data (number of series, number of points, etc.) does not change, I noticed there might be a bug when using setDataSource so you might have to change the values independently, e.g.

    function doInitialize() {

        chart1.getAnimations().getLoad().setEnabled(true);

        chart1.setGallery(cfx.Gallery.Bar);

        var axisY = chart1.getAxisY();

        axisY.setMin(0);

        axisY.setMax(100);

        var data = [{"Year":"2012", Value:25}, {"Year":"2013", Value:45}];

        chart1.setDataSource(data);

        chart1.getAnimations().getDataChange().setEnabled(true);

    }

    function changeData() {

        chart1.getData().getY().setItem(0, 0, 65);

        chart1.getData().getY().setItem(0, 1, 15);

    }

    The second approach works even if the shape of the data changes but will animate from 0 instead of the current values, remove the getDataChange().setEnabled line from the initialization and then use Animations.Reset as follows

    function changeData()

    {

        var data = [{"Year":"2012", Value:65}, {"Year":"2013", Value:15}];

        chart1.setDataSource(data);

        chart1.getAnimations().reset();

    }


    JuanC 

  14. The key here is to remember that everything will run on the client, start with a harcoded sample and then make sure your ASP generates the same script but with real data, if something fails check View - Source to make thing you are generating the same script, e.g.

        chart1.setGallery(cfx.Gallery.Bar);

        var data = [{"Year":"2012", Value:25}, {"Year":"2013", Value:45}];

        chart1.setDataSource(data);

     So your ASP would be something like

     <script language="javascript">

        chart1.setGallery(cfx.Gallery.Bar);

        var data = [{"Year":"2012", Value:<%=lastYearResults%>, {"Year":"2013", Value:<%=thisYearResults%>}];
     
        chart1.setDataSource(data);
     
    Regards,
     
    JuanC 
  15. getData().getItem(series, point) will return the numerical data for the specified series/point combination. The first string in your json objects will be used as the X axis labels which you can retrieve as follows

    chart1.getAxisX().getLabels().getItem(point)

    Obviously if you keep a reference to the data that you passed to the chart using setDataSource you could do this

    var data = [...];

    chart1.setDataSource(data);

    ... 

    data[index].Month 

    JuanC 

    post-2107-13939743544002_thumb.gif

  16. If you are using a line chart, our next build should improve performance for our default animation (from left to right), in certain scenarios this animation might look smoother for line charts

    chart1.getGalleryAttributes().setAnimationStyle(cfx.LineAnimation.YData); 

    Obviously the number of elements (points, series) will affect the animations performance but if you have a sample that exhibits poor performance please post it here (or send it to sales@softwarefx.com) so we can take a look at it.

    Regards,

    JuanC 

×
×
  • Create New...