We have an AmChart Stock Chart implementation with multiple panels. We want to add graphs with the compared property set to true on demand to the first panel of a Stock Chart containing multiple panels.
How do we do this?
What we tried so far:
We push data sets into an AmChart instance called tmpchart. When we add a chart to the panel below the first one it and then attempt to add a graph at index 1, the graph is not drawn. In case we do not have a graph in panel 2, the series are added to panel 1.
tmpchart.dataSets.push({
//title: String(tmpchart.dataSets.length+1) + "th data set",
fieldMappings: [{
fromField: "value" + intSegmentAdded,
toField: "value" + intSegmentAdded
}],
dataProvider: newChartData,
categoryField: "year",
compared: true
});
console.log("---printing dataset -----")
//console.log(tmpchart.dataSets);
console.log(tmpchart.panels[0]);
var oldPanel = tmpchart.panels[0];
var graph = new AmCharts.StockGraph();
graph.id = "g" + intSegmentAdded;
graph.valueField = "value" + intSegmentAdded;
graph.compareField = "value" + intSegmentAdded;
graph.comparable = true;
graph.compareGraph = {type : "smoothedLine", fillAlphas : 0.15, lineThickness :2 };
oldPanel.addStockGraph( graph );
As you can see in the output, the blue and yellow series are added first to the top panel and the green is added to panel below it. When we attempt to add another series to top panel - the red one - it does not appear, even though it is in the dataSets array.
Your code appears to be fine by itself. The only thing your sample is missing is a validateData call.
Codepen
It might be helpful for you to provide an SSCCE that reproduces your scenario more accurately so we can better understand your issue.
Related
I am wondering if it is possible to get access to aggregated data from a deck.gl layer to be able to draw a legend.
Because the colour scheme is supplied I would only require the extent of the aggregated values calculated by the screengrid layer to be able to add this to the legend.
I know there are tooltips, but in some circumstances it would be nice to have access to these values.
I'm using the HexagonLayer and for that one you can find the values for the layers by using a semi custom onSetColorDomain function when initializing your layer. Then save the domain range array to a variable and call a make legend function.
for example:
const hexlayer = new HexagonLayer({
id: 'heatmap',
pickable: true,
colorRange: COLOR_RANGE,
data: feats_obj.coords_array,
elevationScale: 9,
extruded: true,
radius: 300,
getColorValue: points => {
if( points.length > max_points) {
max_points = points.length
}
renderCategories( incident_categories )
return points.length
},
onSetColorDomain: (ecol) => {
console.log('color domain set', ecol)
max_span.innerHTML = ecol[1]
color_domain = ecol;
create_legend()
// console.log('max_points: ', max_points)
},...
})
The hacky way i figured out was to make a max points in a polygon global variable outside initializing the layer and have it update the value anytime there's a polygon with more points in it than that max value. An example of it in the wild is: https://mpmckenna8.github.io/sfviz/?start_date=2020-05-01&end_date=2020-05-31 with a link to the repo u can hack on there.
I am working with amchart to build a strip chart using AMstock (rotated).
Is there a way to display only category axes values on a panel? see sample screenshot here.
I have 2 charts. Left should show only category axes values. the right shows the strip chart.
Right now I am stuck at creating the chart options to show only category axes values (double values).
Any help will be appreciated.
I was able to solve this by removing the stock graphs entry for my panels.
...
'panels': [
{
'showCategoryAxis': true,
'title': 'Value',
'percentHeight': 100,
'lineThickness': 2,
'autoMargins': true,
'autoMarginOffset': 0,
// as you can see, the stockGraphs is commented out.
// 'stockGraphs': [{
// }],
}
],
...
hopefully this helps somebody.
I am trying to get a layout that would, for each object in the data array:
append a rect or a g element that will serve as container
inside or on top of this, append a circle for each of the coordinates.
Below is a mock-up of how the data is massaged before I'm trying to append to the DOM (at the top of the update() function in the block below):
[{
label: 'foo',
circles: [
{ x: 0, y: 10 },
{ x: 10, y: 10 }
]
},{
...
}]
The drawing and updating of the rect elements seems to be working fine, but I am getting the selection and joins confused for the circles.
Here's the block: http://blockbuilder.org/basilesimon/91f75ab5209a62981f11d30a81f618b5
With
var dots = rects.selectAll('.dots')
I can select the right data below but can't draw it.
Could you help me getting the selections right so I can draw and update both the rect and the circle, please?
Thank you Gerard for your help. This is my current state, but I've pitted myself into a hole by running a for loop instead of d3 selections.
I wonder if I couldn't nest the circles in g elements after building a new data object like so:
var data = dataset.map(function(d) {
var circles = d3.range(d.amount).map(function(i) {
return {
x: (i % 5)*20,
y: (i / 5 >> 0)*20
}
});
return {
label: d.label,
dots: circles
};
});
From each object in data, we'll append a g, and inside each g we'll append the circles. Any help appreciated, since this will affect the dots + i used by the update pattern...
New question here
Here is the problem:
var dots = svg.selectAll('dots')
You're selecting something that doesn't exist. Because of that, your "enter" selection will always contain all the data, and your "exit" selection will always be empty.
The solution is changing it for something like this:
var dots = svg.selectAll(".dots" + i)
And, in the enter selection, setting the classes:
.attr("class", "dots" + i)
Here is your updated bl.ocks (with some other minor changes): https://bl.ocks.org/anonymous/4c2e1d66f1ab890da983465a4f84ca9b
I've spent a lot of time finding the solution, but i can't see any property in AmChatrts documentation that can align balloons not vertically. Actually, I just want to see all balloons, but not in one column. Can anybody help me?
There is currently no way to make the balloons stack in any different way than in once column. However, there are a few alternatives you can consider.
1) Displaying just one balloon.
To do that, set oneBalloonOnly to true:
var chart = AmCharts.makeChart("chartdiv",{
...
"chartCursor": {
"oneBalloonOnly": true
}
});
This will make the cursor display just one balloon of the closest graph.
2) Disable balloons and use a legend instead.
To disable balloons, simply set [valueBalloonsEnabled][3] in chart cursor's settings to false.
var chart = AmCharts.makeChart("chartdiv",{
...
"chartCursor": {
"valueBalloonsEnabled": false
},
"legend": {}
});
The legend will show relative value next to each graph title when you hover over the chart.
3) Consolidate values from multiple graphs into a single balloon.
To do that, use graph's balloonText property. It lets you reference to any field in data, so you can make it display values from any graph.
Here's a good example of the above.
Here's a good demo on how to do that.
I'm working on a visualization tool for time series with multiple dimensions.
To simplify my case, each data-point has a dimension on type, clusterId and a set of months:
{
type: "green",
clusterId:42,
months:[1392185580000, 1394604780000, 1397279580000]
}, {
type: "red",
clusterId:43,
months:[1392185580000]
}
Now I would like to show the dates in a dc.barChart, which shows the months of all datasets as keys(bars), and the number of observations of each month as value of the bar.
In the given case, it would result in 3 bars, the first one with a height of 2, and the other with a height of 1.
How can I create this dimension and implement the grouping/reducing function?
You don't have to worry about filtering by this dimension, I already have a custom filter for this dimension. The only thing is displaying the bars on the barChart.
If i get this correctly, you need some code, that outputs: 1392185580000: 2, 1394604780000: 1, 1397279580000:1?
arr.forEach(function(d) {
d.months.forEach(function(month) {
if (!store.hasOwnProperty(month)) {
store[month]=0;
}
store[month]++;
});
});
demo fiddle