Group bars/draw line to separate bar groups/add axes?

TeeChart for Javascript for the HTML5 Canvas
Post Reply
matt
Newbie
Newbie
Posts: 13
Joined: Fri Nov 07, 2014 12:00 am

Group bars/draw line to separate bar groups/add axes?

Post by matt » Tue Dec 09, 2014 1:06 pm

I need to group several bars within one series (because there is a relation in between) and to draw an annotated Line (e.g. Job A) for visual separation. Concerning that topic I studied the example code for multiple axes and tried to adopt it but not yet successfully. The snapshot shows a Tee-Bar-Chart-example which is realized in VB6, but I have to implement it by HTML5/JavaScript. Any help would be nice.

Thanks, Juliane
Attachments
examp_barchart.png
Tee-Bar-Chart-example, realized in VB6
examp_barchart.png (40.09 KiB) Viewed 8559 times
Last edited by matt on Fri Dec 19, 2014 11:46 am, edited 1 time in total.

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

Re: Group bars/draw line to separate bar groups/add axes?

Post by Yeray » Wed Dec 10, 2014 11:41 am

Hello,

Do you have a simple example in VB6 we can take as model?
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

matt
Newbie
Newbie
Posts: 13
Joined: Fri Nov 07, 2014 12:00 am

Re: Group bars/draw line to separate bar groups/add axes?

Post by matt » Fri Dec 12, 2014 1:58 pm

Dear Yeray,

Here the VB6 code:

Code: Select all

'
' shows qsv bar chart.
' shows 1-mean bar chart
'
Private Sub ShowQSVMeanChart( _
        ByVal sTeeFile As String, _
        ctType As ChartType)

    Dim cQSVData As Dictionary
    Dim cSubstAlias As Dictionary
    Dim cSubstQSV As Dictionary
    Dim cSubstGroup As Dictionary
    Dim cSubstRank As Dictionary
    Dim cSubstJob As Dictionary
    Dim cGroups As Dictionary
    Dim cSubstRel As Dictionary
    Dim cSubstRelAlias As Dictionary
    Dim cJobs As Dictionary
    Dim vSubstance, vGroup, vSubst
    Dim bDummy As Boolean
    Dim nPos As Long
    Dim nIndex As Long
    Dim clColor As OLE_COLOR
    Dim clColors(6) As OLE_COLOR
    
    If ctType <> ctQSV And ctType <> ctMean Then
        RaiseError vbError, "ICChart.ShowQSVChart()", "Invalid chart type."
    End If
    
    Set cGroups = New Dictionary
    Set cJobs = New Dictionary
    
    ' get qsv data
    Set cQSVData = GetQSVMeanData(ctType)
    
    ' split data in single dic's
    Set cSubstAlias = cQSVData("alias")
    Set cSubstGroup = cQSVData("group")
    Set cSubstRank = cQSVData("rank")
    Set cSubstQSV = cQSVData("qsv")
    Set cSubstJob = cQSVData("job")
    Set cSubstRel = cQSVData("rel")
    Set cSubstRelAlias = cQSVData("rel_alias")
    
    ' get group count
    nPos = 1
    For Each vSubstance In cSubstGroup.Keys()
        If Not cGroups.Exists(cSubstGroup(vSubstance)) Then
            cGroups.Add cSubstGroup(vSubstance), nPos
            nPos = nPos + 1
        End If
    Next
    
    ' show chart now: prepare chart for qsv
    With frmICChart.tchSeries
    
        .ClearChart
        .Import.LoadFromFile sTeeFile     ' load config
        
        .RemoveAllSeries
        .Header.Text.Clear
        .Legend.Visible = False
        .Zoom.Enable = True
        .Zoom.Animated = True
        .Zoom.AnimatedSteps = 15
        .Zoom.Direction = tzdBoth
        .Zoom.MouseButton = mbLeft
        .Zoom.Brush.Style = bsClear
        .Axis.Bottom.Labels.Separation = 0
        .Canvas.Pen.Width = 0
        
        If ctType = ctQSV Then
            .Header.Text.Add UCase(qsvFeature)
            .Axis.Left.Title.Caption = UCase(qsvFeature) + " VALUES"
            .Axis.Bottom.Title.Caption = sChartQSVAxisBottomTitle
        End If
        
        If ctType = ctMean Then
            .Header.Text.Add UCase(signalFeature)
            .Axis.Left.Title.Caption = UCase(signalFeature) + " VALUES"
            .Axis.Bottom.Title.Caption = sChartMeanAxisBottomTitle
        End If
    End With

    ' a little color palette
    clColors(0) = vbRed
    clColors(1) = vbBlue
    clColors(2) = vbGreen
    clColors(3) = vbMagenta
    clColors(4) = vbYellow
    clColors(5) = vbCyan
    clColors(6) = vbBlack

    Dim nPosFix
    ' add series to chart
    nPos = 0
    nPosFix = 0
    nIndex = 1
    bDummy = True
    
    Dim xyz
    With frmICChart.tchSeries.Series(frmICChart.tchSeries.AddSeries(scBar))
        .asBar.MultiBar = mbSide
        .asBar.AutoBarSize = True
        .asBar.BarWidthPercent = 80
        .asBar.BarPen.Width = 0
        .Marks.Visible = False
        
        For Each vSubstance In cSubstGroup.Keys
            nPos = nPos + 1
            nPosFix = nPos
            .AddXY nPos, cSubstQSV(vSubstance), cSubstAlias(vSubstance), vbRed
            For Each xyz In cSubstRel(vSubstance)
                nPos = nPos + 1
                .AddXY nPosFix + cSubstRel(vSubstance)(xyz), cSubstQSV(xyz), cSubstRelAlias(vSubstance)(xyz), vbBlue
            Next
            nPos = nPos + 1
            cJobs.Add nPos - 0.2, cSubstJob(vSubstance)
            .AddNullXY nPos, cSubstQSV(xyz), vbNullString ', frmICChart.BackColor
        Next
        
        'frmICChart.tchSeries.Axis.Bottom.Labels.Font.Size = 7
        'frmICChart.tchSeries.Axis.Left.Labels.Font.Size = 7
        'If .Count > nScaleDownLimit1 Then
        '    frmICChart.tchSeries.Axis.Bottom.Labels.Font.Size = 6
        '    frmICChart.tchSeries.Axis.Left.Labels.Font.Size = 6
        'End If
        'If .Count > nScaleDownLimit2 Then
        '    frmICChart.tchSeries.Axis.Bottom.Labels.Font.Size = 4
        '    frmICChart.tchSeries.Axis.Left.Labels.Font.Size = 4
        'End If
        
    End With

    With frmICChart
        Set .Jobs = cJobs
        .GroupDistance = cGroups.Count()
        .tchSeries.Zoom.Undo
        .tchSeries.Repaint
        .countData = nPos
    
        .tchSeries_Init
    End With
End Sub
Regards, Juliane

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

Re: Group bars/draw line to separate bar groups/add axes?

Post by Yeray » Mon Dec 15, 2014 12:17 pm

Hi Juliane,

There are many variables being used in that code snipped we don't have here. Could you please arrange a simple example project we can run as-is to reproduce the problem here?

Thanks in advance.
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

matt
Newbie
Newbie
Posts: 13
Joined: Fri Nov 07, 2014 12:00 am

Re: Group bars/draw line to separate bar groups/add axes?

Post by matt » Thu Dec 18, 2014 10:56 am

Hello,
The data structure looks like this: attached code. The values for the targets are derived from variable “bar_data”. The requirements are the following:
Groups of targets are to be shown in given order.
Group name (job) must be recognizable for related targets.
The bar of first target of group is to be shown in different color.
The font size of labels for targets should be resized automatically in case there are lots of bars to be shown.
Editor: WebStorm8.0.5

Thanks,
Juliane

Code: Select all

<!DOCTYPE html>
<html>
<head>
    <title>Groups of Bars</title>
    <script src="js/teechart.js" type="text/javascript"></script>
    <script>
        function draw() {

            var rel_groups = [["jobA", ['target5','target4','target11']], ["jobB", ['target13']],["jobC", ['target8','target7','target6']]];

            var bar_data = ['mg_name1',{'target1':7,'target2':8,'target3':9,'target4':4,'target5':3,'target6':2,'target7':11,'target8':5,'target9':6,'target10':12,'target11':10,'target12':14,'target13':16},'feat_name1'];

            var target_val = bar_data[1];

            var val_array = [];
            var x_array = []; //  to be solved: bar groups
            var target_name = []; //  to be solved: grouped target_names
            var number_target;
            var line; // to be solved: Line after jobA
            var anno; //  to be solved: Annotation: for example "jobA" for Line after jobA



            for (var i = 0; i < rel_groups.length; i++)
            {
                var iter = rel_groups[i][1];

                for (var k = 0; k < iter.length; k++)
                {
                    target_name = rel_groups[i][1][k];

                    for (target in target_val)
                    {
                        if (target == target_name)
                        {
                            x_array.push (target);
                            val_array.push (target_val[target]);
                        }
                    }
                }
            }

            number_target = x_array.length;
            var x_array_numb = new Array(number_target);
            x_array_numb[0] = 1;

            for (var i = 0; i<number_target; ++i) {
                x_array_numb[i] = i;
            }

            Chart1=new Tee.Chart("canvas");

            var vdata1 = new Tee.Bar();
            Chart1.addSeries(vdata1);
            vdata1.data.values = val_array;
            vdata1.data.x =  x_array_numb;

            Chart1.axes.bottom.labels.ongetlabel=function(value,s)
            {
                  return x_array[value]
            }

            Chart1.title.text="Groups of Bars?";
            Chart1.axes.bottom.labels.rotation = 90;
            Chart1.draw();
        }
    </script>


</head>
<body onload="draw()">
    <br><canvas id="canvas" width="600" height="400">
    This browser does not seem to support HTML5 Canvas.
    </canvas>


</body>
</html>

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

Re: Group bars/draw line to separate bar groups/add axes?

Post by Yeray » Fri Dec 19, 2014 2:54 pm

Hello ,

Take a look at this variant.
I'm manually drawing the vertical lines and the "group" texts:

Code: Select all

function draw() {
    var rel_groups = [["jobA", ['target5','target4','target11']], ["jobB", ['target13']],["jobC", ['target8','target7','target6']]];

    var bar_data = ['mg_name1',{'target1':7,'target2':8,'target3':9,'target4':4,'target5':3,'target6':2,'target7':11,'target8':5,'target9':6,'target10':12,'target11':10,'target12':14,'target13':16},'feat_name1']

	var target_val = bar_data[1];
	
	var val_array = [];
    var x_array = []; //  to be solved: bar groups
    var target_name = []; //  to be solved: grouped target_names
    var number_target;
    var line; // to be solved: Line after jobA
    var anno; //  to be solved: Annotation: for example "jobA" for Line after jobA

	for (var i = 0; i < rel_groups.length; i++)
    {
		var iter = rel_groups[i][1];

		for (var k = 0; k < iter.length; k++)
        {
			target_name = rel_groups[i][1][k];

			for (target in target_val)
			{
				if (target == target_name)
				{
					x_array.push (target);
					val_array.push (target_val[target]);
				}
			}
		}
	}

	number_target = x_array.length;
	var x_array_numb = new Array(number_target);
	x_array_numb[0] = 1;

	for (var i = 0; i<number_target; ++i) {
		x_array_numb[i] = i;
	}
			
    Chart1=new Tee.Chart("canvas1");

    Chart1.ondraw=function() {
		var c=Chart1.ctx,
			y0=Chart1.chartRect.y, y1=Chart1.chartRect.getBottom();

		c.beginPath();

		var pos = 0;
		var diff = Chart1.axes.bottom.calc(0.5) - Chart1.axes.bottom.calc(0);
		var f =  new Tee.Format(Chart1);
		var r = new Rectangle();
		r.height=f.textHeight("Wj");
		
		for (var i = 0; i<rel_groups.length; i++) {
			c.moveTo( pos + Chart1.axes.bottom.calc(rel_groups[i][1].length) - diff, y0 );
			c.lineTo( pos + Chart1.axes.bottom.calc(rel_groups[i][1].length) - diff, y1 );			
			c.strokeStyle="black";
			c.lineWidth=1;
			c.stroke();
			
			var s = rel_groups[i][0];
			r.width = f.textWidth(s);
			r.x = pos + Chart1.axes.bottom.calc(rel_groups[i][1].length) - diff - r.height;
			r.y = y0;
			f.fill = "";       
			c.save();
			c.translate(r.x, r.y);
			c.rotate(-Math.PI*90/180);
			c.textAlign = "right";
			r.x = -rotatedWidth(90, r.width) * 0.5;
			r.y = -(rotatedWidth(90, r.height) * 0.5)+3;
			f.drawText(r, s);
			c.restore();
			
			pos = pos + Chart1.axes.bottom.calc(rel_groups[i][1].length) - Chart1.axes.bottom.calc(0);
		}
	}
	
    var vdata1 = new Tee.Bar();
    Chart1.addSeries(vdata1);
    vdata1.data.values = val_array;
    vdata1.data.x = x_array_numb;
	
	Chart1.axes.bottom.labels.ongetlabel=function(value,s)
	{
		return x_array[value]
	}

    Chart1.title.text="Groups of Bars";
    Chart1.axes.bottom.labels.rotation = 90;
    Chart1.draw();
}

function Rectangle(x,y,width,height)
{
  this.set(x,y,width,height);
}

Rectangle.prototype.set=function(x,y,width,height) {
  this.x=x;
  this.y=y;
  this.width=width;
  this.height=height;
};

rotatedWidth = function(a, w) {
  return Math.abs(Math.sin(toRadians(a)) * w);
}

function toRadians(angle) {
  return angle * (Math.PI / 180);
}
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

matt
Newbie
Newbie
Posts: 13
Joined: Fri Nov 07, 2014 12:00 am

Re: Group bars/draw line to separate bar groups/add axes?

Post by matt » Tue Jan 20, 2015 1:35 pm

Dear Yeray,
Thank you very much for your help, it works fine.

Kind regards,
Juliane

matt
Newbie
Newbie
Posts: 13
Joined: Fri Nov 07, 2014 12:00 am

Re: Group bars/draw line to separate bar groups/add axes?

Post by matt » Mon May 04, 2015 1:23 pm

Hello,
I would like to add to this code just one feature (see below), but legend annotations are empty.
Regards, Juliane

Code: Select all

Chart1.legend.textStyle="label";

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

Re: Group bars/draw line to separate bar groups/add axes?

Post by Yeray » Tue May 05, 2015 11:17 am

Hello Juliane,

Setting the "label" textStyle in the legend makes it to use the strings on the series' data.labels. So, if you want to use it, you can populate the data.labels array as follows:

Code: Select all

	vdata1.data.labels = x_array;
	vdata1.marks.style="value"; //this is to force the series marks to only show the values and not the labels
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