Jquery flot - zero value exceeds grid when changing axes direction

I have a problem with a juqery flot and jquery.flot.symbol usage. I render a flot using jquery.flot and using an additional plugin (jquery.flot.symbol to make some rectangles over the graph). The problem is when I reverse the axes (ox starting from right to left and oy position right). The part that is generated with the help of jquery.flot.symbol exceeds the grid and the zero values is somehow outside the graph (with other words all the values are moved to right)

http://jsfiddle.net/5L3eyafn/2/

and a relevant part of the code

        var data1 = [
                    {
                        data: graphData,
                        bars: {
                            show: true,
                            lineWidth: 3,
                            horizontal: false,
                            fillColor: "#f8e7b3"
                        },
                        color: "#ffffff"
                    },
                    {
                        data: trendData,
                        points: {
                            show: true,
                            lineWidth: 3,
                            radius: 10,
                            fill: true,
                            fillColor: "#000000",
                            symbol: "rectangleGraph"
                        },
                        color: "#000000"
                    }
                ];

                $.plot($(".graph"), data1,  {
                    grid:{
                        tickColor: "#eee",
                        borderColor: "#eee",
                        borderWidth: 1,
                        hoverable: true,
                        clickable: true
                    },
                    xaxis:{
                        show: true,
                        transform: function (v) { return -v; },
                        inverseTransform: function (v) { return -v; }
                    },
                    yaxis: {
                        show: true,
                        position: "right"
                    }
                });

Answers


The problem here is that the bars are aligned left by default which switches to alignment right by your transformation to the reverse. This does not happen automatically with the symbols. Here you have to do it by hand.

1) Changing symbol alignment to right like the bars (fiddle):

Change

ctx.rect(x + 3, y - 8, 12, 1); //12 - width, 1 - height

to

ctx.rect(x - 15, y - 8, 12, 1); //12 - width, 1 - height

If you want to be able to switch between normal and reverse axis you have to use a variable for the x offset.

2) Using center alignment (fiddle):

Change the above line to

ctx.rect(x - 6, y - 8, 12, 1); //12 - width, 1 - height

and add this to the bars options:

align: "center"

With center alignment you can switch between normal and reverse without need to change the symbol code. (And it better shows which bar belongs to which x value.)

3) Correction for symbol y values (fiddle):

As you can see in the fiddles for both 1) and 2), the symbol for the value x = 0 is above the bar, but it should not be (symbol y = 41.6, bar y = 42.0). To correct this you can also change the y offset in the code line from above to

ctx.rect(x - 6, y + 1, 12, 1); //12 - width, 1 - height

Here is the result from 2) plus 3) as a code snippet:

/*
Flot plugin that adds some extra symbols for plotting points.

The symbols are accessed as strings through the standard symbol
choice:

  series: {
      points: {
          symbol: "square" // or "diamond", "triangle", "cross"
      }
  }

*/

(function ($) {
    function processRawData(plot, series, datapoints) {
        // we normalize the area of each symbol so it is approximately the
        // same as a circle of the given radius

        var handlers = {
            square: function (ctx, x, y, radius, shadow) {
                // pi * r^2 = (2s)^2  =>  s = r * sqrt(pi)/2
                var size = radius * Math.sqrt(Math.PI) / 2;
                ctx.rect(x - size, y - size, size + size, size + size);
            },
            diamond: function (ctx, x, y, radius, shadow) {
                // pi * r^2 = 2s^2  =>  s = r * sqrt(pi/2)
                var size = radius * Math.sqrt(Math.PI / 2);
                ctx.moveTo(x - size, y);
                ctx.lineTo(x, y - size);
                ctx.lineTo(x + size, y);
                ctx.lineTo(x, y + size);
                ctx.lineTo(x - size, y);
            },
            triangle: function (ctx, x, y, radius, shadow) {
                // pi * r^2 = 1/2 * s^2 * sin (pi / 3)  =>  s = r * sqrt(2 * pi / sin(pi / 3))
                var size = radius * Math.sqrt(2 * Math.PI / Math.sin(Math.PI / 3));
                var height = size * Math.sin(Math.PI / 3);
                ctx.moveTo(x - size / 2, y + height / 2);
                ctx.lineTo(x + size / 2, y + height / 2);
                if (!shadow) {
                    ctx.lineTo(x, y - height / 2);
                    ctx.lineTo(x - size / 2, y + height / 2);
                }
            },
            cross: function (ctx, x, y, radius, shadow) {
                // pi * r^2 = (2s)^2  =>  s = r * sqrt(pi)/2
                var size = radius * Math.sqrt(Math.PI) / 2;
                ctx.moveTo(x - size, y - size);
                ctx.lineTo(x + size, y + size);
                ctx.moveTo(x - size, y + size);
                ctx.lineTo(x + size, y - size);
            },
            rectangle: function (ctx, x, y, radius, shadow) {
                // pi * r^2 = (2s)^2  =>  s = r * sqrt(pi)/2
                var size = radius * Math.sqrt(Math.PI) / 2;
                ctx.rect(x + 2, y - 8, 5, 8); //5 - width, 9 - height
            },
            rectangleGraph: function (ctx, x, y, radius, shadow) {
                // pi * r^2 = (2s)^2  =>  s = r * sqrt(pi)/2
                var size = radius * Math.sqrt(Math.PI) / 2;
                //ctx.rect(x + 3, y - 8, 12, 1); //12 - width, 1 - height
                ctx.rect(x - 6, y + 1, 12, 1); //12 - width, 1 - height
            }
        };

        var s = series.points.symbol;
        if (handlers[s]) series.points.symbol = handlers[s];
    }

    function init(plot) {
        plot.hooks.processDatapoints.push(processRawData);
    }

    $.plot.plugins.push({
        init: init,
        name: 'symbols',
        version: '1.0'
    });
})(jQuery);
// end of symbol plugin


$(document).ready(function () {
    var graphData = [
        [0, "42.00"],
        [1, "42.00"],
        [2, "42.00"],
        [3, "42.00"],
        [4, "42.00"],
        [5, "42.00"],
        [6, "42.00"],
        [7, "42.00"],
        [8, "42.00"],
        [9, "42.00"],
        [10, "42.00"],
        [11, "42.00"],
        [12, "43.00"],
        [13, "43.00"],
        [14, "43.00"],
        [15, "43.00"],
        [16, "43.00"],
        [17, "43.00"],
        [18, "43.00"],
        [19, "43.00"],
        [20, "43.00"],
        [21, "43.00"],
        [22, "43.00"],
        [23, "42.00"],
        [24, "42.00"],
        [25, "42.00"],
        [26, "41.00"],
        [27, "41.00"],
        [28, "41.00"],
        [29, "41.00"],
        [30, "41.00"],
        [31, "41.00"],
        [32, "41.00"],
        [33, "41.00"],
        [34, "41.00"],
        [35, "41.00"],
        [36, "41.00"],
        [37, "40.00"],
        [38, "40.00"],
        [39, "41.00"],
        [40, "41.00"],
        [41, "40.00"]
    ];

    var trendData = [
        [0, "41.60"],
        [1, "39.93"],
        [2, "39.13"],
        [3, "38.87"],
        [4, "38.20"],
        [5, "37.93"],
        [6, "37.13"],
        [7, "36.73"],
        [8, "36.27"],
        [9, "36.07"],
        [10, "34.60"],
        [11, "35.20"],
        [12, "35.00"],
        [13, "33.53"],
        [14, "34.07"],
        [15, "33.47"],
        [16, "32.93"],
        [17, "31.40"],
        [18, "32.07"],
        [19, "30.07"],
        [20, "28.80"],
        [21, "29.00"],
        [22, "28.67"],
        [23, "29.20"],
        [24, "26.13"],
        [25, "28.40"],
        [26, "26.27"],
        [27, "25.07"],
        [28, "25.07"],
        [29, "24.53"],
        [30, "25.80"],
        [31, "20.40"],
        [32, "25.07"],
        [33, "23.27"],
        [34, "22.13"],
        [35, "22.07"],
        [36, "20.27"],
        [37, "22.07"],
        [38, "18.67"],
        [39, "19.13"],
        [40, "18.87"],
        [41, "18.67"]
    ];

    var data1 = [{
        data: graphData,
        bars: {
            show: true,
            lineWidth: 3,
            horizontal: false,
            fillColor: "#f8e7b3",
            align: "center"
        },
        color: "#ffffff"
    }, {
        data: trendData,
        points: {
            show: true,
            lineWidth: 3,
            radius: 10,
            fill: true,
            fillColor: "#000000",
            symbol: "rectangleGraph"
        },
        color: "#000000"
    }];

    $.plot($(".graph"), data1, {
        grid: {
            tickColor: "#eee",
            borderColor: "#eee",
            borderWidth: 1,
            hoverable: true,
            clickable: true
        },
        xaxis: {
            show: true,
            //*
            transform: function (v) {
                return -v;
            },
            inverseTransform: function (v) {
                return -v;
            }
            //*/
        },
        yaxis: {
            show: true,
            position: "right"
        }
    });
});
.graph {
    width: 800x;
    height: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/flot/0.8.2/jquery.flot.min.js"></script>
<div class="graph bar"></div>

Need Your Help

Can I use different CSS background images based on browser type?

html css html5 css3 svg

I have a basic website design and for the logo I have created a simple SVG image. This image is very basic and just contains some text, a polyline and a dropshadow effect using feOffset as describe...

Collection is being changed in another thread before GUI thread is done with it

c# .net multithreading

I'm writing a program to record load cell data. The data collecting is done in a separate thread. The collection the data is stored in, is passed back every .5 seconds to the UI where is it display...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.