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/
Related
I am using chart.js to try to create a timeline of events relative to current date.
The horizontal bar chart is close but would like to show only the tips of the bars eg as points which would pretty much be a horizontal line chart.
I have shown my horizontal bar chart along with a mock-up of what it would look like as horizontal line chart.
Is this possible with chart.js ?
You first need to know that every information that you can edit about the chart is stored in the variable containing your chart (called myChart usually, but my2Bar in your fiddle).
If you want to globally change the graph, you will need to edit attributes in myChart.config.options.
If you want to change a specific chart, you will need to edit attributes in myChart.config.data.
In this case, you need to change a specific chart (which is the horizontal bar).
If you happen to check the logs of your graph, and go very deep in the config, you will finally see that bars in your chart are drawn using attributes stored in myChart.config.data.datasets[0]._meta[0].data[n]._model (n being the nth rectangle drawn, top to bottom).
Some attributes you can find there :
base : The X position where the rectangle is starting to be drawn (0 in your xAxe for instance).
x : The rectangle is being drawn until this X position.
height : The height of the drawn rectangle.
and so on ...
To edit these values, you just need to loop in your different rectangles (the n in the above path).
But you just can't do it manually on the config of your variable. If you do this, it won't work since your chart is responsive (on resize, it will redraw the chart using the former options).
What you must use are Chart.js plugins.
Plugins let you handle all the events that are triggered while creating, updating, rendering your graph.
Then, in your beforeRender event (triggered after the initialisation, but before the drawing), you need to loop in your different rectangles to edit the values to affect how they will be drawn :
beforeRender: function(chart) {
for (var i = 0; i < chart.config.data.datasets[0]._meta[0].data.length; i++) {
// Change both `3` values to change the height & width of the point
chart.config.data.datasets[0]._meta[0].data[i]._model["base"] = chart.config.data.datasets[0]._meta[0].data[i]._model["x"] + 3;
chart.config.data.datasets[0]._meta[0].data[i]._model["height"] = 3;
}
}
Here is a jsFiddle with the final result.
Unfortunately, I wasn't able to make round dots, instead of squared ones.
Update :
I have also made another jsFiddle where all the dots are linked together which makes it look like it is a horizontal line chart (can be improved of course, but it is a good start).
Im using this great article to produce a venn diagram with D3.
http://www.benfrederickson.com/venn-diagrams-with-d3.js/
It looks great but on occasion I get bubbles overlapping the the labels become hidden. Is there a way to make sure the text element is always on top? (see the picture below.. label A needs to be on top of circle B.
I found this good article but im struggling in how to implement this in the venn.
How can I bring a circle to the front with d3?
You should grab the latest code from master: this commit should fix the issue you had there https://github.com/benfred/venn.js/commit/4cb3bbef65b5b3c3ce02aee7d913e8814e898baf
Instead of having the 'A' label be overtop of the 'B' circle - it willnow move the label so that its in the certain of the 'A' region that isn't overlapped with 'B'. Some details are in this issue here: https://github.com/benfred/venn.js/issues/18
You might find it easier to work in actual layers. You can use g elements to create them. For example:
var lowerLayer = svg.append('g');
var upperLayer = svg.append('g');
Now anything you append to upperLayer will appear above anything you append to lowerLayer because the two g elements have been added to the DOM and are in a specific order.
Also check out this answer I wrote up for a similar question.
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.
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.
Is there a way to make a vertical line in the js graph library dygraph?
I am loading data and would like to put vertical lines like graphite does to show events
is there some special context to add vertical lines
You've probably figured this out by now, or stopped caring, but the way to do this is with a custom underlay (see http://dygraphs.com/tests/highlighted-region.html and http://dygraphs.com/tests/underlay-callback.html for examples). You provide an underlayCallback function when creating the graph, and it gets called with the canvas element, area (which helps with coordinate math), and a reference to the Dygraph object.
Here is a simple solution.
Use the crosshair demo (http://dygraphs.com/tests/crosshair.html) on the Dygraph site.
Once you disable the horizontal bar on the crosshair sample, you are getting a vertical bar.
g4.updateOptions({ pointClickCallback: function(event, p) {
var div_vertical_style="top:0px;left:"+g4.toDomCoords(p.xval,-20)[0]+"px;width:1px;height:"+g4.plotter_.area.h+";background-color:black;position:absolute;";
$("#graphdiv4").append("<div style="+div_vertical_style+"></div>")
}});
//my idea , add div .....