Page 1 of 1
Group bars/draw line to separate bar groups/add axes?
Posted: Tue Dec 09, 2014 1:06 pm
by 17770651
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
Re: Group bars/draw line to separate bar groups/add axes?
Posted: Wed Dec 10, 2014 11:41 am
by yeray
Hello,
Do you have a simple example in VB6 we can take as model?
Re: Group bars/draw line to separate bar groups/add axes?
Posted: Fri Dec 12, 2014 1:58 pm
by 17770651
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
Re: Group bars/draw line to separate bar groups/add axes?
Posted: Mon Dec 15, 2014 12:17 pm
by yeray
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.
Re: Group bars/draw line to separate bar groups/add axes?
Posted: Thu Dec 18, 2014 10:56 am
by 17770651
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>
Re: Group bars/draw line to separate bar groups/add axes?
Posted: Fri Dec 19, 2014 2:54 pm
by yeray
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);
}
Re: Group bars/draw line to separate bar groups/add axes?
Posted: Tue Jan 20, 2015 1:35 pm
by 17770651
Dear Yeray,
Thank you very much for your help, it works fine.
Kind regards,
Juliane
Re: Group bars/draw line to separate bar groups/add axes?
Posted: Mon May 04, 2015 1:23 pm
by 17770651
Hello,
I would like to add to this code just one feature (see below), but legend annotations are empty.
Regards, Juliane
Re: Group bars/draw line to separate bar groups/add axes?
Posted: Tue May 05, 2015 11:17 am
by yeray
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