Dimple Filter for X Value - d3.js

I've been using a little d3 and am now exploring dimple. I am trying to create some pie charts. However, I want the x-axis value to be a subset of the actual values.
Here's what I have:
var svg = dimple.newSvg("body", 800, 600);
//data
var data = [{"Inst":"Two", "Finaid":"Grant", "Value":50},
{"Inst":"Two","Finaid":"None", "Value":10},
{"Inst":"Two","Finaid":"No", "Value": 30},
{"Inst":"One", "Finaid":"Grant", "Value":20},
{"Inst":"One","Finaid":"None", "Value":10},
{"Inst":"One","Finaid":"No", "Value": 30}];
//basic chart
var chart = new dimple.chart(svg, data);
console.log(data);
chart.setBounds(50,20,460,360)
chart.addCategoryAxis("y", "Inst")
chart.addMeasureAxis("x", "Value");
chart.addMeasureAxis("p", "Value");
chart.addMeasureAxis("z", "Value");
chart.addSeries("Finaid", dimple.plot.pie);
chart.addLegend(600,20,90,300, "left");
chart.draw();
So this works, but I want the x-axis value to only be the value of "Finaid":"Grant" something like chart.addMeasureAxis("x", {"Finaid":"Grant"}.Value);... although I realize that actual code does nothing.
Any suggestions? Thanks

Just filter it before plotting. In fact, dimple.js even offers a helpful function for just that.
var data = [{"Inst":"Two", "Finaid":"Grant", "Value":50},
{"Inst":"Two","Finaid":"None", "Value":10},
{"Inst":"Two","Finaid":"No", "Value": 30},
{"Inst":"One", "Finaid":"Grant", "Value":20},
{"Inst":"One","Finaid":"None", "Value":10},
{"Inst":"One","Finaid":"No", "Value": 30}];
var filteredData = dimple.filterData(data, "Finaid", "Grant");
// now make chart
var chart = new dimple.chart(svg, filteredData);

Related

Chart.js: How to get bar chart labels clickable?

I use chart.js 2.8.0 to create mainly pie and bar charts. The clickable legend on pie charts is really useful, filtering out unwanted data from the result.
When creating a chart there are two kinds of labels:
* An array of labels on chart level, label 1 corresponding to item 1 in each dataset.
* Dataset labels, one for each dataset.
A pie chart as standard get the chart label array turned into a legend with clickable labels, click on a label and that item is filtered out from the chart.
A bar chart, on the other hand, gets the labels shown below the bar but not clickable. Instead the legend here is made out of the dataset label. If you have more than one dataset, a whole dataset is filtered out if you click on that label.
Since I sometimes have several datasets I can not use the "trick" that consists of putting data item into a separate dataset (that was otherwise the closest to what I wanted that I found in my search, the "extra" clickable legend that would create would work as well). The situation is also that the end user should get a drop-down (or similar) so he, from the same data, can select chart type. So the soultion need to work both for pie and bar charts. the same data and (standard) code creates the two shown charts (except for the colors).
The question is now, as stated in the title: Is it possible to get clickable labels for a bar chart with the same filtering functionality as when the chart is of pie type?
I understand that it isn't doable by just setting some options, it would probably have to be done by creating a plugin, but is it at all doable? if so, any pointers for help?
If not clickable labels, maybe make the bars themselves clickable (with the same result)...?
With a slight change to the fiddle given by https://stackoverflow.com/users/3963330/tob%c3%adas in his answer here: Click events on Pie Charts in Chart.js I get a fiddle that also can handle multiple datasets, and on my second try I managed to hide a segment when I clicked on it. And then I relized that if it wasn't a pie chart there would be no clickable legend to use for unhiding that element - so that's not a solution for my bar charts.
Tried combining a couple of SO questions/answers (generating labels by #GRUNT : Bar labels in Legend) but can't get legend labels for bar charts to filter out segments instead of datasets.
Fiddle: https://jsfiddle.net/tommypeters/24ra6egy/9/
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="canvas"></canvas>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
var myNewChart = new Chart(ctx, {
type: 'bar',
data: {
datasets: [{
data: [300, 50, 100],
backgroundColor: [
"#F7464A",
"#46BFBD",
"#FDB45C"
]
},
{
data: [400, 60, 101],
backgroundColor: [
"#F7464A",
"#46BFBD",
"#FDB45C"
]
}
],
labels: [
"Red",
"Green",
"Yellow"
]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
},
legend: {
labels: {
generateLabels: function(chart) {
var labels = chart.data.labels;
var dataset = chart.data.datasets[0];
var legend = labels.map(function(label, index) {
return {
datasetIndex: 0,
fillStyle: dataset.backgroundColor && dataset.backgroundColor[index],
strokeStyle: dataset.borderColor && dataset.borderColor[index],
lineWidth: dataset.borderWidth,
text: label
}
});
return legend;
}
}
}
}
});
canvas.onclick = function(evt) {
var activePoints = myNewChart.getElementsAtEvent(evt);
if (activePoints[0]) {
var chartData = activePoints[0]['_chart'].config.data;
var idx = activePoints[0]['_index'];
var dIndex = myNewChart.getDatasetAtEvent(evt)[0]._datasetIndex;
var label = chartData.labels[idx];
var value = chartData.datasets[dIndex].data[idx];
// Doesn't hide a slice but a whole dataset...
// var meta = myNewChart.getDatasetMeta(dIndex);
// meta.hidden = meta.hidden === null ? !myNewChart.data.datasets[dIndex].hidden : null;
// myNewChart.update();
var i, ilen, meta;
for (i = 0, ilen = (myNewChart.data.datasets || []).length; i < ilen; ++i) {
meta = myNewChart.getDatasetMeta(i);
if (meta.data[idx]) {
meta.data[idx].hidden = !meta.data[idx].hidden;
}
}
myNewChart.update();
var url = "http://example.com/?label=" + label + "&value=" + value;
console.log(url);
alert(url);
}
}

Legends cut off

Some part of legend is missing. How it possible to show full. Some time my label is long. I searched a lot but I am not found any thing
var chart = am4core.create("product_sale_chart", am4charts.PieChart);
// Add data
chart.data = [{
"product": "Brufen 200 mg",
"size": "94000"
}, {
"product": "Panadol Ford-20-Tablet-Pack",
"size": "387000"
}, {
"product": "Betnovit",
"size": "4340"
}]
chart.innerRadius = 100;
var label = chart.seriesContainer.createChild(am4core.Label);
label.text = "2019";
label.horizontalCenter = "middle";
label.verticalCenter = "middle";
label.fontSize = 50;
label.labelRadius = -500;
//label.paddingLeft = '50px !important';
var pieSeries = chart.series.push(new am4charts.PieSeries());
pieSeries.dataFields.value = "size";
pieSeries.dataFields.category = "product";
This is because the labels are stretching outside the bounds of the chart. If this is Amcharts v3 you can reduce the labelRadius to bring them closer to the center.
EDIT
Now that I see your code it's clear you're using Amcharts v4, so instead of labelRadius you need to use the following:
pieSeries.labels.template.radius = am4core.percent(-40);
Here's a working pen
More on labels

dimple d3 plot, average of the values, quick command fix

Want to make a plot with the average values of HR and avg. Looked it up in the documentation, but it seems i cannot get the average command to work :(
Can anybody spot my stupid mistake ?
var svg = dimple.newSvg("#chartContainer", 590, 400);
d3.tsv("bbd3.tsv", function (data) {
var myChart = new dimple.chart(svg, data);
myChart.setBounds(75, 30, 490, 330)
myChart.addMeasureAxis("x", "HR");
myChart.addMeasureAxis("y", "avg");
myChart.aggregate = dimple.aggregateMethod.avg;
myChart.addSeries( ["handedness"], dimple.plot.bubble);
myChart.addLegend(180, 10, 360, 20, "right");
myChart.draw();
Aggregation applies to the series not the chart. So you can rewrite like this:
var mySeries = myChart.addSeries( ["handedness"], dimple.plot.bubble);
mySeries.aggregate = dimple.aggregateMethod.avg;

DimpleJS legend limited to part of the series

I'm using DimpleJS to render a BubblePlot. My data looks like this:
[
{type: "A", name:"First", x:1, y:200},
{type: "A", name:"Second", x:30, y:10},
{type: "B", name:"Third", x:50, y:120},
{type: "B", name:"Fifth", x:90, y:100}
]
The graph is created with:
var myChart = new dimple.chart(svg, chartData);
myChart.setBounds(50, 30, 370, 230);
var x = myChart.addMeasureAxis("x", "x");
var y = myChart.addMeasureAxis("y", "y");
var series = myChart.addSeries(["type", "name"], dimple.plot.bubble);
myChart.addLegend(10, 10, 360, 20, "right");
myChart.draw();
This nearly does what I want, with all the data available in the tooltips etc. But coloring is based on both typeand name.
Also unfortunately the legend also picks up all the values from the name field where I'd prefer to just see the type values within the legend.
I also tried to the use the addColorAxismethod like this:
var c = myChart.addColorAxis("type");
var series = myChart.addSeries("name", dimple.plot.bubble);
But that renders black bubbles, shows "NaN" as type in the tooltips and putting that into a legend also doesn't seem to be possible.
Any suggestions are welcome!
Turns out that the order of arguments in the series is important.
This solved my problem:
var myChart = new dimple.chart(svg, chartData);
myChart.setBounds(50, 30, 370, 230);
var x = myChart.addMeasureAxis("x", "x");
var y = myChart.addMeasureAxis("y", "y");
var series = myChart.addSeries(["name","type"], dimple.plot.bubble);
myChart.addLegend(10, 10, 360, 20, "right");
myChart.draw();

Dimple.js assign colour to bar, when series is null

I'm trying to change the default colour in Dimple.js, I want each bar to be red, I can change the colour by individually citing each entry in the series, but I can't seem to change the colour across the whole chart, once I set the buyerchartSeries to null.
var myChart = new dimple.chart(svg2_3, data);
myChart.setBounds(10, 15, "92%", "84%");
myChart.addMeasureAxis("x", "sum");
var y = myChart.addCategoryAxis("y", "service");
y.addOrderRule("sum");
y.hidden = true;
var buyerchartSeries = myChart.addSeries(null, dimple.plot.bar);
myChart.assignColor(null,"red")
myChart.draw();
Your solution is fine but if you also have some non-null series identifiers which you would like to colour separately it won't work. You can use assignColor but you need to assign to "All":
var myChart = new dimple.chart(svg2_3, data);
myChart.setBounds(10, 15, "92%", "84%");
myChart.addMeasureAxis("x", "sum");
var y = myChart.addCategoryAxis("y", "service");
y.addOrderRule("sum");
y.hidden = true;
var buyerchartSeries = myChart.addSeries(null, dimple.plot.bar);
// This is all I've changed
myChart.assignColor("All", "red");
myChart.draw();
I've found the answer... it might be an egregious hack, or it might be the best way to do this, (advice welcome).
Rather than assign a colour to a 'null' series, which obviously won't work, I've changed the defaultColor of the chart. If you only have one colour it has the correct effect of imposing a single colour on all the bars.
var myChart = new dimple.chart(svg3_1, dt);
myChart.setBounds(4, 20, "88%", "80%");
myChart.addMeasureAxis("x", "sum");
var y = myChart.addCategoryAxis("y", "supplier");
y.hidden = true;
supplierChartSeries = myChart.addSeries("supplier", dimple.plot.bar);
myChart.defaultColors = [
new dimple.color("#3498db", "#2980b9", 1), // blue
];

Resources