Create dynamic vertical rule in d3 - javascript

I want to create a vertical rule like the one shown at http://bost.ocks.org/mike/cubism/intro/demo-stocks.html that updates its value dynamically according to the user's mouse.
This demo uses cubism.js but I'd like to use d3 and/or jQuery to achieve the same effect.
Any suggestions?
EDIT: I've tried creating rules according to the ones in this thread (How to make a vertical line in HTML), but I don't know how to position it and move it according to the user's mouse position.

You need to update your question to include more detail about what you actually want, but here's one implementation using d3: http://jsfiddle.net/q3P4v/
d3.select('html').on('mousemove', function() {
var xpos = d3.event.pageX;
var rule = d3.select('body').selectAll('div.rule')
.data([0]);
rule.enter().append('div')
.attr('class', 'rule')
.append('span');
rule.style('left', xpos + 'px');
rule.select('span').text(xpos);
});
Note that this depends on some associated CSS, as shown in the fiddle.

Related

GitGraph - scaling the size of the graph

I am using the GitGraph javascript library - http://gitgraphjs.com/
I am currently using the examples file to see how things work in GitGraph. The link to the example file - https://github.com/nicoespeon/gitgraph.js/blob/develop/examples/index.js
Is there any possible way to scale the graph? I tried overriding CSS styles, the quality of graph diminished greatly.
I was expecting something like a GitGraph.scale option? Is that available?
The main project page doesn't make it easy to link, but it looks like the section titled "Define Your Own Template" is what you're looking for?
EDIT:
OK, with a better understanding of what you're looking for, I played around with it myself, and noticed that the canvas element's width and height properties are added to the DOM programmatically in GitGraph.prototype.render(), based on some moderately complicated math involving a bunch of values from the template object, plus a scalingFactor value derived using window.devicePixelRatio.
There doesn't seem to be a way to modify these values before the canvas is rendered, but using the provided graph:render event, you could do it after.
gitGraph.canvas.addEventListener("graph:render", function(event) {
console.log(event.data.id, "has been rendered with a scaling factor of", gitGraph.scalingFactor);
rescale();
}
function rescale() {
var g = document.getElementById('gitGraph');
var w = +g.style.width.slice(0,-2) * 0.5; // < just change these two
var h = +g.style.height.slice(0,-2) * 0.5; // multipliers to the same
g.style.width = w + 'px'; // value
g.style.height = h + 'px';
};
Here's that function working with the official example code (notice that it does screw up the absolutely-positioned detail div):
http://codepen.io/phoward8020/pen/ZOpERB
Does that help?
(EDIT 2: Inline Stack Overflow example code added no value to answer since it's not editable. Replaced with CodePen so readers can verify functionality by changing multiplier values.)

Adding c3.js padding without cutting off graph

This is in response to the following question, How to remove padding in c3.js?, where the answer that was provided solves this issue, but also raises another issue -- the buttons on the graph are cut off at the end --
How would I get there to be no padding and the buttons not to be cut off, for example, it should look like:
The dots are getting clipped off because of the clip-path set on the chart layer. You just have to remove it. You can use D3 for this, like so
d3.select(chart.element).select("." + c3.chart.internal.fn.CLASS.chart).attr("clip-path", null);
where chart is your C3 chart object
Fiddle - http://jsfiddle.net/zds67nh1/
However you most probably want the dots to appear above the axis layer. For that you need to detach and attach the chart layer (in SVG, the z-index is determined by the order - the last of the siblings come on top. So you have to basically move it to the end of the siblings list), like so
var chartLayer = d3.select(chart.element).select("." + c3.chart.internal.fn.CLASS.chart);
var chartLayerParentNode = chartLayer.node().parentNode;
var chartLayerNode = chartLayer.remove();
chartLayerParentNode.appendChild(chartLayerNode.node());
chartLayer.attr("clip-path", null);
Fidle - http://jsfiddle.net/7e1eL22f/

Changing an html attribute based on its current value in D3

I feel like I'm trying to do something fairly straightforward, but I can't seem to figure out how. I have a page displaying several bar graphs, and I'm trying to build a button that makes certain bars appear and disappear. The bars have labels, and when the button is toggled, I want half the bars to dissappear, the remaining bars to double in size and the labels for the bars to move down a little bit.
I'm using D3.js to draw my graphs, and I've got almost everything working, except these little labels. All I'm trying to do is increment their "y" attribute by about 15 pixels, but I can't seem to find a way to request this value before changing it!
Initially I thought
d3.selectAll(".bar-value-label").attr("y", function(d,i){ return d + 15;})
should work. However, when I logged what this "d" was, it turned out to be a reference to the data object initially used to create this element.
So, basically I'm just trying to find a way to get the current value and in- or decrement it. Is there a nice way to do this within D3?
Regards,
Linus
EDIT:
Okay, so I've found a way that works. I'm very doubtfull that this is the best/most efficient way, so answers are still very much welcome :)
var resp_labels = d3.selectAll(".bar-value-label-resp")[0];
resp_labels.forEach(function(d,i){
var old_y = parseFloat(d.getAttribute("y"));
d3.select(d).transition().attr("y", function(i){ return old_y - barheight/4 ;});
});
I haven't had a chance to check that it works, but I think that this is a slightly simplified version of your solution:
var resp_label = d3.select(".bar-value-label-resp");
var old_y = +resp_label.attr("y");
resp_label.transition().attr("y", old_y - barheight/4);

The d3 force layout central node positioning

I have use the d3.js to visualize my data. And the result like this.
PIC_1
PIC_2
My question is how can I make the data present like PIC_1,the center point local in the fixed position,and the other points (children points) around the center point like a circle.
Now,when I refresh the page the data will reload in the brower and all the points' position will randomly change as well.
So which d3's api or tricks can be used to this purpose. :)
Take a look at this example:
link to jsfiddle
If you exampne the code, and play with layout, you'll see that the root node has special treatment that makes it always remain in the center of the graph (unless you drag it, but even that you can prevent if you want).
On initialization, its property fixed is set to true, so that d3 force layout simulation doesn't move it. Also, it is placed in the center of rectangle containing layout:
root.fixed = true;
root.x = width / 2;
root.y = height / 2;
You ofcourse need to change or add some code in order to integrate this feature to your example, but the core idea is really clear from the example I linked.
Hope this helps. Let me know if you have a question, need a clarification, etc.

Tracking mouse position of a jqplot vertical line chart

I want to create a jqPlot line chart which has the ability to change orientation between vertical and horizontal orientation. I was able to achieve this using CSS rules, by rotating the div element containing the chart.
My work up to now: http://jsfiddle.net/GayashanNA/A4V4y/14/
But the problem is I also want to track the mouse-pointer and mouse clicks on points on chart after the orientation is flipped because i want to annotate those points. I am unable to do this when the chart is in vertical orientation. Can anyone suggest a method to do this? Or am i approaching the problem in a wrong way?
(Note: I am able to do this in horizontal orientation, you can observe it if you try to click on a point on the above chart.)
Thanks and help is much appreciated.
I've never used jqPlot, but I guess your problem is trying to use css rotate(), since the cursor plugin is using the mouse position to determine where to draw the lines, and element's size doesn't change when transformed by rotate(), it still have the same width and height values.
If you take a look at the code, you will see:
if (c.showVerticalLine) {
c.shapeRenderer.draw(ctx, [[gridpos.x, 0], [gridpos.x, ctx.canvas.height]]);
}
if (c.showHorizontalLine) {
c.shapeRenderer.draw(ctx, [[0, gridpos.y], [ctx.canvas.width, gridpos.y]]);
}
So it seems like the library is always drawing the lines based on mouse position over the original element, which of course, won't match the position after being transformed by rotate(), and XY coordinates are going to be transformed to YX after rotate().
I would try to change the size of your original element, though I don't know if the library lets you specify in which sides are the labels going to be drawn.
I finally found a solution for the problem. But i had to change jqPlot library to achieve this. To help anyone else who run in to the same problem, i'll put my solution here.
First i had to insert the following code in to the jqPlot class of the jquery.jqplot.js file, which is the core library.
function jqPlot() {
//add the following code segment
var verticallyOriented = false;
this.setVertical = function(state){
verticallyOriented = state;
}
//don't change other code that isn't mentioned here
//now you have to change the logic in the getEventPosition function
//to make sure the new orientation is detected
function getEventPosition(ev) {
//change the line starting with var gridPos = ...
//to the following code segment
//depending on the orientation the event position calculating algorithm is changed
if(verticallyOriented){
var gridPos = {x:ev.pageY - go.top , y:plot.eventCanvas._elem.height() - ev.pageX + go.left};
} else {
var gridPos = {x:ev.pageX - go.left, y:ev.pageY - go.top};
}
//no change to other code is needed
}
}
You can view a working example here: http://jsfiddle.net/GayashanNA/yZwxu/
Gist for the changed library file: https://gist.github.com/3755694
Please correct me if i have done something wrong.
Thanks.

Categories

Resources