Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Marker for JQPLOT

Tags:

jquery

css

jqplot

Is there a way to add multiple different effects to a marker?

I know that there's line, color and shadow properties, all could help me try to create the following design, however I've been failing for the past 2 hours and have come up with absolutely nothing!

enter image description here

seriesDefaults: {
    lineWidth: 50,
    color: 'yellow',
    markerRenderer: $.jqplot.MarkerRenderer,
    markerOptions: {
        show: true,
        style: 'circle',
        color: 'white',
        lineWidth: 4,
        size: 25,
        shadow: true,
        shadowAngle: 0,
        shadowOffset: 0,
        shadowDepth: 1,
        shadowAlpha: 0.07
    }
}

I feel like a need the following attributes: markerBackgroundColor, markerShadowSize to achieve my result.

Is there something I can do with css3? like create my own html for the marker and style that?

like image 328
Shannon Hochkins Avatar asked Dec 19 '22 15:12

Shannon Hochkins


2 Answers

I tried using the markerOptions properties as you did and failed. Therefore I wrote my own ShapeRenderer and used this instead of the default jqPlot one to draw both the semi-transparent outer circle and the inner marker circle. The end result looks like this:

enter image description here

I've just done a quick and dirty solution to show how it can be done this way (i.e. the colours and circle radius are defined in the ShapeRenderer). A more elegent (and reusable) way to do this would be to allow the colours, radius etc to be defined in the options and modify the custom ShapeRenderer work with the options passed in.

The custom ShapeRenderer code is as follows (this could be factored out into an external Javascript file):

(function ($) {
    $.jqplot.customMarkerRenderer = function (options) {
        $.extend(true, this, options);
    };

    $.jqplot.customMarkerRenderer.prototype.init = function (options) {
        $.extend(true, this, options);
    };

    $.jqplot.customMarkerRenderer.prototype.draw = function (ctx, points, options) {
        ctx.save();

        // Shadow
        ctx.lineWidth = 30;
        ctx.strokeStyle = 'rgba(108, 161, 93, 0.3)';
        ctx.beginPath();
        ctx.arc(points[0], points[1], points[2], points[3], points[4], true);
        ctx.closePath();
        ctx.stroke();

        // Yellow inner
        ctx.lineWidth = 10;
        ctx.fillStyle = '#F6C528';
        ctx.beginPath();
        ctx.arc(points[0], points[1], points[2], points[3], points[4], true);
        ctx.closePath();
        ctx.fill();

        ctx.restore();
    };
})(jQuery);

It can be defined in the jqchart options as follows:

markerOptions: {
    ...
    shapeRenderer: new $.jqplot.customMarkerRenderer()
}

I've created a Fiddle to demonstrate this.

like image 109
Ian A Avatar answered Jan 05 '23 15:01

Ian A


I faced with similar issue. Rather than trying to draw shapes on the context, I preferred to draw image on the context. I created a renderer plugin by which you can plot any image in place of a point.

The code for the plugin is here:

(function($) {
    $.jqplot.ImageMarkerRenderer = function() {
        $.jqplot.MarkerRenderer.call(this);
        //image element which should have src attribute populated with the image source path
        this.imageElement = null;
        //the offset to be added to the x position of the point to align the image correctly in the center of the point.
        this.xOffset = null;
        //the offset to be added to the y position of the point to align the image correctly in the center of the point.
        this.yOffset = null;
    };
    $.jqplot.ImageMarkerRenderer.prototype = new $.jqplot.MarkerRenderer();
    $.jqplot.ImageMarkerRenderer.constructor = $.jqplot.ImageMarkerRenderer;

    $.jqplot.ImageMarkerRenderer.prototype.init = function(options) {
        options = options || {};
        this.imageElement = options.imageElement;
        this.xOffset = options.xOffset || 0;
        this.yOffset = options.yOffset || 0;
        $.jqplot.MarkerRenderer.prototype.init.call(this, options);
    };

    $.jqplot.ImageMarkerRenderer.prototype.draw = function(x, y, ctx, options) {
        //draw the image onto the canvas
        ctx.drawImage(this.imageElement, x + this.xOffset, y + this.yOffset);
        ctx.restore();
        return;
    };
})(jQuery);

More information is available on my github page

like image 29
user1719160 Avatar answered Jan 05 '23 16:01

user1719160