I am new to node-graphviz, which is a Node.js interface to the GraphViz graphing tool.
I want to draw a directed graph and save it into memory using the code:
var graphviz = require('graphviz');
var debug = true;
function draw (hbGraph) {
/** Create the digraph */
var vGraph = graphviz.digraph('Happens-Before-Graph'),
eventNodes = {};
/** Create nodes for digraph */
for (var i = 0; i < hbGraph.eventNodes.length; i++) {
/** Note, eventNodes is a sparse array */
var event = hbGraph.eventNodes[i];
if (event != undefined) {
var node = vGraph.addNode(event.id, {
'color': common.COLOR.GREY,
'style': common.STYLE,
});
eventNodes[node.id] = node;
}
}
/** Create edges for digraph, just ignore for this question */
if (debug) {
// Create digraph G
var g = graphviz.digraph("G");
// Add node (ID: Hello)
var n1 = g.addNode( "Hello", {"color" : "blue"} );
n1.set( "style", "filled" );
// Add node (ID: World)
g.addNode( "World" );
// Add edge between the two nodes
var e = g.addEdge( n1, "World" );
e.set( "color", "red" );
// Print the dot script
console.log( g.to_dot() );
// Set GraphViz path (if not in your path)
g.setGraphVizPath( "/usr/local/bin" );
// Generate a PNG output
g.output( "png", "test01.png" );
}
console.log( vGraph.to_dot() );
vGraph.setGraphVizPath( "/usr/local/bin" );
vGraph.output('png', 'test02.png');
}
After running the code, file test01.png is generated while file test02.png is not without any exception. Both two results of to_dot() methods are successfully printed on the console.
The printout of to_dot() method for test02.png is:
digraph Happens-Before-Graph {
"1" [ color = "grey" ];
"7" [ color = "grey" ];
"8" [ color = "grey" ];
"9" [ color = "grey" ];
"10" [ color = "grey" ];
"11" [ color = "grey" ];
"12" [ color = "grey" ];
"13" [ color = "grey" ];
"14" [ color = "grey" ];
}
I want to why file test02.png is not generated and how it can be generated. Could anyone help me?
In addition, the documenation about this library cannot be generated, so I am unfamiliar with it.
Additional information: link to node-graphviz is node-graphviz
The answer is just to remove the minus sign - in the digraph.
Since the documentation of node-graphviz cannot be built, I just post the right answer here.
Related
how can I center label in graphviz ?
digraph "toto" {
graph ["rankdir"="TB"]
node ["shape"="box"]
"BROUILLON" ["label"="Brouillon","margin"="0.4,0.0"]
"A_VALIDER_RH" ["label"="À valider par la RH","margin"="0.4,0.0","color"="red"]
"A_VALIDER_RH" -> "BROUILLON" ["label"="Refuser"]
"BROUILLON" -> "A_VALIDER_RH" ["label"="Soumettre"]
}
I have:
expected:
You will need to use extra nodes for the labels:
digraph "toto"
{
// graph[ "rankdir" = "TB" ]
// nodes
node[ shape = box ];
BROUILLON[ label= "Brouillon", margin = "0.4,0.0" ];
A_VALIDER_RH[ label = "À valider par la RH", margin = "0.4,0.0", color = red ];
node[ shape = plaintext ];
n1[ label = "Soumettre" ];
n2[ label = "Refuser" ];
// edges
BROUILLON -> n1 -> A_VALIDER_RH;
BROUILLON -> n2 -> A_VALIDER_RH[ dir = back ];
}
yields
I want to set different text color of label in each row SegmentControl programmatically.
Please check my ref. code.
var arrColors = [
{"color":"white"},
{"color":"orange"},
{"color":"blue"},
{"color":"yellow"},
{"color":"gray"}
];
this.view.segCont.widgetDataMap = {lblColorName: "color"};
this.view.segCont.setData(arrColors);
I want to do something like attached image.
Thanks in advance!!
I got solution from kony team.
1) Create different skin for different color label. See below image:
2) Set condition for as per your require color label.
var arrColors = [
{"color": "white"},
{"color": "orange"},
{"color": "blue"},
{"color": "yellow"},
{"color": "gray"}
];
for (i = 0; i < arrColors.length; i++) {
if (arrColors[i].color === "orange") {
arrColors[i].color = {
"skin": "sknLblOrange"
};
} else {
arrColors[i].color = {
"skin": "sknLblGreen"
};
}
}
this.view.segCont.widgetDataMap = {
lblColor: "color"
};
this.view.segCont.setData(arrColors);
Hope this helpful to you. Happy Coding :)
This is fine if your data is finite and static, or if the data array is always the same length, like with a menu.
However, if your data is dynamic you should consider instead this solution:
var arrColors = [
{"skin": "whiteRowSkin"},
{"skin": "orangeRowSkin"},
{"skin": "blueRowSkin"},
{"skin": "yellowRowSkin"},
{"skin": "grayRowSkin"}
];
this.view.segCont.widgetDataMap = {
lblColor: "color"
// plus any other properties you need for this data.
};
// Lets assume this getData function fetches your dynamic data from a service.
var segData = getData();
for (var i = 0; i < segData.length; i++) {
var colorIndex = i % arrColors.length;
segData[i].color = arrColors[colorIndex];
};
this.view.segCont.setData(segData);
The key above is the Modulus/Remainder % operator, which allows you to decide dynamically which of the colors/skins in the skin array to corresponds to each data row, even if the size of the data array varies.
Note: This obviates the fact that the data may be a matrix if you're using segment sections.
I'm trying to find an example of setasign/fpdi code.
I have a pdf document with multiple pages. I want to create a new pdf that imports each page AND adds a background (this background is another pdf doc - portrait or landscape depending on root pdf page) + some extra text to it.
I'm unable to find a correct example for this issue, hope someone can help me with this one.
I found the answer, I will post it here. Maybe there is a better way... :-)
$portrait_backgroundpdf = "pdf/background_portrait.pdf";
$landscape_backgroundpdf = "pdf/background_landscape.pdf";
$originalpdf = "pdf/original.pdf";
// First get number of pages + orientations of original pdf
$temp_pdf = new Fpdi();
$count = $temp_pdf->setSourceFile($originalpdf);
$sizes = [];
for ($pageNo = 1; $pageNo <= $count; $pageNo++) {
$templateId = $temp_pdf->importPage($pageNo);
$size = $temp_pdf->getTemplateSize($templateId);
$sizes[$pageNo] = $size['orientation'];
}
// sizes is now an array like this example:
// [
// 1 => "P", <-- portrait
// 2 => "P", <-- portrait
// 3 => "L", <-- landscape
// 4 => "L", <-- landscape
// ]
// Now start the new PDF
$pdf = new Fpdi();
foreach($sizes as $page => $size) {
$pdf->AliasNbPages();
$pdf->AddPage();
if ($size == "P") {
$pdf->setSourceFile($portrait_backgroundpdf);
} else {
$pdf->setSourceFile($landscape_backgroundpdf);
}
$tplId = $pdf->importPage(1);
$pdf->useImportedPage($tplId, 0, 0, null);
$pdf->setSourceFile($pdfurl.$pastepdf);
$template = $pdf->importPage($page);
$pdf->useTemplate($template, 10, 30, 180);
// Do other pdf stuff here per page
}
$pdf->Output();
I'm trying to move label test to right few pixels because the way it's displayed now it looks like it is more to the left:
Label text is aligned to center for 2d bar charts but when you have 3d bars you have this slight offset effect to left that needs to be corrected.Label position values are: "bottom", "top", "right", "left", "inside", "middle".
I wasn't able to fine tune it.
Any ideas on this?
As mentioned in my comment, the labels are centered with respect to the angle setting for 3D charts. The API doesn't allow you to shift the label left or right, so you have to manipulate the graph SVG nodes directly through the drawn event. If you set addClassNames to true, you can retrieve the label elements using document.querySelectorAll through the generated DOM class names and then modifying the translate value in the transform attribute accordingly. You can use a technique from this SO answer to easily manipulate the transform attribute as an object:
// ...
"addClassNames": true,
"listeners": [{
"event": "drawn",
"method": function(e) {
Array.prototype.forEach.call(
document.querySelectorAll(".amcharts-graph-g4 .amcharts-graph-label"),
function(graphLabel) {
var transform = parseTransform(graphLabel.getAttribute('transform'));
transform.translate[0] = parseFloat(transform.translate[0]) + 5; //adjust X offset
graphLabel.setAttribute('transform', serializeTransform(transform));
});
}
}]
// ...
// from http://stackoverflow.com/questions/17824145/parse-svg-transform-attribute-with-javascript
function parseTransform(a) {
var b = {};
for (var i in a = a.match(/(\w+\((\-?\d+\.?\d*e?\-?\d*,?)+\))+/g)) {
var c = a[i].match(/[\w\.\-]+/g);
b[c.shift()] = c;
}
return b;
}
//serialize transform object back to an attribute string
function serializeTransform(transformObj) {
var transformStrings = [];
for (var attr in transformObj) {
transformStrings.push(attr + '(' + transformObj[attr].join(',') + ')');
}
return transformStrings.join(',');
}
Updated fiddle
I have a linear scale and I am using it for one of my axis in a chart.
I want to define a custom format only showing positive numbers and following this example I created a customFormat in this way:
function yFormat(formats) {
return function(value) {
var i = formats.length - 1, f = formats[i];
while (!f[1](value)) f = formats[--i];
return f[0](value);
};
}
var customFormat = yFormat([
[d3.format("?????"), function() { return true }],
[d3.format("d"), function(d) { return d >= 0 }]
]);
but I don't know how to define an empty format for Numbers (link to doc)
Does anybody have an idea? Thanks
EDIT
d3.format("") seems to work for time scales but not for linear scale. In a console:
> var emptyTime = d3.time.format("");
undefined
> emptyTime("something");
""
> var emptyInt = d3.format("");
undefined
> emptyInt(5);
"5"
ANSWER
I am just using tickValues on the axis itself. So, something like:
yAxis.tickValues(
d3.range(
0,
d3.max(y.domain()),
shift
)
);