Trying to create a dynamic Dundas Stackedarea chart - charts

Good afternoon. I try to research and have yet to find anyone that has an example of this, I normally do not ask for help, I just figure it out, but this one is killing me! I am trying to create a stacked area chart dynamically, I already can create a dynamic area chart, but cannot for the life of me figure out how to get a stacked area chart to stack the series. I have made something similar in excel and I can get it to chart fine, but it is not dynamic.
I have data that is laid out like this:
How the data is laid out
And this is how I want the chart to look:
How I want the chart to look
How can I associate the data to categories or whatever it is I need to do? I have the data in an array but I can just not seem to figure out how to get the chart to stack. Can anyone help? If you need some more info please ask, I know I am not including my code, mainly because it is very ugly and drawn out, but can try to compress it a bit and simplify if anyone needs that.
My code is below (maybe that will help, even if it is ugly)
For tmpatozgroup = 1 To 1
Dim chart1 As New Chart()
chart1.ID = "chrt-" & tmpatozgroup & "-" & atozser
Dim seriesperrow As Integer
Dim chartArea1 As New ChartArea()
chart1.Height = 340
chart1.Palette = ChartColorPalette.Dundas
chart1.BackColor = System.Drawing.Color.LightGray
chart1.BorderSkin.SkinStyle = BorderSkinStyle.Emboss
chart1.BorderLineColor = System.Drawing.Color.Gray
chart1.BorderLineStyle = ChartDashStyle.Solid
chart1.BorderLineWidth = 4
' Set the ChartArea properties
chartArea1.Name = "Default"
chartArea1.BackColor = System.Drawing.Color.LightGray
chartArea1.AxisX.LabelsAutoFit = False
chartArea1.AxisX.LabelStyle.FontAngle = -45
chartArea1.Area3DStyle.Enable3D = True
chart1.ChartAreas.Add(chartArea1)
Dim series1 As New Series()
series1.Name = tblGrouping1(tmpatozgroup, 0)
chart1.Series.Add(series1)
chart1.Legends.Clear()
If Not IsNothing(tblGrouping1(tmpatozgroup, 0)) Then
For tmpatozgroup2 = 1 To 9
Dim legend1 As New Legend()
Dim sername As String
Dim servalues() As Double
Dim serformat As String
Dim chrtSeriesCnt As Integer
sername = tblGrouping1(0, tmpatozgroup2)
'need to tear the current row out of the array and place in tmpseries
Dim tmpatozcnt As Integer
For tmpatozcnt = 1 To 999
If IsNothing(tblGrouping1(0, tmpatozcnt)) Then atozseries = tmpatozcnt : Exit For
tmpSeries(tmpatozcnt) = tblGrouping1(tmpatozgroup2, tmpatozcnt)
chrtSeriesLabels(tmpatozcnt) = tblGrouping1(0, tmpatozcnt)
Next
servalues = tmpSeries
serformat = chrtSeriesForm1
chart1.Width = 1000
seriesperrow = 1
'chart1.AlignDataPointsByAxisLabel()
series1.Type = SeriesChartType.StackedColumn
series1("StackedGroupName") = "'" & tblGrouping1(tmpatozgroup, 0) & "'"
If Not IsNothing(tblGrouping1(tmpatozgroup, 0)) Then
For Each ser As Series In chart1.Series
For i2 As Integer = 1 To atozseries - 1
ser.Points.AddXY(chrtSeriesLabels(i2), servalues(i2 - 1))
ser.Points(i2 - 1).BorderColor = Drawing.Color.FromArgb(Split(sercolor(i2), "|")(0), Split(sercolor(i2), "|")(1), Split(sercolor(i2), "|")(2))
ser.Points(i2 - 1).Color = Drawing.Color.FromArgb(Split(sercolor(i2), "|")(0), Split(sercolor(i2), "|")(1), Split(sercolor(i2), "|")(2))
'ser.XAxisType = AxisType.Secondary
Dim tooltipformat As String
If serformat = "Currency" Then serformat = "$#,##0.00" : tooltipformat = "{$#,#.00}"
If serformat = "###,###,##0.00" Then serformat = "#,##0.00" : tooltipformat = "{#,#}"
If serformat = "###,###,##0" Then serformat = "0" : tooltipformat = "{#,#}"
ser.Points(i2 - 1).ToolTip = ser.Points(i2 - 1).AxisLabel & " : #VALY" & tooltipformat
Next
chart1.ChartAreas(0).AxisX.Interval = 1
chart1.ChartAreas(0).AxisX.LabelStyle.Interval = 1
chart1.ChartAreas(0).AxisX.Title = "test" 'chrtXAxisName
chart1.ChartAreas(0).AxisY.Title = sername
chart1.ChartAreas(0).AxisY.LabelStyle.Format = serformat
chart1.Palette = ChartColorPalette.Dundas
Next
End If
Next
If seriesonrow = seriesperrow Or seriesonrow = 0 Then
tr = New TableRow
tr.CssClass = "charts column"
tr.Style("display") = "none"
End If
td = New TableCell
td.HorizontalAlign = HorizontalAlign.Center
td.ColumnSpan = 6 / seriesperrow
td.Controls.Add(chart1)
tr.Cells.Add(td)
tblReport.Rows.Add(tr)
chart1 = Nothing
End If
Next
Thanks a bunch in advance!
Later

Here's a sample:
<asp:Chart ID="Chart1" runat="server" Width="600px">
<Series>
<asp:Series Name="Series1" ChartType="StackedArea">
<Points>
<asp:DataPoint XValue="1" YValues="10" />
<asp:DataPoint XValue="2" YValues="20" />
<asp:DataPoint XValue="3" YValues="30" />
<asp:DataPoint XValue="4" YValues="15" />
</Points>
</asp:Series>
<asp:Series ChartArea="ChartArea1" ChartType="StackedArea" Name="Series2">
<Points>
<asp:DataPoint XValue="1" YValues="20" />
<asp:DataPoint XValue="2" YValues="40" />
<asp:DataPoint XValue="3" YValues="60" />
<asp:DataPoint XValue="4" YValues="45" />
</Points>
</asp:Series>
</Series>
<ChartAreas>
<asp:ChartArea Name="ChartArea1">
<AxisY>
<MajorGrid LineColor="DarkGray" LineDashStyle="Dot" />
</AxisY>
<AxisX>
<MajorGrid LineColor="DarkGray" LineDashStyle="Dot" />
</AxisX>
</asp:ChartArea>
</ChartAreas>
</asp:Chart>
EDIT: Using code-behind:
protected void Page_Load(object sender, EventArgs e)
{
Chart chart1 = new Chart();
ChartArea area1 = new ChartArea("Area1");
Series series1 = new Series();
series1.ChartType = SeriesChartType.StackedArea;
series1.Points.Add(new DataPoint { XValue = 1, YValues = new double[] { 10 } });
series1.Points.Add(new DataPoint { XValue = 2, YValues = new double[] { 20 } });
series1.Points.Add(new DataPoint { XValue = 3, YValues = new double[] { 30 } });
series1.Points.Add(new DataPoint { XValue = 4, YValues = new double[] { 15 } });
series1.ChartArea = "Area1";
Series series2 = new Series();
series2.ChartType = SeriesChartType.StackedArea;
series2.Points.Add(new DataPoint { XValue = 1, YValues = new double[] { 20 } });
series2.Points.Add(new DataPoint { XValue = 2, YValues = new double[] { 40 } });
series2.Points.Add(new DataPoint { XValue = 3, YValues = new double[] { 60 } });
series2.Points.Add(new DataPoint { XValue = 4, YValues = new double[] { 45 } });
series2.ChartArea = "Area1";
chart1.ChartAreas.Add(area1);
chart1.Series.Add(series1);
chart1.Series.Add(series2);
Controls.Add(chart1);
}
EDIT 2: adding a legend:
protected void Page_Load(object sender, EventArgs e)
{
Chart chart1 = new Chart();
ChartArea area1 = new ChartArea("Area1");
Legend legend1 = new Legend("Legend1");
legend1.Docking = Docking.Top;
legend1.Alignment = System.Drawing.StringAlignment.Center;
Series series1 = new Series("Bought");
series1.ChartType = SeriesChartType.StackedArea;
series1.Points.Add(new DataPoint { XValue = 1, YValues = new double[] { 10 } });
series1.Points.Add(new DataPoint { XValue = 2, YValues = new double[] { 20 } });
series1.Points.Add(new DataPoint { XValue = 3, YValues = new double[] { 30 } });
series1.Points.Add(new DataPoint { XValue = 4, YValues = new double[] { 15 } });
series1.ChartArea = "Area1";
series1.Legend = "Legend1";
Series series2 = new Series("Sold");
series2.ChartType = SeriesChartType.StackedArea;
series2.Points.Add(new DataPoint { XValue = 1, YValues = new double[] { 20 } });
series2.Points.Add(new DataPoint { XValue = 2, YValues = new double[] { 40 } });
series2.Points.Add(new DataPoint { XValue = 3, YValues = new double[] { 60 } });
series2.Points.Add(new DataPoint { XValue = 4, YValues = new double[] { 45 } });
series2.ChartArea = "Area1";
series2.Legend = "Legend1";
chart1.ChartAreas.Add(area1);
chart1.Legends.Add(legend1);
chart1.Series.Add(series1);
chart1.Series.Add(series2);
Controls.Add(chart1);
}

Related

LineSeries Multiple Date Axes breaks the DateAxis (Amcharts 4 )

I am trying to make a multiple date axis graph in AmCharts 4
I have two inputs from two temperature sensors. The dateAxis is cutted at some value and the values are not properly set.
Any ideas please on what's wrong ?
Here is the graph from first temperature sensor
chart from sensor 1
2.The graph from second temperature sensor
chart from sensor 2
3.The resulting image of both sensors:
chart from both sensors
4.Here is the code:
`
chart.data = chartData;
if (chart.data[0]) {
seriesArray = Object.keys(chart.data[0]);
// TODO: only for occurDate
seriesArray.splice(0, 1);
}
// Create axes
var dateAxis = chart.xAxes.push(new am4charts.DateAxis());
dateAxis.renderer.grid.template.location = 0;
dateAxis.renderer.minGridDistance = 50;
dateAxis.baseInterval = {
"timeUnit": "day",
"count": 1
};
dateAxis.skipEmptyPeriods = true;
// Create value axis
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
for(let i=0;i<seriesArray.length;i++){
// Create series
var series = chart.series.push(new am4charts.LineSeries());
series.dataFields.valueY = seriesArray[i];
series.dataFields.dateX = "date";
series.strokeWidth = 2;
series.tensionX = 0.90;
series.name = seriesArray[i];
var bullet = series.bullets.push(new am4charts.Bullet());
bullet.tooltipText = seriesArray[i] + ": {valueY}" + unit;
bullet.adapter.add("fill", function(fill, target){
if(target.dataItem.valueY < 21){
return am4core.color("#D66D6D");
}
return fill;
})
var range = valueAxis.createSeriesRange(series);
range.value = goodRange.min;
range.endValue = 0;
range.contents.stroke = am4core.color("#D66D6D");
range.contents.fill = range.contents.stroke;
range.axisFill.fill = am4core.color("#cccccc");
range.axisFill.fillOpacity = 0.2;
range.grid.strokeOpacity = 0;
var range2 = valueAxis.createSeriesRange(series);
range2.value = 1000000;
range2.endValue = goodRange.max;
range2.contents.stroke = am4core.color("#D66D6D");
range2.contents.fill = range.contents.stroke;
range2.axisFill.fill = am4core.color("#cccccc");
range2.axisFill.fillOpacity = 0.2;
range2.grid.strokeOpacity = 0;
}
// Add scrollbar
var scrollbarX = new am4charts.XYChartScrollbar();
scrollbarX.series.push(series);
chart.scrollbarX = scrollbarX;
chart.cursor = new am4charts.XYCursor();
chart.legend = new am4charts.Legend();
chart.legend.position = "bottom";
chart.legend.scrollable = true;
}`

How columns should be manged in OpenXML

I have ceated a excel file with OpenXMl library with the follwing code.
The columns do not get theit widths as they are defined in the code.
Has anybody an idea?
WorkbookPart workbookPart = document.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet();
var workbookStylesPart = workbookPart.AddNewPart<WorkbookStylesPart>();
workbookStylesPart.Stylesheet = new Stylesheet();
workbookStylesPart.Stylesheet.Save();
// Make the columns in the worksheet
var columns = worksheetPart.Worksheet.GetFirstChild<Columns>();
bool needToInsertColumns = false;
if (columns == null)
{
columns = new Columns();
needToInsertColumns = true;
}
Column column1 = new Column() { CustomWidth = true, Width = 5};
columns.Append(column1);
// Insert the columns into the Worksheet
if (needToInsertColumns)
worksheetPart.Worksheet.InsertAt(columns, 0);
SheetData sheetData = worksheetPart.Worksheet.AppendChild(new SheetData());
Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());
Sheet sheet = new Sheet() { Id = workbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "Employees" };
sheets.Append(sheet);
workbookPart.Workbook.Save();
worksheetPart.Worksheet.Save();
document.Save();
I have tried the following and have success:
var columns = new Columns();
var column1 = new Column { Min = 1, Max = 1, Width = 5, CustomWidth = true };
var column2 = new Column { Min = 2, Max = 2, Width = 10, CustomWidth = true };
var column3 = new Column { Min = 3, Max = 3, Width = 5, CustomWidth = true };
var column4 = new Column { Min = 4, Max = 4, Width = 20, CustomWidth = true };
var column5 = new Column { Min = 5, Max = 5, Width = 50, CustomWidth = true };
columns.Append(column1);
columns.Append(column2);
columns.Append(column3);
columns.Append(column4);
columns.Append(column5);
worksheetPart.Worksheet.Append(columns);

Get two offset points between two points

Hi I need help finding coordinate or points offset from two endpoints of a line. In my program, I would like to specify the two points and the offset. Then I need to calculate the two offset coordinates.
I worked something out using trigonometry but it only works in some cases and when the line is in the positive quadrant.
Here is an image describing what I need to find:
Points on line
Ok so I need to find X3,Y3 and X4,Y4 coordinates.
My method I followed:
Calculate angle:
Ang = atan((Y2 - Y1)/(X2 - X1))
To find X3:
X3 = X1 + Offset * Cos(Ang)
The same concept for Y3
The issue is that if the line is in a different quadrant the point info is not correct... Any help, please.
This question is a clear case for using 2d vector math. The idea is that we subtract p1 from p2 to give us a vector that describes the length and direction of the line. We then normalize this vector, such that it has a length of 1. If you then multiply this normalized vector with the number of units you'd like to move away from the end and add the result to the end-point, you'll have a new point.
Consider an example walking along the x axis:
p1 = 0,0
p2 = 10,0
dif = p2 - p1 = (10,0)
length is 10, so it's 10 times too long - we divide it by 10 to get a vector 1 unit long.
If we then move 5 times (1,0), we end up at 5,0 - 5 units away, bewdy!
Here's a function that achieves the same thing:
function calcOffsetPoint(x1,y1, x2,y2, distTowardsP2fromP1)
{
var p1 = new vec2d(x1,y1);
var p2 = new vec2d(x2,y2);
var delta = p2.sub(p1);
var dirVec = delta.clone();
dirVec.normalize();
dirVec.timesEquals(distTowardsP2fromP1);
var resultPoint = p1.add(dirVec);
return resultPoint;
}
As you can see, this makes use of something I've called vec2d. There's a copy of it in the following snippet:
"use strict";
function byId(id){return document.getElemetById(id)}
function newEl(tag){return document.createElement(tag)}
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded(evt)
{
var end1 = new vec2d(0,0);
var end2 = new vec2d(10,0);
var midPoint = calcOffsetPoint(end1.x,end1.y, end2.x,end2.y, 5);
console.log( midPoint.toStringN(2) );
}
class vec2d
{
constructor(x=0, y=0)
{
this.mX = x;
this.mY = y;
}
get x(){return this.mX;}
set x(newX){this.mX = newX;}
get y(){return this.mY;}
set y(newY){this.mY = newY;}
add(other)
{
return new vec2d(this.x+other.x, this.y+other.y);
}
sub(other)
{
return new vec2d(this.x-other.x, this.y-other.y);
}
timesEquals(scalar)
{
this.x *= scalar;
this.y *= scalar;
return this;
}
divByEquals(scalar)
{
this.x /= scalar;
this.y /= scalar;
return this;
}
dotProd(other)
{
return this.x*other.x + this.y*other.y;
}
length()
{
return Math.hypot(this.x, this.y);
}
normalize()
{
this.divByEquals( this.length() );
return this;
}
perpendicular()
{
var tmp = this.x;
this.x = -this.y;
this.y = tmp;
return this;
}
clone()
{
return vec2d.clone(this);
}
static clone(other)
{
return new vec2d(other.x, other.y);
}
toString(){return `vec2d {x: ${this.x}, y: ${this.y}}`}
toStringN(n){return `vec2d {x: ${this.x.toFixed(n)}, y: ${this.y.toFixed(n)}}`}
}
function calcOffsetPoint(x1,y1, x2,y2, distTowardsP2fromP1)
{
var p1 = new vec2d(x1,y1);
var p2 = new vec2d(x2,y2);
var delta = p2.sub(p1);
var dirVec = delta.clone();
dirVec.normalize();
dirVec.timesEquals(distTowardsP2fromP1);
var resultPoint = p1.add(dirVec);
return resultPoint;
}
I had some spare time over the weekend, so put together a working demo of the image you posted. Have a play around. Make sure you run it in full-screen, so you can see the sliders that set the offsets for p3 and p4. Disregard the coordinate-system transformation stuff, that's just there to allow me to make an image the same dimensions as your image yet conveniently display it in a window with about 5% the area. The questions come from the exercise section of some old text-book I was reading over the weekend.
"use strict";
class vec2d
{
constructor(x=0,y=0)
{
this.x = x;
this.y = y;
}
abs()
{
this.x = Math.abs(this.x);
this.y = Math.abs(this.y);
return this;
}
add(vec1)
{
return new vec2d(this.x+vec1.x, this.y+vec1.y);
}
sub(vec1)
{
return new vec2d(this.x-vec1.x, this.y-vec1.y);
}
mul(scalar)
{
return new vec2d(this.x*scalar, this.y*scalar);
}
plusEquals(vec1)
{
this.x += vec1.x;
this.y += vec1.y;
return this;
}
minusEquals(vec1)
{
this.x -= vec1.x;
this.y -= vec1.y;
return this;
}
timesEquals(scalar)
{
this.x *= scalar;
this.y *= scalar;
return this;
}
divByEquals(scalar)
{
this.x /= scalar;
this.y /= scalar;
return this;
}
normalize()
{
var len = this.length;
this.x /= len;
this.y /= len;
return this;
}
get length()
{
//return Math.sqrt( (this.x*this.x)+(this.y*this.y) );
return Math.hypot( this.x, this.y );
}
set length(newLen)
{
var invLen = newLen / this.length;
this.timesEquals(invLen);
}
dotProd(vec1)
{
return this.x*vec1.x + this.y*vec1.y;
}
perp()
{
var tmp = this.x;
this.x = -this.y;
this.y = tmp;
return this;
}
wedge(other)
{ // computes an area for parallelograms
return this.x*other.y - this.y*other.x;
}
static clone(other)
{
var result = new vec2d(other.x, other.y);
return result;
}
clone() // clone self
{
return vec2d.clone(this);
}
setTo(other)
{
this.x = other.x;
this.y = other.y;
}
get(){ return {x:this.x, y:this.y}; }
toString(){ return `vec2d {x: ${this.x}, y: ${this.y}}` }
toStringN(n){ return `vec2d {x: ${this.x.toFixed(n)}, y: ${this.y.toFixed(n)}}` }
print(){console.log(this.toString())}
};
class mat3
{
static clone(other)
{
var result = new mat3();
other.elems.forEach(
function(el, index, collection)
{
result.elems[index] = el;
}
);
return result;
}
clone()
{
return mat3.clone(this);
}
constructor(a,b,c,d,e,f)
{
if (arguments.length < 6)
this.setIdentity();
else
this.elems = [a,b,0,c,d,0,e,f,1];
}
setIdentity()
{
this.elems = [1,0,0, 0,1,0, 0,0,1];
}
multiply(other, shouldPrepend)
{
var a, b, c = new mat3();
if (shouldPrepend === true)
{
a = other;
b = this;
}
else
{
a = this;
b = other;
}
c.elems[0] = a.elems[0]*b.elems[0] + a.elems[1]*b.elems[3] + a.elems[2]*b.elems[6];
c.elems[1] = a.elems[0]*b.elems[1] + a.elems[1]*b.elems[4] + a.elems[2]*b.elems[7];
c.elems[2] = a.elems[0]*b.elems[2] + a.elems[1]*b.elems[5] + a.elems[2]*b.elems[8];
// row 1
c.elems[3] = a.elems[3]*b.elems[0] + a.elems[4]*b.elems[3] + a.elems[5]*b.elems[6];
c.elems[4] = a.elems[3]*b.elems[1] + a.elems[4]*b.elems[4] + a.elems[5]*b.elems[7];
c.elems[5] = a.elems[3]*b.elems[2] + a.elems[4]*b.elems[5] + a.elems[5]*b.elems[8];
// row 2
c.elems[6] = a.elems[6]*b.elems[0] + a.elems[7]*b.elems[3] + a.elems[8]*b.elems[6];
c.elems[7] = a.elems[6]*b.elems[1] + a.elems[7]*b.elems[4] + a.elems[8]*b.elems[7];
c.elems[8] = a.elems[6]*b.elems[2] + a.elems[7]*b.elems[5] + a.elems[8]*b.elems[8];
for (var i=0; i<9; i++)
this.elems[i] = c.elems[i];
}
transformVec2s(pointList)
{
var i, n = pointList.length;
for (i=0; i<n; i++)
{
var x = pointList[i].x*this.elems[0] + pointList[i].y*this.elems[3] + this.elems[6];
var y = pointList[i].x*this.elems[1] + pointList[i].y*this.elems[4] + this.elems[7];
pointList[i].x = x;
pointList[i].y = y;
}
}
makeTransformedPoints(pointList)
{
var result = [];
for (var i=0,n=pointList.length;i<n;i++)
{
var x = pointList[i].x*this.elems[0] + pointList[i].y*this.elems[3] + this.elems[6];
var y = pointList[i].x*this.elems[1] + pointList[i].y*this.elems[4] + this.elems[7];
result.push( new vec2d(x,y) );
}
return result;
}
rotate(degrees, shouldPrepend)
{
var tmp = new mat3();
tmp.elems[0] = Math.cos( degrees/180.0 * Math.PI );
tmp.elems[1] = -Math.sin( degrees/180.0 * Math.PI );
tmp.elems[3] = -tmp.elems[1];
tmp.elems[4] = tmp.elems[0];
this.multiply(tmp, shouldPrepend);
}
scaleEach(scaleX, scaleY, shouldPrepend)
{
var tmp = new mat3();
tmp.elems[0] = scaleX;
tmp.elems[4] = scaleY;
this.multiply(tmp, shouldPrepend);
}
scaleBoth(scaleAmount, shouldPrepend)
{
var tmp = new mat3();
tmp.elems[0] = scaleAmount;
tmp.elems[4] = scaleAmount;
this.multiply(tmp, shouldPrepend);
}
translate(transX, transY, shouldPrepend)
{
var tmp = new mat3();
tmp.elems[6] = transX;
tmp.elems[7] = transY;
this.multiply(tmp, shouldPrepend);
}
determinant()
{
var result, a, b;
a = ( (this.elems[0]*this.elems[4]*this.elems[8])
+ (this.elems[1]*this.elems[5]*this.elems[6])
+ (this.elems[2]*this.elems[3]*this.elems[7]) );
b = ( (this.elems[2]*this.elems[4]+this.elems[6])
+ (this.elems[1]*this.elems[3]+this.elems[8])
+ (this.elems[0]*this.elems[5]+this.elems[7]) );
result = a - b;
return result;
}
isInvertible()
{
return (this.determinant() != 0);
}
invert()
{
var det = this.determinant();
if (det == 0)
return;
var a,b,c,d,e,f,g,h,i;
a = this.elems[0]; b = this.elems[1]; c = this.elems[2];
d = this.elems[3]; e = this.elems[4]; f = this.elems[5];
g = this.elems[6]; h = this.elems[7]; i = this.elems[8];
this.elems[0] = (e*i - f*h); this.elems[1] = -((b*i) - (c*h)); this.elems[2] = (b*f)-(c*e);
this.elems[3] = -(d*i - f*g); this.elems[4] = (a*i) - (c*g); this.elems[5] = -( (a*f) - (c*d) );
this.elems[6] = (d*h - e*g); this.elems[7] = -((a*h) - (b*g)); this.elems[8] = (a*e)-(b*d);
var detInv = 1.0 / det;
for (var i=0; i<9; i++)
this.elems[i] *= detInv;
return this;
}
reset()
{
this.setIdentity();
}
print()
{
var str = '';
for (var i=0; i<9; i++)
{
if (i && i%3==0)
str += "\n";
str += " " + this.elems[i].toFixed(5);
}
console.log(str);
}
}
function byId(id){return document.getElementById(id)}
function newEl(tag){return document.createElement(tag)}
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded(evt)
{
byId('output').addEventListener('mousemove', onMouseMove, false);
byId('slider1').addEventListener('input', onSliderInput, false);
byId('slider2').addEventListener('input', onSliderInput, false);
draw();
}
//(400-48)/400 = 0.88
var invMat, svgInvMat;
function onMouseMove(evt)
{
var mousePos = new vec2d(evt.offsetX,evt.offsetY);
var worldPos = mousePos.clone();
invMat.transformVec2s( [worldPos] );
byId('screenMouse').textContent = `screen: ${mousePos.x},${mousePos.y}`;
byId('worldMouse').textContent = `world: ${worldPos.x.toFixed(1)}, ${worldPos.y.toFixed(1)}`;
}
function onSliderInput(evt)
{
draw();
}
function updateSliderLabels()
{
byId('ofset1Output').textContent = byId('slider1').value;
byId('ofset2Output').textContent = byId('slider2').value;
}
function draw()
{
var can = byId('output');
var ctx = can.getContext('2d');
ctx.clearRect(0,0,can.width,can.height);
var orientMat = evaluateViewOrientationMatrix(0.06*can.width,can.height-24, 0,-1);
var scaleMat = computeWindowToViewPortMatrix(2052,1317, can.width,can.height);
var viewMat = scaleMat.clone();
viewMat.multiply(orientMat);
console.log('viewMat');
viewMat.print();
invMat = viewMat.clone().invert();
for (var i=0; i<9; i++)
invMat.elems[i] /= invMat.elems[8];
ctx.strokeStyle = '#fff';
var axisPts = [ new vec2d(0,1070), new vec2d(0,0), new vec2d(0.88*2052,0) ]; // xAxis line 88% of image width
var axis = viewMat.makeTransformedPoints(axisPts);
drawLine(axis[0].x,axis[0].y, axis[1].x,axis[1].y, ctx);
drawLine(axis[1].x,axis[1].y, axis[2].x,axis[2].y, ctx);
var lineEnds = [new vec2d(330,263), new vec2d(1455,809)];
var pts2 = viewMat.makeTransformedPoints(lineEnds);
drawCircle(pts2[0].x,pts2[0].y, 4, ctx);
drawCircle(pts2[1].x,pts2[1].y, 4, ctx);
drawLine(pts2[0].x,pts2[0].y, pts2[1].x,pts2[1].y, ctx);
var rawP3 = calcOffsetCoords(lineEnds[0].x,lineEnds[0].y, lineEnds[1].x,lineEnds[1].y, byId('slider1').value);
var rawP4 = calcOffsetCoords(lineEnds[1].x,lineEnds[1].y, lineEnds[0].x,lineEnds[0].y, byId('slider2').value);
var ofsPts = viewMat.makeTransformedPoints( [rawP3, rawP4] );
drawCircle(ofsPts[0].x,ofsPts[0].y, 4, ctx);
drawCircle(ofsPts[1].x,ofsPts[1].y, 4, ctx);
updateSliderLabels();
}
function calcOffsetCoords(x1,y1, x2,y2, offset)
{
var dx = x2 - x1;
var dy = y2 - y1;
var lineLen = Math.hypot(dx, dy);
var normDx=0, normDy=0;
if (lineLen != 0)
{
normDx = dx / lineLen;
normDy = dy / lineLen;
}
var resultX = x1 + (offset * normDx);
var resultY = y1 + (offset * normDy);
return {x:resultX,y:resultY};//new vec2d(resultX,resultY); //{x:resultX,y:resultY};
}
// Exercise 6-1:
// Write a procedure to implement the evaluateViewOrientationMatrix function that calculates the elements of the
// matrix for transforming world coordinates to viewing coordinates, given the viewing coordinate origin Porigin and
// the viewUp vector
function evalViewOrientMatrix(screenOriginX,screenOriginY, worldUpVectorX,worldUpVectorY)
{
var worldUp = {x: worldUpVectorX, y: worldUpVectorY};
var len = Math.hypot(worldUp.x, worldUp.y);
if (len != 0)
len = 1.0 / len;
worldUp.x *= len;
worldUp.y *= len;
var worldRight = {x: worldUp.y, y: -worldUp.x};
var rotMat = svg.createSVGMatrix();
rotMat.a = worldRight.x;
rotMat.b = worldRight.y;
rotMat.c = worldUp.x;
rotMat.d = worldUp.y;
var transMat = svg.createSVGMatrix();
transMat = transMat.translate(screenOriginX, screenOriginY);
var result = rotMat.multiply(transMat);
return result;
}
function evaluateViewOrientationMatrix(screenOriginX,screenOriginY, worldUpVectorX,worldUpVectorY)
{
var worldUp = new vec2d(worldUpVectorX, worldUpVectorY);
worldUp.normalize();
var worldRight = worldUp.clone().perp();
var rotMat = new mat3();
rotMat.elems[0] = worldRight.x; rotMat.elems[1] = worldRight.y;
rotMat.elems[3] = worldUp.x; rotMat.elems[4] = worldUp.y;
var transMat = new mat3();
transMat.translate(screenOriginX,screenOriginY);
var result = rotMat.clone();
result.multiply(transMat);
return result;
}
/*
0 1 2
3 4 5
6 7 8
translation
-----------
1 0 0
0 1 0
tX tY 1
scaling
---------
sX 0 0
0 sY 0
0 0 1
rotation
--------
cosX -sinX 0
sinX cosX 0
0 0 1
*/
// Exercise 6-2:
// Derive the window to viewport transformation equations 6-3 by first scaling the window to
// the size of the viewport and then translating the scaled window to the viewport position
function computeWindowToViewPortMatrix(windowWidth,windowHeight,viewPortWidth,viewPortHeight)
{
var result = new mat3();
result.scaleEach(viewPortWidth/windowWidth,viewPortHeight/windowHeight);
return result;
}
// returns an SVGMatrix
function compWnd2ViewMat(windowWidth,windowHeight,viewPortWidth,viewPortHeight)
{
var result = svg.createSVGMatrix();
return result.scaleNonUniform(viewPortWidth/windowWidth,viewPortHeight/windowHeight);
}
function drawLine(x1,y1,x2,y2,ctx)
{
ctx.beginPath();
ctx.moveTo(x1,y1);
ctx.lineTo(x2,y2);
ctx.stroke();
}
function drawCircle(x,y,radius,ctx)
{
ctx.beginPath();
ctx.arc(x, y, radius, 0, (Math.PI/180)*360, false);
ctx.stroke();
ctx.closePath();
}
canvas
{
background-color: black;
}
.container
{
display: inline-block;
background-color: #888;
border: solid 4px #555;
}
#screenMouse, #worldMouse, .control
{
display: inline-block;
width: calc(513px/2 - 2*8px);
margin-left: 8px;
}
<body>
<div class='container'>
<canvas id='output' width='513' height='329'></canvas><br>
<div id='screenMouse'></div><div id='worldMouse'></div>
<div>
<div class='control'>P2 ofs: <input id='slider1' type='range' min='0' max='500' value='301'><span id='ofset1Output'></span></div>
<div class='control'>P3 ofs: <input id='slider2' type='range' min='0' max='500' value='285'><span id='ofset2Output'></span></div>
</div>
</div>
</body>

mouseJoint box2dweb doesn't work

I am trying to catch object with mouse using mousejoint. As I am a fool I've stolen the code. But it isnt working or me.
I am getting this errors:
Uncaught TypeError: Object #< ba > has no method 'IsActive' Box2dWeb-2.1.a.3.min.js:236
Uncaught TypeError: Object #< ba > has no method 'SetAwake' Box2dWeb-2.1.a.3.min.js:223
here is the code:
var def = new b2MouseJointDef();
def.bodyA = ground;
def.bodyB = body;
def.target = p;
def.collideConnected = true;
def.maxForce = 1000 * body.GetMass();
def.dampingRatio = 0;
mouse_joint = world.CreateJoint(def);
body.SetAwake(true);
And this is the body
function createBox(world, x, y, width, height, options) {
options = $.extend(true, {
'density' : 1.0 ,
'friction' : 1.0 ,
'restitution' : 0.5 ,
'linearDamping' : 0.0 ,
'angularDamping' : 0.0 ,
'type' : b2Body.b2_dynamicBody
}, options);
var body_def = new b2BodyDef();
var fix_def = new b2FixtureDef();
fix_def.density = options.density;
fix_def.friction = options.friction;
fix_def.restitution = options.restitution;
fix_def.shape = new b2PolygonShape();
fix_def.shape.SetAsBox( width , height );
body_def.position.Set(x , y);
body_def.linearDamping = options.linearDamping;
body_def.angularDamping = options.angularDamping;
body_def.type = options.type;
body_def.userData = options.user_data;
var b = world.CreateBody( body_def );
var f = b.CreateFixture(fix_def);
return b;
}
Maybe someone can help?
Falk
I can answer half of the question:
if I set up the ground with
ground = createBox(world, 4, 1, 4 , 0.5, {type : b2Body.b2_staticBody});
instead with this function:
var bodyDef = new b2BodyDef();
var fixDef = new b2FixtureDef();
fixDef.density = 1.0;
fixDef.friction = 1.0;
fixDef.restitution = 0.5;
fixDef.shape = new b2PolygonShape;
//mention half the sizes
fixDef.shape.SetAsBox(4.00 , .5);
//set the position of the center
bodyDef.position.Set(4.10 , 1);
return world.CreateBody(bodyDef).CreateFixture(fixDef);
then it is working. But why?

Fix the cell width in Word using Open XML SDK

I have a table with one row in a docx file and I want to add some rows. For the first existing row I set the GridSpan to 3. In the next one I want add a row only with two cell, then I have the result as on the picture. How can I fix the new row width to the table width? The same I want to do, when I add only a one cell in the new row.
My code:
private static TableRow AddRow(WordprocessingDocument docx, Table tbl, int cellsQuantity)
{
TableRow newRow = new TableRow();
var firstCell = tbl.Descendants<TableRow>().First()
.Descendants<TableCell>().First();
firstCell.Append(new TableCellProperties(new GridSpan() { Val = 3 }));
for (int i = 0, max = cellsQuantity; i < max; i++)
{
// TableCellProperties tcp = new TableCellProperties(new TableCellWidth() { Width = firstCell.TableCellProperties.TableCellWidth.Width, Type = firstCell.TableCellProperties.TableCellWidth.Type });
TableCell cell = new TableCell(new Paragraph(new Run(new Text("test"))));
newRow.AppendChild(cell);
}
tbl.Append(newRow);
return newRow;
}
Ok, I thing I got it :)
private static TableRow AddRow(WordprocessingDocument docx, Table tbl, int cellsQuantity)
{
TableRow newRow = new TableRow();
var grid = tbl.Descendants<TableGrid>().First();
var firstCell = tbl.Descendants<TableRow>().First()
.Descendants<TableCell>().First();
firstCell.Append(new TableCellProperties(new GridSpan() { Val = 4 }));
int ind = 0;
int[] widthPerColumn = new int[] { 3070, 1536, 1535, 3071 };
grid.Descendants<GridColumn>().ToList().ForEach(x =>
{
x.Width = widthPerColumn[ind++].ToString();
});
int[] gridSpan = null;
switch (cellsQuantity)
{
case 4:
gridSpan = new int[] { 1, 1, 1, 1 };
break;
case 3:
gridSpan = new int[] { 1, 2, 1 };
break;
case 2:
gridSpan = new int[] { 2, 2 };
break;
case 1:
gridSpan = new int[] { 4 };
break;
default:
throw new InvalidOperationException("The cellsQuantity variable must have a value from [1,4] range");
}
for (int i = 0, max = cellsQuantity; i < max; i++)
{
TableCellProperties tcp = new TableCellProperties(new GridSpan() { Val = gridSpan[i] });
TableCell cell = new TableCell(tcp, new Paragraph(new Run(new Text("test"))));
newRow.AppendChild(cell);
}
tbl.Append(newRow);
return newRow;
}
TableCell tCell = new TableCell();
tCell.Append(new TableCellProperties(
new GridSpan { Val = table.LastChild.ChildElements.Count },
new Justification { Val = JustificationValues.Right })
);