2

Is it possible to make a chart like the example below?

Bar chart using chartjs with horizontal rule

I haven't been able to find an example with an overlay. I'm using this in the context of an atmosphere plugin within a meteor application so it might not be possible for me to easily add plugins to my chartjs instance.

I've built out quite a few charts already, so for that reason it's my strong preference to get this to work over switching to another charting library, but it's not too late to port them over if there's no other way to make this work.

Shane
  • 4,921
  • 5
  • 37
  • 53

1 Answers1

2

You could extend the Bar Chart to add the horizontal line

Chart.types.Bar.extend({
        name: "BarLine",
        draw: function () {

            Chart.types.Bar.prototype.draw.apply(this, arguments);

            var scale = this.scale,
                barHeight = this.scale.calculateY(83);


            // draw line
            this.chart.ctx.beginPath();
            this.chart.ctx.moveTo(30, barHeight);

            this.chart.ctx.strokeStyle = '#ff0000';
            this.chart.ctx.lineWidth = 3;
            this.chart.ctx.lineTo(this.chart.width, barHeight);
            this.chart.ctx.stroke();

            // write Label Text
            this.chart.ctx.fillStyle = '#000000';
            var text = this.options.labelText ? this.options.labelText : "DEFAULT TEXT" 
            this.chart.ctx.textAlign = 'center';
            this.chart.ctx.font = '22px Arial';
            this.chart.ctx.fillText(text, this.chart.width  * 0.5, 95);
            this.chart.ctx.closePath();                            

        }
    });`

You could add the bar values in the draw function i'm sure, but I generally do it in the 'onanimationcomplete' function for the chart, like so:

resultChart = new Chart(resultGraphCanvas.getContext("2d")).BarLine(chart, {

                        scaleBeginAtZero: true,
                        scaleOverride: true,
                        scaleSteps: 10,
                        scaleStepWidth: 10,
                        maintainAspectRatio: false,
                        labelText: "TEST DRAWN NEAR THE LINE",

                        showTooltips: false, //Needs to be set to false for the onAnimationComplete drawing to persist
                        onAnimationComplete: function () {


                            var ctx = this.chart.ctx;
                            ctx.font = this.scale.font;
                            ctx.fillStyle = this.scale.textColor
                            ctx.textAlign = "center";
                            ctx.textBaseline = "bottom";

                            this.datasets.forEach(function (dataset) {
                                dataset.bars.forEach(function (bar) {

                                    ctx.fillText(bar.value, bar.x, bar.y );
                                });
                            })
                        },
                    });

This will draw the values at the top of the bars, i'll leave positioning them elsewhere to you :)

Lee Brindley
  • 6,242
  • 5
  • 41
  • 62
  • Interesting... Will have to play with this given I'm in the context of Meteor + using chartJS for many other bar charts with and without guides. Plenty of food for thought here and I'll come back and mark as answer if I can abstract it and make it work. – Shane Dec 10 '15 at 12:11
  • 1
    I haven't used Meteor before, but there shouldn't be any reason (he says) why this wouldn't work. You could make it a lot more configurable by giving the BarLine chart a property that defines what level to draw the horizontal line for example – Lee Brindley Dec 10 '15 at 12:16
  • For some reason I'm not seeing labelText make it to options. Any idea what might be going on there? http://codepen.io/cshanejennings/pen/RrNEov?editors=001 – Shane Dec 10 '15 at 12:42
  • Updated your pen, all is now working . http://codepen.io/anon/pen/EPjQXO?editors=001 – Lee Brindley Dec 10 '15 at 13:03
  • 1
    Explanation is in the code, options you want to access when overriding the chart should be passed in as the second param :) – Lee Brindley Dec 10 '15 at 13:05
  • Works perfectly, plenty to go on here... thanks. Just got it working in Meteor! – Shane Dec 10 '15 at 13:59