Using D3, I am creating a dial with a nice lighting effect using SVG with a filter. When displayed at the top of the webpage, everything looks great. When displayed lower down in the page, it usually (9 times out of 10) gets corrupted somehow during page load. I guess this is something to do with the dial being rendered and then moved, with the filter not catching up somehow, but I'm not sure. I hope someone can tell me why. I don't think I can reproduce this in a Fiddle but if I can I'll add a link. Here are the essential parts.
Just the circle without the filter.
The circle with filter applied and looking good.
The circle with filter applied and corrupted. It looks like maybe the filter position is slightly down and right relative to the simple circle.
Filter code:
var defs = svg.append("defs");
defs.append("path").attr({ id: "curve", d: "M20,20 A43,40 0 0,0 66,20" });
var f1 = defs.append("filter").attr({ id: "f1", x: "-10%", y: "-10%", width: "120%", height: "120%" });
f1.append("feGaussianBlur").attr({ "in": "SourceAlpha", stdDeviation: "4", result: "blur" });
f1.append("feOffset").attr({ "in": "blur", dx: 4, dy: 4, result: "offsetBlur" });
f1.append("feSpecularLighting").attr({ "in": "blur", surfaceScale: "5", specularConstant: ".75", specularExponent: "20", "lighting-color": "#eeeeee", result: "specOut" })
.append("fePointLight").attr({ x: "-5000", y: "-10000", z: "20000" });
f1.append("feComposite").attr({ "in": "specOut", in2: "SourceAlpha", operator: "in", result: "specOut" });
f1.append("feComposite").attr({ "in": "SourceGraphic", in2: "specOut", operator: "arithmetic", k1: "0", k2: "1", k3: "1", k4: "0", result: "litPaint" });
var merge = f1.append("feMerge");
merge.append("feMergeNode").attr({ "in": "offsetBlur" });
merge.append("feMergeNode").attr({ "in": "litPaint" });
Filter application:
svg.append("circle").attr({ cx: mid, cy: mid, r: radius, "class": "edge", filter: "url(#f1)" });
Related
I'm working with plotly in JS, trying to draw a sunburst chart. Everything works, but i would like to make it so that the child sections on the chart each have a different color. I cant seem to figure it out, any help is extremely appreciated.
Here is how my sunburst looks:
Notice that "Enos" and "Noam" have the same color, I would like them to have either different colors, or at least different opacities.
Like so:
Here is my code:
var data = [{
"type": "sunburst",
"labels": ["Eve", "Awan", "Seth", "Enos", "Noam", "Enoch"],
"parents": ["", "Eve", "Eve", "Seth", "Seth", "Awan"],
"values": [100, 20, 80, 60, 20, 20]
}];
var layout = {
sunburstcolorway: ["#636efa", "#ef553b"]
};
Plotly.newPlot('myChart', data, layout)
If you want to have custom colors for your traces, then you need to set the colors array of the marker object. There you can set the color for every single part of the sunburst diagram:
var data = [{
"type": "sunburst",
"labels": ["Eve", "Awan", "Seth", "Enos", "Noam","Enoch"],
"parents": ["", "Eve", "Eve", "Seth", "Seth", "Awan"],
"values": [100, 20, 80, 60, 20, 20],
"opacity" : 1,
"marker": {
colors: ["#ffffff","#fc6e08","#3e81ed","#3293e3","#c429ad","#d99543"]
}
}];
var layout = {
// sunburstcolorway: ["#636efa", "#ef553b"]
};
Plotly.newPlot('myChart', data, layout)
So the first value ("Eve") has the first color of the array, the second value ("Awan")the second color, and so on. In the example, I set the opacity to 1 to get the real colors from the colors array.
I have a small issue with the parameter direction of the function getConnectedNodes() based on the Vis.js documentation (search for "getConnectedNodes" in the link)
Any idea to get the direction of the edges using the parameter (i don't know how to)?
JSON Example
[
{ "x": 0, "y": 0, "id": "0", "connections": [ 2 ] // i think here should be a from?},
{ "x": 200, "y": 0, "id": "1", "connections": [ 3, 2 ] },
{ "x": 500, "y": 500, "id": "2", "connections": [ 0, 1 ] },
{ "x": 300, "y": -200, "id": "3", "connections": [ 1 ] }
]
Here part of the code
google.script.run.withSuccessHandler(([nodes, edges]) => new vis.Network(container, {nodes: nodes, edges: edges}, options)).sample();
let network;
function init() {
container = document.getElementById('mynetwork');
exportArea = document.getElementById('input_output');
network = google.script.run.withSuccessHandler(([nodes, edges]) => {network = new vis.Network(container, {nodes: nodes, edges: edges}, options);}).sample();
};
function addConnections(elem, index) {
elem.connections = network.getConnectedNodes(index); < I THINK THE PROBLEM IS HERE
}
function exportNetwork() {
var nodes = objectToArray(network.getPositions());
nodes.forEach(addConnections);
var exportValue = JSON.stringify(nodes, undefined, 2);
exportArea.innerHTML = exportValue;
}
function objectToArray(obj) {
return Object.keys(obj).map(function(key) {
obj[key].id = key;
return obj[key];
});
}
Before hand, thanks a lot!
index is the index of the array like 0, 1, 2,,,. The start index is 0. On the other hand, elem is the object like {x: ###, y: ###, id: ###}. From these situation, I thought that index of getConnectedNodes(index) might be elem.id. So how about the following modification?
From:
elem.connections = network.getConnectedNodes(index);
To:
elem.connections = network.getConnectedNodes(elem.id, "from");
From the document, if you want to retrieve "parent", you can retrieve it by adding from to the argument.
For a node id, returns an array with the id's of the connected nodes.
If optional parameter direction is set to string 'from', only parent nodes are returned.
If direction is set to 'to', only child nodes are returned.
Any other value or undefined returns both parent and child nodes.
When you want to retrieve "child", please add to to the argument instead of from.
I'm creating a pedigree tree diagram for breeding rats and I'm having trouble calculating the horizontal distance I need for each tree node since the number of descendants vary or is dynamic.
I found a script that I'm using to draw the tree but it looks like it doesn't have any documentation with it.
I need help in this part
var node = new Node({
title: 'M: ' + pair.male + '<br />F: ' + pair.female,
stage: stage,
w: NODE_DIMENSIONS.w,
h: NODE_DIMENSIONS.h,
x: COORDINATES.x + (INCREMENTS.x * pair.column), // Formula should adjust based on descendants - HELP
y: COORDINATES.y + (INCREMENTS.y * pair.generation)
}).attach();
Here's a Fiddle if you would like to mess around with it and the complete code is provided below.
HTML
<div id="stage"></div>
CSS
.node h4 {
position: static;
left: auto;
bottom: auto;
width: 80px;
height: 80px;
text-align: center;
vertical-align: middle;
display: table-cell;
text-shadow: none;
color: #ffffff;
font-weight: bold;
}
Script
var stage = $('#stage');
var NODE_DIMENSIONS = { w: 80, h: 80 };
var SEGMENT_DIMENSIONS = { h: 5 };
var COORDINATES = { x: 50, y: 50 };
var INCREMENTS = { x: 200, y: 150 };
// Sample JSON array resulting from an AJAX call.
var mating = [{
"name": "one",
"male": 1234,
"female": 5643,
"male_lineage": null,
"female_parent": null,
"generation": 0,
"column": 0
}, {
"name": "two",
"male": 6737,
"female": 1627,
"male_lineage": ["four"],
"female_parent": null,
"generation": 0,
"column": 2
}, {
"name": "three",
"male": 9332,
"female": 6227,
"male_lineage": ["five", "six"],
"female_parent": null,
"generation": 0,
"column": 3
}, {
"name": "four",
"male": 1111,
"female": 6537,
"male_lineage": null,
"female_parent": "one",
"generation": 1,
"column": 1
}, {
"name": "five",
"male": 8853,
"female": 3189,
"male_lineage": null,
"female_parent": "two",
"generation": 1,
"column": 2
}, {
"name": "six",
"male": 8853,
"female": 3189,
"male_lineage": null,
"female_parent": "three",
"generation": 1,
"column": 3
}];
var m = new Map();
for (var i = 0; i < mating.length; i++) {
var pair = mating[i];
var node = new Node({
title: 'M: ' + pair.male + '<br />F: ' + pair.female,
stage: stage,
w: NODE_DIMENSIONS.w,
h: NODE_DIMENSIONS.h,
x: COORDINATES.x + (INCREMENTS.x * pair.column), // Formula should adjust based on descendants - HELP
y: COORDINATES.y + (INCREMENTS.y * pair.generation)
}).attach();
var element = {
"pair": pair,
"node": node
};
m.set(pair.name, element);
}
m.forEach(function(element, key, m) {
// We are going to create 2 segments
// First is for the male lineage
if (element.pair.male_lineage != null) {
for(var i = 0; i < element.pair.male_lineage.length; i++) {
new Segment({
h: SEGMENT_DIMENSIONS.h,
stage: stage,
origin: element.node,
destination: m.get(element.pair.male_lineage[i]).node
}).attach();
}
}
// Last is the female parent
if (element.pair.female_parent != null) {
new Segment({
h: SEGMENT_DIMENSIONS.h,
stage: stage,
origin: element.node,
destination: m.get(element.pair.female_parent).node
}).attach();
}
});
Without even attempting (pardon me ...) to dive into the whys-and-wherefores of “your” particular problem, I can categorically say that “tree-drawing is an inherently recursive problem.”
Furthermore, it is not a problem that maps directly to the HTML “DOM.” (You will have to “deal with the DOM” after, not before, you decide “what the tree needs to look like.”)
Generally speaking, tree-painting problems need to work, recursively, from the bottom up: the lowest non-leaf nodes distribute their leaves equally, then position themselves equidistant between the leftmost and the rightmost of their children, then report their width as being equal to the extent of their children’s width. (This recursive description of the problem then resolves itself, more-or-less satisfactorily, to encompass the entire tree.)
Once you have thus determined how the entire tree would like to appear, your next (but, altogether unrelated ...) problem is: how to manipulate the DOM-tree, which is “the thing that more-or-less drives the browser,” to actually produce the visual outcome that you want.
(“Uhh... except on Internet Explorer 8.”)
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I'm growing desperate with amCharts doing the simplest task. Well, at least what I think is simple. I want to create a normal line chart with "normal" data. What do I mean with normal? Well, having an array with my y values, and maybe also one for x:
x = [1,2,3,4]
y = [5,6,7,8]
Shouldn't it be pretty easy to put something like this in a chart? And still I'm sitting here having no idea how to do this properly(!) in amcharts. I'm using Flask (Python) and can use jsonify to get my arrays into JSON files and send it to the client, but I'm not able to go any further.
Any ideas? I mean, shouldn't this be the most basic task? But all examples using amCharts doing special stuff with date formats for x..
Thank you very much!
First things first, if you are looking at plotting a line graph out of arbitrary X and Y coordinates (as opposed plotting series-based data), you're better off using XY chart than serial one.
Also, amCharts will not be able to plot data in separate arrays of coordinates.
You can either convert the data to a proper format at the moment of generation of data, so it looks like this:
chartData = [ {
x: 1,
y: 5
}, {
x: 2,
y: 6
}, {
x: 3,
y: 7
}, {
x: 4,
y: 8
}];
Or add some code that converts your data to amCharts-compatible data before supplying it to the chart:
/**
* Source data
*/
var x = [1,2,3,4];
var y = [5,6,7,8];
/**
* Convert source data to AmCharts-compatible format
*/
var chartData = [];
for( var i = 0; i < x.length; i++ ) {
chartData.push( {
"x": x[ i ],
"y": y[ i ]
} )
}
/**
* Create the chart
*/
var chart = AmCharts.makeChart( "chartdiv", {
"type": "xy",
"pathToImages": "http://www.amcharts.com/lib/3/images/",
"dataProvider": chartData,
"graphs": [ {
"bullet": "circle",
"bulletSize": 8,
"lineAlpha": 1,
"lineThickness": 2,
"fillAlphas": 0,
"xField": "x",
"yField": "y",
} ]
} );
Here's a working demo of the above:
http://codepen.io/amcharts/pen/15b2c710357a7e29eda11dc5caa07d44
following is the simpliest definition possible. The dateProvider is an array of objects where each element represents the x-axis item with it's y values.
AmCharts.makeChart("your element id",{
"type": "serial",
"pathToImages": "http://cdn.amcharts.com/lib/3/images/",
"categoryField": "category",
"graphs": [
{
"valueField": "column-1"
}
],
"dataProvider": [
{
"category": "1",
"column-1": "8"
},
{
"category": "2",
"column-1": 6
},
{
"category": "3",
"column-1": 2
},
{
"category": "4",
"column-1": 1
}
]
});
Live sample:
http://live.amcharts.com/2JmYT/edit/
I am new to Jquery. I am calling a Struts 2 action which return a Json object.
I dont understand how actually .each function works in Jquery.
Can you please explain how can I use the variable data, in a complex json using jquery.
{
"od": {
"cwd": [
{
"batchCount": 140,
"batchId": "2121",
"countryName": "Mexico",
"processId": "210002",
"status": "F",
"timeRequired": 140
},
{
"batchCount": 140,
"batchId": "8259",
"countryName": "Japan",
"processId": "220002",
"status": "F",
"timeRequired": 140
}
],
"percentageCompleted": 100,
"remainingTime": "-104Hours -4Mins",
"successBatchCount": 0,
"totalBatchCount": 920
},
"processDateInput": "19/11/2014" }
So here is what I wanted to know that
if json data is parsed into var obj,
Can cwd be accessed by :
var cwd = result.od.cwd;
$.each(cwd, fuction(index, value)){
var batchcount = value.batchcount;
});
and likewise can we parse any json string in jquery.
Thanks and regards,
Tushar
For basic understanding , explain you with your example,
First parent object has two object , "od" and "processDateInput" you can get the values of object directly like od.percentageCompleted , od.remainingTime, processDateInput etc..
So if there is an array inside an object then you need to go for $.each or for loop ,example
$.each(od.cwd,function(index,element){
/*index will be 0 and element will have first cwd[0] value {
"batchCount": 140,
"batchId": "2121",
"countryName": "Mexico",
"processId": "210002",
"status": "F",
"timeRequired": 140
}*/
//similar to this you can get the value
var batchCount=element.batchCount;
});