PROLOGUE
This is my first time posting to stackoverflow and i'm a noob with dc.js. Apologies in advance for etiquette transgressions (feedback welcome on this too)
PROBLEM
I have defined a barchart and it displays perfectly, but brushOn(true) is not letting me filter the data. In the past, this seemed to work perfectly with a crosshair appearing as soon as i hovered over the bargraph. Now it is not. Any idea why?! or what i can do to fix it? I'm on day 3 of trying to figure out what is happening. The help is MUCH appreciated!
PREREQS:
https://d3js.org/d3.v5.min.js
crossfilter.min.js
https://unpkg.com/dc#3.0.4/dc.js
CODE FOR BARCHART
I have defined a barchart as follows:
filterDim = cross.dimension(function(d){return d3.timeWeek(d.date);});
var filterGroup = filterDim.group().reduceSum(function(d){
if(d.isTrue){return 1;}
else {return 0;} });
height=400;
if(width == 0){
width = $(dom_id).parent().innerWidth();
}
var hitsbarChart = dc.barChart(dom_id);
hitsbarChart
.width(width).height(height)
.dimension(sentDimension)
.group(allGroups[0].data,allGroups[0].name)
.xUnits(d3.timeWeeks);
hitsbarChart
.x(d3.scaleTime())
.valueAccessor(function(d){return d.value;})
.keyAccessor(function(d){return d.key;})
.round(d3.timeWeek.round)
.yAxis().ticks(d3.format('.3s'));
function calc_domain(chart) {
var min = d3.min(chart.group().all(), function(kv) { return kv.key; }),
max = d3.max(chart.group().all(), function(kv) { return kv.key; });
max = d3.timeMonth.offset(max, 1);
chart.x().domain([min, max]);
}
hitsbarChart.on('preRender', calc_domain);
hitsbarChart.on('preRedraw', calc_domain);
hitsbarChart.brushOn(true);
dc.renderAll();
RESEARCH
I found this example which demonstrates something different but outputs a graph with time-series as the x-axis and working brush to select a range of dates.
Also, there this bug with work-around but the work around did not work. I can't imagine that time-series data works more like an ordinal scale than a numerical scale.
It's likely that you have some CSS inadvertently affecting your chart when it was supposed to be control some other part of the page.
This could happen either because you used a generic name which is also used by dc.js or d3.js, or because a style sheet from another library does. All of dc.js's style rules are carefully scoped so that they shouldn't affect anyone else, but many common words are used for class names, so interference the other way is common.
The brushing behavior comes from d3, so I'd try looking at d3's g.brush rect.overlay in the inspector of your developer tools. You should be able to bring it up by right-clicking the background of the chart and selecting Inspect.
If it has something like
pointer-events: none;
or
display: none;
applied to it, find out what applied that (hopefully CSS you control) and try to make the rules more specific.
Of course it's also possible for JavaScript from another library to cause such troubles, but interference from CSS is much more common.
Related
I am building a Highcharts visualisation where there is a line series, and an area series that hugs it (as the error of that series).
My problem is that when I add the arearange, the zoom animation no longer works. The zoom animation works just fine without the arearange series and, strangely enough, the zoom animation works fine if there are eight data points in the area range, but not if there are nine or above.
I have created a codepen to demonstrate this: http://codepen.io/samirelanduk/pen/eWgdZN
The two highcharts files I am pulling in are:
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/stock/highcharts-more.js"></script>
Does anybody know why this is? Is it a bug (known or unknown) within Highcharts, or have I done something wrong? Or is there a very good reason for why it does this?
If the number of the points is higher than 99, then the animation for zooming is disabled, unless you force it by setting chart.animation to true. I cannot find whether it is documented, sadly, but it can be seen in the function responsible for zooming.
In chart.prototype.zoom:
// Redraw
if (hasZoomed) {
chart.redraw(
pick(chart.options.chart.animation, event && event.animation, chart.pointCount < 100) // animation
);
}
example: http://codepen.io/anon/pen/bWgBMw
I was hoping to get some help on Highcharts/Highstock. I created a jsFiddle with my chart so far.
https://jsfiddle.net/Wolfs_Brain/qhgxd813/1/
Here is what I am trying to do:
I would like the Tooltip to show up initially without ruining responsiveness.
I have commented out the last two functions to point out the ones that seem to be causing the issue. If you uncomment these two:
function(chart){
// Last point in graph...
showLastPointTooltip(chart);
chart.series[0].data[i].setState('select');
}
function showLastPointTooltip(objHighStockchart){
//show tooltip for last point
var points=[];
if(objHighStockchart)
{
for(var i=0;i<objHighStockchart.series.length;i++)
points.push(objHighStockchart.series[i].points[objHighStockchart.series[i].points.length-1]);
objHighStockchart.tooltip.refresh(points);
}
};
the graph will function how i'd like but it is no longer responsive.
If you need any other information from my part please let me know.
Thanks in advance.
I'm new to d3 and now trying to render a sunburst chart with a really big set of data. But I find out that with the number of paths goes up, the drilling of chart becomes dull, like stops for one sec and then drills.
Is there any way to improve this? I'm thinking to display a limited number of levels but how to make showing levels dynamically change when the center changes?
function click(d) {
var duration = config.animationDuration || config.animationDuration === 0 ? config.animationDuration : 1000;
path.transition()
.duration(duration)
.attrTween("d", arcTween(d))
path.attr("display", function(d){
if(d.depth>config.drillDownPath.length + data.levelLimit-1) return "none";
}); }
In the code above, I tracked the chart drilldown path to decide if a path is shown or not. But this didn't solve the question because the the path still exists in the DOM.
Can anyone help me with this? Thanks!
I know this is a bit late, but I might try this example for displaying a large hierarchical dataset allowing for the user to drill down to any level.
By only rendering and transitioning 2-3 levels of arcs at a time, your transitions will probably lag less and the chart would probably be more readable. However, as mentioned by Lars, it's really hard to give you a concrete demo without seeing more code...
I'm trying to render the legend of a pie chart so that it has a fixed width, and when the labels reach that width (the div holder) to hyphenate on the next line. I tried the row option but it doesn't work very well because my data is dynamic and at times i have say 3 data sets, and each one of them gets rendered in a separate row, while at other times i have 15-20 data sets and it becomes messy.
Anyway the solution is to restrain the legend to the width of the div, that it is rendered into, yet it doesn't seem to be accepting any css alterations. I tried adding width:250px; to the "jqplot-table-legend" in jqPlot css, i also tried adding it into various places using Inspect Element in Chrome to test whether it works, but it doesn't seem to accept the new width. I also tried to hard code it into the javascript file at various places with no luck.
I'm not sure what I can add to the question in terms of code. Everything is pretty standard on the jqPlot side.
Any suggestions on how to get around this will be much appreciated.
This seems like the quick and dirty way, but it gets the job done. I'll use the jqplot.pieRenderer.js file as the example since it's easier to read than the minified version. Open the js file and scroll down to line 568. Right under
this._elem = $(document.createElement('table'));
this._elem.addClass('jqplot-table-legend');
add
this._elem.css({width: 300});
That will stretch the table out to whatever width you need it to be. Unfortunately, it also stretches out the column with the color swatch so you'll now need to scroll down a little further until you find
td1.css({textAlign: 'center', paddingTop: rs});
change that to
td1.css({width: 16, textAlign: 'center', paddingTop: rs});
and you should be all set.
Another method:
Just add these lines:
if (this.width) {
ss['width'] = this.width;
}
They allow you to set an arbitrary width in each different graph
You might also want to add these lines in jquery.jqplot.js (i.e if rendering bars)
Search for "createElement('table')" as described by mike
Worked for me
I'm hoping to use arbor.js as a way of creating annotated illustrations.
The plan:
Fixed size canvas
Draw image to canvas – as an example i've used the silhouette of head.
Then have a mixture of fixed and floating nodes.
var data = {
nodes:{
brain-position:{},
brain-text:{'color':'green','shape':'dot','label':'brain'},
mouth-position:{},
mouth-text{'color':'green','shape':'dot','label':'mouth'},
},
edges:{
brain-position:{ brain-text },
mouth-position:{mouth-text}
}
};
sys.graft(data);
The problems i'm having is that when I try to create a statically positioned nodeBox eg.
nodeBoxes[node.name] = [50,50, w,w] it breaks the link to other linked nodes.
I'm tinkering with halfvis/src/renderer.js file from the downloaded arbor file.
Many thanks
EDIT
Below is an additional image that hopefully visualises the functionality I'm attempting. Probably should have done this first :)
nodeBoxes, in the halfvis example, is an array used to work out where to start drawing edges so the arrows don't overlap with the boxes - is that what you're using it for?
Are you trying to find a way of forcing the 'brain-position' node inside an area?
Please provide a bit more detail of what you're planning and we can probably do this.