Generate bar chart based on Min and Max value

TeeChart for JavaScript for the HTML5 Canvas
Post Reply
SenSeo
Newbie
Newbie
Posts: 71
Joined: Wed Mar 09, 2016 12:00 am

Generate bar chart based on Min and Max value

Post by SenSeo » Tue Apr 05, 2016 11:50 am

We are developing a graph to generate a bar chart based on Min and Max value which is coming from database.We are using Origin property to set min value and data value property of y axis is used to set Max value. Based on this we are able to generate a bar chart. But bar is not generated properly based on min value.Please refer the below code samples which we used . Please advise us how can we set min, max value dynamically.

Code: Select all

<!DOCTYPE html>
<html>
<head>
    <title>TeeChart JavaScript Date Time Chart Example</title>

    <!--[if lt IE 9]>
        <script src="../../src/excanvas/excanvas_text.js"></script>
        <script src="../../src/excanvas/canvas.text.js"></script>
    <![endif]-->

    <script src="Scripts/TeeChart/teechart.js"></script>
    <script src="Scripts/TeeChart/teechart-extras.js"></script>
    <script src="Scripts/TeeChart/teechart-animations.js"></script>
    <script src="Scripts/TeeChart/date.format.js"></script>

    <script type="text/javascript">
var Chart1;
function draw() {
    


    Chart1 = new Tee.Chart("canvas");
    Chart1.axes.left.title.text = "Value";
    Chart1.axes.bottom.title.text = "Time";
    Chart1.title.text = "DateTime X data";
    var series = Chart1.addSeries(new Tee.Bar(Chart1)), today = new Date().getTime();
    
    var values = [50, 20, 30, 40, 50, 60, 70, 80, 90, 100];

    var minValues = [10, 10, 15, 20, 25, 30, 40, 50, 60, 70];
    
    series.data.x = [];
   
    var msecsInADay = 86400000;
    
    
    for (var t = 0; t < 10; t++) {

        series.data.values[t] = values[t];       
        series.data.x[t] = new Date(today + t * msecsInADay);
        series.marks.visible = false;
        series.useOrigin = true;        
        series.origin = minValues[t];        

    }
    

    
    Chart1.axes.bottom.labels.dateFormat = "shortTime";

    Chart1.draw();
}
    </script>
</head>
<body onload="draw()">

   

    <center>
        <br><canvas id="canvas" width="600" height="400">
            This browser does not seem to support HTML5 Canvas.
        </canvas>
    </center>
</body>
</html>

Yeray
Site Admin
Site Admin
Posts: 9613
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Generate bar chart based on Min and Max value

Post by Yeray » Wed Apr 06, 2016 11:29 am

Hello,

The Bar series is designed to have a unique origin for the whole series, not an origin for each value.
Try using a Bar series for each value instead. Ie:

Code: Select all

    var series, today = new Date().getTime();
    var values = [50, 20, 30, 40, 50, 60, 70, 80, 90, 100];
    var minValues = [10, 10, 15, 20, 25, 30, 40, 50, 60, 70];
   
    var msecsInADay = 86400000;
   
    for (var t = 0; t < 10; t++) {

        series = Chart1.addSeries(new Tee.Bar(Chart1));
        series.data.values[0] = values[t];       
        series.data.x = [];
        series.data.x[0] = new Date(today + t * msecsInADay);
        series.marks.visible = false;
        series.useOrigin = true;       
        series.origin = minValues[t];       
    }
  
    Chart1.axes.bottom.labels.dateFormat = "shortTime";  
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

SenSeo
Newbie
Newbie
Posts: 71
Joined: Wed Mar 09, 2016 12:00 am

Re: Generate bar chart based on Min and Max value

Post by SenSeo » Thu Apr 07, 2016 9:53 am

Thanks for your reply. We already used the bar series to show bar for min and max values, and it worked as expected.But one problem what we found is that the bar is not aligned properly(it is moved from x axis value) when we tried to draw line on top of bar chart.

Is there any way to fix alignment of bar when we draw any object on this?

Yeray
Site Admin
Site Admin
Posts: 9613
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Generate bar chart based on Min and Max value

Post by Yeray » Fri Apr 08, 2016 9:15 am

Hello,
SenSeo wrote:But one problem what we found is that the bar is not aligned properly(it is moved from x axis value) when we tried to draw line on top of bar chart.

Is there any way to fix alignment of bar when we draw any object on this?
Adding this code to the example in my last post draws a line on top of each bar correctly:

Code: Select all

  var myFormat = new Tee.Format(Chart1);

  Chart1.ondraw=function() {
      var visibleSeries = Chart1.series.visibleCount();
      var axisSize = Chart1.axes.bottom.axisSize;
      var tmpBarSize = axisSize / visibleSeries;
      
      for (var i=0; i<Chart1.series.count(); i++) {
        var xOffset = (tmpBarSize*Chart1.series.items[i].barSize*0.01) * (i -(visibleSeries*0.5));
        xOffset += (tmpBarSize*Chart1.series.items[i].barSize*0.01) / 2;
        var x1 = Chart1.axes.bottom.calc(Chart1.series.items[i].data.x[0]) + xOffset,
        y1 = Chart1.axes.left.calc(Chart1.series.items[i].data.values[0]);

        Chart1.ctx.beginPath();
        Chart1.ctx.moveTo(x1, y1);
        Chart1.ctx.lineTo(x1, y1-20);
    
        myFormat.stroke.fill=Chart1.series.items[i].getFill(i);
        myFormat.stroke.prepare();
        Chart1.ctx.stroke();
      }
  }
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

SenSeo
Newbie
Newbie
Posts: 71
Joined: Wed Mar 09, 2016 12:00 am

Re: Generate bar chart based on Min and Max value

Post by SenSeo » Wed Apr 13, 2016 6:31 am

Hello Team,

We have tried with your code. But still the problem remains the same. Below is my code to draw the bar and line together.

Code: Select all

<!DOCTYPE html>
<html>
<head>
    <title></title>
	<meta charset="utf-8" />
    <script src="Scripts/TeeChart/teechart.js"></script>
    <script src="Scripts/TeeChart/teechart-extras.js"></script>
    <script src="Scripts/TeeChart/teechart-animations.js"></script>
    <script src="Scripts/TeeChart/date.format.js"></script>
    <script type="text/javascript">
        var Chart1;

        function draw() {
            Chart1 = new Tee.Chart("canvas1");
            var myFormat = new Tee.Format(Chart1);

            var series, series1, series2, today = new Date().getTime();
            var values = [50, 20, 30];
            var minValues = [20, 15, 15];

            var values1 = [35, 15, 30];
            var minValues1 = [25, 20, 15];

            var avg = [30, 18, 22];

            var msecsInADay = 86400000;

            for (var t = 0; t < 3; t++) {

                series = Chart1.addSeries(new Tee.Bar(Chart1));
                series.data.values[0] = values[t];
                series.data.x = [];
                series.data.x[0] = new Date(today + t * msecsInADay);
                series.marks.visible = false;
                series.useOrigin = true;
                series.origin = minValues[t];
                series.barSize = 8;


                series1 = Chart1.addSeries(new Tee.Bar(Chart1));
                series1.data.values[0] = values1[t];
                series1.data.x = [];
                series1.data.x[0] = new Date(today + t * msecsInADay);
                series1.marks.visible = false;
                series1.useOrigin = true;
                series1.origin = minValues1[t];
                series1.barSize = 8;

                series2 = Chart1.addSeries(new Tee.Line(Chart1));
                series2.data.values[0] = avg[t];
                series2.data.x = [];
                series2.data.x[0] = new Date(today + t * msecsInADay);
                series2.format.stroke.size = 10;
                series2.pointer.visible = true;
                series2.pointer.style = "ellipse";
            }

            Chart1.axes.bottom.labels.dateFormat = "shortTime";

            Chart1.ondraw = function () {
                var visibleSeries = Chart1.series.visibleCount();
                var axisSize = Chart1.axes.bottom.axisSize;
                var tmpBarSize = axisSize / visibleSeries;

                for (var i = 0; i < Chart1.series.count() ; i++) {
                    var xOffset = (tmpBarSize * Chart1.series.items[i].barSize * 0.01) * (i - (visibleSeries * 0.5));
                    xOffset += (tmpBarSize * Chart1.series.items[i].barSize * 0.01) / 2;
                    var x1 = Chart1.axes.bottom.calc(Chart1.series.items[i].data.x[0]) + xOffset,
                    y1 = Chart1.axes.left.calc(Chart1.series.items[i].data.values[0]);

                    Chart1.ctx.beginPath();
                    Chart1.ctx.moveTo(x1, y1);
                    Chart1.ctx.lineTo(x1, y1 - 20);

                    myFormat.stroke.fill = Chart1.series.items[i].getFill(i);
                    myFormat.stroke.prepare();
                    Chart1.ctx.stroke();
                }
            }
            Chart1.draw();
            
        }

    </script>
</head>
<body onload="draw()">
    <center>
        <br><canvas id="canvas1" width="1000" height="400">
            This browser does not seem to support HTML5 Canvas.
        </canvas>
    </center>
</body>
</html>
Kindly check the sample code and assist to fix the bar and line position exactly.

For your quick reference we have attached the output chart image.

Thanks!
Attachments
BarandLine.jpg
BarandLine.jpg (83.43 KiB) Viewed 28489 times

Yeray
Site Admin
Site Admin
Posts: 9613
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Generate bar chart based on Min and Max value

Post by Yeray » Wed Apr 13, 2016 2:14 pm

Hello,
SenSeo wrote: Kindly check the sample code and assist to fix the bar and line position exactly.
I've modified your onDraw function a little bit:

Code: Select all

    Chart1.ondraw = function () {
        var visibleSeries = 0;
        for (var i = 0; i < Chart1.series.count() ; i++) {
            if (Chart1.series.items[i] instanceof Tee.Bar) {
                visibleSeries++;
            }
        }
        
        var axisSize = Chart1.axes.bottom.axisSize;
        var tmpBarSize = axisSize / visibleSeries;

        var nNoBarSeries = 0;
        for (var i = 0; i < Chart1.series.count() ; i++) {
            if (Chart1.series.items[i] instanceof Tee.Bar) {
                var barSize = (tmpBarSize * Chart1.series.items[i].barSize * 0.01);
                var xOffset = barSize * (i - (visibleSeries * 0.5));
                xOffset += barSize / 2;
                xOffset -= barSize * nNoBarSeries;
                var x1 = Chart1.axes.bottom.calc(Chart1.series.items[i].data.x[0]) + xOffset,
                y1 = Chart1.axes.left.calc(Chart1.series.items[i].data.values[0]);

                Chart1.ctx.beginPath();
                Chart1.ctx.moveTo(x1, y1);
                Chart1.ctx.lineTo(x1, y1 - 20);

                myFormat.stroke.fill = Chart1.series.items[i].getFill(i);
                myFormat.stroke.prepare();
                Chart1.ctx.stroke();
            }
            else
                nNoBarSeries++;
        }
    }
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

SenSeo
Newbie
Newbie
Posts: 71
Joined: Wed Mar 09, 2016 12:00 am

Re: Generate bar chart based on Min and Max value

Post by SenSeo » Fri Apr 15, 2016 9:18 am

Hello,

I have also tried with your modified code. But, still the problem remains the same.

Yeray
Site Admin
Site Admin
Posts: 9613
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Generate bar chart based on Min and Max value

Post by Yeray » Mon Apr 18, 2016 8:58 am

Hello,

This is what I'm getting:
BarsWithLines.png
BarsWithLines.png (46.6 KiB) Viewed 28464 times
with this code:

Code: Select all

<!DOCTYPE html>
<html>
<head>
    <link rel="shortcut icon" href="favicon.ico">
<title>Testing</title>

<!--[if lt IE 9]>
    <script src="../src/excanvas/excanvas_text.js"></script>
    <script src="../src/excanvas/canvas.text.js"></script>
<![endif]-->

<script src="../src/date.format.js" type="text/javascript"></script>
<script src="../src/Three.js" type="text/javascript"></script>
<script src="../src/teechart.js" type="text/javascript"></script>
<script src="../src/teechart-extras.js" type="text/javascript"></script>
<script src="../src/teechart-3d.js" type="text/javascript"></script>

<script type="text/javascript">

var Chart1;

function draw() {
  Chart1 = new Tee.Chart("canvas1");
  
    var myFormat = new Tee.Format(Chart1);

    var series, series1, series2, today = new Date().getTime();
    var values = [50, 20, 30];
    var minValues = [20, 15, 15];

    var values1 = [35, 15, 30];
    var minValues1 = [25, 20, 15];

    var avg = [30, 18, 22];

    var msecsInADay = 86400000;

    for (var t = 0; t < 3; t++) {

        series = Chart1.addSeries(new Tee.Bar(Chart1));
        series.data.values[0] = values[t];
        series.data.x = [];
        series.data.x[0] = new Date(today + t * msecsInADay);
        series.marks.visible = false;
        series.useOrigin = true;
        series.origin = minValues[t];
        series.barSize = 8;
    
        series1 = Chart1.addSeries(new Tee.Bar(Chart1));
        series1.data.values[0] = values1[t];
        series1.data.x = [];
        series1.data.x[0] = new Date(today + t * msecsInADay);
        series1.marks.visible = false;
        series1.useOrigin = true;
        series1.origin = minValues1[t];
        series1.barSize = 8;

        series2 = Chart1.addSeries(new Tee.Line(Chart1));
        series2.data.values[0] = avg[t];
        series2.data.x = [];
        series2.data.x[0] = new Date(today + t * msecsInADay);
        series2.format.stroke.size = 10;
        series2.pointer.visible = true;
        series2.pointer.style = "ellipse";
    }

    Chart1.axes.bottom.labels.dateFormat = "shortTime";

    Chart1.ondraw = function () {
        var visibleSeries = 0;
        for (var i = 0; i < Chart1.series.count() ; i++) {
            if (Chart1.series.items[i] instanceof Tee.Bar) {
                visibleSeries++;
            }
        }
        
        var axisSize = Chart1.axes.bottom.axisSize;
        var tmpBarSize = axisSize / visibleSeries;

        var nNoBarSeries = 0;
        for (var i = 0; i < Chart1.series.count() ; i++) {
            if (Chart1.series.items[i] instanceof Tee.Bar) {
                var barSize = (tmpBarSize * Chart1.series.items[i].barSize * 0.01);
                var xOffset = barSize * (i - (visibleSeries * 0.5));
                xOffset += barSize / 2;
                xOffset -= barSize * nNoBarSeries;
                var x1 = Chart1.axes.bottom.calc(Chart1.series.items[i].data.x[0]) + xOffset,
                y1 = Chart1.axes.left.calc(Chart1.series.items[i].data.values[0]);

                Chart1.ctx.beginPath();
                Chart1.ctx.moveTo(x1, y1);
                Chart1.ctx.lineTo(x1, y1 - 20);

                myFormat.stroke.fill = Chart1.series.items[i].getFill(i);
                myFormat.stroke.prepare();
                Chart1.ctx.stroke();
            }
            else
                nNoBarSeries++;
        }
    }
    
    Chart1.draw();
}

</script>
</head>
<body onload="draw()">
<br><canvas id="canvas1" width="1000" height="400">
This browser does not seem to support HTML5 Canvas.
</canvas>
</body>
</html>
Don't you get the same?
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

SenSeo
Newbie
Newbie
Posts: 71
Joined: Wed Mar 09, 2016 12:00 am

Re: Generate bar chart based on Min and Max value

Post by SenSeo » Wed Apr 20, 2016 11:20 am

Hello,

As per your attached image, bar and point is not plotted to correct position even I have used the same x-axis value for both.

Yeray
Site Admin
Site Admin
Posts: 9613
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Generate bar chart based on Min and Max value

Post by Yeray » Thu Apr 21, 2016 8:06 am

Hello,

I thought we were talking about drawing lines on top of the bars. But I understand we are now talking about the pointers of the line series.
I'm afraid this isn't possible at the moment. The problem is we are using many Bar series to workaround the origin limitation but this makes the chart to think there are many bar series being drawn at each value, and it's leaving space for all them; but the points from the Line series (why don't you use a PointXY series?) are always drawn at the center of the values, giving this effect.

But I've been working with it to try to give you some alternative. And I think the best would be to improve the Bar series to accept an array as "origin", so you can use only two Bar series and a PointXY series instead of repeating all them.
With this modification, if I do this, without the for loop:

Code: Select all

    var myFormat = new Tee.Format(Chart1);

    var series, series1, series2, today = new Date().getTime();
    var values = [50, 20, 30];
    var minValues = [20, 15, 15];

    var values1 = [35, 15, 30];
    var minValues1 = [25, 20, 15];

    var avg = [30, 18, 22];

    var msecsInADay = 86400000;

        series = Chart1.addSeries(new Tee.Bar(Chart1));
        series.data.values = values;
        series.data.x = [];
        series.data.x = [new Date(today + msecsInADay), new Date(today + 2 * msecsInADay), new Date(today + 3 * msecsInADay)];
        series.marks.visible = false;
        series.useOrigin = true;
        series.origin = minValues; //teechart.js modified to accept an array here
        series.barSize = 8;
    
        series1 = Chart1.addSeries(new Tee.Bar(Chart1));
        series1.data.values = values1;
        series1.data.x = [];
        series1.data.x = [new Date(today + msecsInADay), new Date(today + 2 * msecsInADay), new Date(today + 3 * msecsInADay)];
        series1.marks.visible = false;
        series1.useOrigin = true;
        series1.origin = minValues1; //teechart.js modified to accept an array here
        series1.barSize = 8;

        series2 = Chart1.addSeries(new Tee.PointXY(Chart1));
        series2.data.values = avg;
        series2.data.x = [];
        series2.data.x = [new Date(today + msecsInADay), new Date(today + 2 * msecsInADay), new Date(today + 3 * msecsInADay)];
        series2.format.stroke.size = 10;
        series2.pointer.visible = true;
        series2.pointer.style = "ellipse";
originsArray.png
originsArray.png (41.52 KiB) Viewed 28450 times
I've added it to the public tracker and closed the ticket:
http://bugs.teechart.net/show_bug.cgi?id=1517

So the next maintenance release will include this change.
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

SenSeo
Newbie
Newbie
Posts: 71
Joined: Wed Mar 09, 2016 12:00 am

Re: Generate bar chart based on Min and Max value

Post by SenSeo » Thu Apr 21, 2016 10:31 am

Hello,

Can you please share the modified Teechart.js script file to accept array for Origin? If you share the updated script file that would be better for us. Actually, we are expecting to pass the array value to the Origin.

Thanks!

Yeray
Site Admin
Site Admin
Posts: 9613
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Generate bar chart based on Min and Max value

Post by Yeray » Fri Apr 22, 2016 9:04 am

Hello,

I've just sent it to the mail account you have registered in these forums.
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Post Reply