how to make Dimple Scatterplot no aggregate - dimple.js

I am trying to build a scatterplot on Iris data using dimple.js.
Here is my Code:
<div id="chartContainer">
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="http://dimplejs.org/dist/dimple.v2.2.0.min.js"></script>
<script type="text/javascript">
var svg = dimple.newSvg("#chartContainer", 590, 400);
d3.csv("/wp-content/uploads/2016/05/iris.csv", function (data) {
var myChart = new dimple.chart(svg, data);
myChart.setBounds(60, 30, 500, 330)
myChart.addMeasureAxis("x", "sepal_length");
myChart.addMeasureAxis("y", "sepal_width");
myChart.addSeries(null, dimple.plot.bubble);
//myChart.addLegend(200, 10, 360, 20, "right");
myChart.draw();
});
</script></div>
Here is the result:
I know dimple gonna aggregate data based on myChart.addSeries(null, dimple.plot.bubble);, that's why there is only one bubble comes out. But I wanna every records of data have a bubble, how can I cancel aggregation?

Ideally you'd have a field in your data which identifies what the bubble represents, which you could pass into the first parameter of addSeries as you mention.
myChart.addSeries("Observation", dimple.plot.bubble);
If you really don't have anything to distinguish what makes an element in your data distinct from another other than sepal width and length you can pass those in instead:
myChart.addSeries(["sepal_width", "sepal_length"], dimple.plot.bubble);
The last element in the array is used for colouring, so this will cause all bubbles with a different sepal length to be coloured the differently. Therefore I would suggest adding a label for what the series represents after the two fields:
myChart.addSeries(["sepal_width", "sepal_length", "Sepals"], dimple.plot.bubble);

Related

'state' mapped from Vuex doesn't work in mounted()

I use Vue2 and Vuex. My app draws a rectangle based on user input (length and width). I use mapState to get length and width from Vuex store. I can display those values in mainPage.vue so mapping and vuex works fine:
computed: {
...mapState("model2D", ["modelLength", "modelWidth"]),
},
The issue is when I try to refer to those values from mounted() - I set user input as rectangle length and width here (ZimModel.vue):
var line1 = new Line(this.modelLength, 1, black);
var line2 = new Line(this.modelWidth, 1, black);
but seems those vuex values are not passed here at all. When I return dimension in logs then I can see this:
r {x: 0, y: 0, width: 0, height: 0, setValues: ƒ ()…}
As you can see e.g. width is not assigned any value here. I use some 2D lib to draw shapes but I guess that regardless a library everything should work fine. I just simply pass vuex value. I don't know, maybe I'm doing sth wrong.
I add Sanbox here: https://codesandbox.io/s/vue-2-playground-vuex-2okckn?file=/src/components/ZimModel.vue:1218-1267
Main code where I try to draw a shape is located in ZimModel.vue component.

Chartist.js - point value and X label in tooltip?

I have a Chartist.js line chart with points and I'm using tooltip so when you hover over a point you get the value for that point. I'd also like to add the label for the X axis in there so this...
$chart.on('mouseenter', '.ct-point', function () {
const $point = $(this);
const label = Number($point.attr('ct:label')); // doesn't work
const value = Number($point.attr('ct:value')); // does work
$toolTip.html(value + ' at ' + label).show();
});
...would show the value of the point plus the index (X axis label).
I'm 3 years late but maybe someone else still has the same problem.
I had a similar issue with a bar chart that showed amounts of euro by date. The tooltip only showed the amount for each bar (y-value), but I also wanted it to show the date for that bar (x-value).
Chartist.js and the tooltip plugin come with an inbuilt solution for this - though this is neither intuitive nor well documented. So there is no special CSS or JS hacking involved. You only have to modify your series data array.
Before doing so, my data array looked like this (simplified):
var regularData= [];
// [...]
regularData.push(427615440);
regularData.push(428134236);
regularData.push(428543629);
// [...]
var graphData = {
series: regularData
};
new Chartist.Bar('#chart-container', graphData, options);
So in this case i had a bar chart where the bars each had a value, which was also shown in the tooltip. Now I wanted to add the date.
Solution
Instead of pushing the values directly to the array, you need to push container objects to it, that contain key-value pairs for "meta" and "value", where meta specifies the x-value and value specifies the y-value. Note: the "meta" value can be any value, it does not need to be consistent with the x-value in your data/axis.
var labeledData = [];
// [...]
labeledData.push({meta: "15.12.", value: 427615440});
labeledData.push({meta: "16.12.", value: 428134236});
labeledData.push({meta: "17.12.", value: 428543629});
// [...]
var graphData = {
series: [labeledData]
};
new Chartist.Bar('#chart-container', graphData, options);
And here we go! The mouesover-tooltip now also displays the date instead of the y-value only! Hope this helps. :)
Sidenote: I left out my tooltip formatting (euro values) and the customized CSS (bold y-value) for simplicity.

Use Dojo boxConstrainedMoveable to constrain movable div to window

I have a div, to which I applied Dojo dojo/dnd/Moveable. But, I'd like to prevent the user from dragging the div offscreen. So, I think I need to implement dojo/dnd/move/boxConstrainedMoveable.
I'm starting with this:
var dnd = new Moveable(this.domNode, {
'handle': this.titleNode
});
There's a similar SO question here:
Constrain a moveable object in Dojo. Applying that answer, I get something like this:
var dnd = new move.boxConstrainedMoveable(
'handle': this.titleNode
constraints: {
l: 0,
t: 20,
w: 500,
h: 500
},
within: true
);
But, I just can't understand how the bounding box works. I simply want the div to stay inside the window. I've tried implementing a few things with the window box, the div's margin box. Nothing's worked, and all I've made is a big mess.
I read the docs here:
http://dojotoolkit.org/api/?qs=1.9/dojo/dnd/move.boxConstrainedMoveable
Has anyone done this with Dojo? I'd be very appreciate of an example.
I looked up some old code I have and I did implement this type of movable once. This was written against Dojo 1.7, so things may have changed in 1.9. Fiddle demonstration: https://jsfiddle.net/4ev1daqr/26/
The main difference between your attempted solution and this is that the constraints property in the moveable needs to be a function rather than a static bounding box. When using the boxConstrainedMoveable module, the static bounding box should be assigned to a box property, rather than the constraints property.
This is actually a nice design, IMHO, because it allows the constraints to react to changes in application state, e.g. hiding a sidebar or moving a splitter, but it does make the simple case a bit more difficult to get working.
define(["dojo/_base/declare",
"dojo/dnd/move",
"dojo/dom",
"dojo/_base/window",
"dojo/dom-style",
"dojo/dom-geometry",
],
function (declare, move, dom, win, domStyle, domGeom) {
return declare( "my/dnd/move/BodyConstrainedMoveable", [move.constrainedMoveable], {
markupFactory: function(params, node){
return new this(node, params);
},
constructor: function(node, params) {
// Constrain the node to be within the body
this.constraints = function() {
var n = win.body(),
s = domStyle.getComputedStyle(n),
mb = domGeom.getMarginBox(n, s);
if ( this.node ) {
var menubox = domGeom.getMarginBox(this.node);
mb.w -= menubox.w;
mb.h -= menubox.h;
}
return mb;
};
}
})});

Finding Animated Bar Chart Library Or Component

I am interested in making a bar chart that changes over time (ideally bars will move up and down smoothly to show data changes over time). I didn't expect it would be difficult but, maybe due to the way I am searching, I cannot find a pre-built component or library that does this. I have come across other animated graphs that show data changes over time (like https://developers.google.com/chart/interactive/docs/gallery/motionchart and http://www.highcharts.com/demo/dynamic-update) but nothing that does what I describe in a bar chart. It would also work if I could find a line chart or pie chart that smoothly changed over time but I would rather make a bar chart to do this if possible.
Does an application or component or library like this exist (and if so can you point me in the right direction)? If for some reason nothing like this is available, what is the closest thing to it available (what is the path that would require the least amount of effort to produce this chart)?
ZingChart should be able to do this for you, and it's super easy to use. The chart configuration is defined using a JSON object. Inside the plot object, the animation object can hold a number of different animation options, including effect, speed, delay, and sequence. More information on ZingChart's animation effects can be found here. The render method is called to tell ZingChart where to render the chart using a div's unique ID. For this example, I configured a function to be called every 3000 milliseconds, generating a random array of numbers between 0 and 100, using the setseriesvalues method to change the data at plotindex 0.
var oData = {
"type": "bar",
"scaleY": {
"values": "0:100:10"
},
"plot": {
"animation": {
"effect": "ANIMATION_SLIDE_BOTTOM"
}
},
"series": [{
"values": [69, 68, 54, 48, 70, 74, 98, 70, 72, 68, 49, 69]
}]
};
zingchart.render({
id: 'myChartDiv',
width: 600,
height: 400,
data: oData
});
setInterval(function() {
var aValues = [];
for (var n = 0; n < 12; n++) {
var num = Math.random() * (100 - 0) + 0;
aValues.push(num);
}
console.log(aValues);
zingchart.exec('myChartDiv', 'setseriesvalues', {
plotindex: 0,
values: aValues
});
}, 3000);
<script src="http://cdn.zingchart.com/zingchart.min.js"></script>
<div id="myChartDiv"></div>
Full disclaimer: I'm on the ZingChart team, but if there's anything else I can help you with, I'd be happy to help!

Hiding a series by default in a spider plot

I have a spider plot in using the graphing library of Dojo defined like this:
require([
"dojox/charting/Chart",
"dojox/charting/themes/Claro",
"dojox/charting/plot2d/Spider",
"dojox/charting/action2d/Tooltip",
"dojox/charting/widget/SelectableLegend",
"dojox/charting/axis2d/Default"
], function (Chart, theme, Spider, Tooltip, Legend, Default) {
var chart = new Chart(element).setTheme(theme).addPlot("default", {
type: Spider,
radius: 200,
fontColor: "black",
labelOffset: "-20"
});
var colors = ["blue", "red", "green", "yellow", "purple", "orange", "teal",
"maroon", "olive", "lime", "aqua", "fuchsia"];
$.each(factors, function (index, factor) {
chart.addAxis(factor.name, {
type: Default,
min: factor.min,
max: factor.max
});
});
$.each(presets, function (pIndex, preset) {
var data = [];
$.each(factors, function (fIndex, factor) {
data[factor.name] = preset.values[fIndex];
});
chart.addSeries(preset.short, data, {
fill: colors[pIndex % colors.length]
});
});
new Tooltip(chart, "default");
chart.render();
new Legend({
chart: chart,
horizontal: false
}, $(element).next(".legend")[0]);
});
I add a series for every member of an array called presets and I use a selectable legend that lets the user turn them on or off as they want. However, what I can't seem to find in the docs is how to start a series in the unselected, not visible state? What I ideally want to do is cap the number of series visible when the page loads because in some cases I have up to 14 presets and it just looks a mess until the user deselects a bunch. So I'd like to have, say, every preset above the first 5 be hidden at the start.
Here's a crude fiddle I've knocked to demonstrate. What I want is to have some of the series unselected when the plot is first displayed.
Update: I tried adding this after adding my series:
var checkboxes = $(".dijitCheckBoxInput").each((index, elem) => {
if (index > 4) {
elem.click();
}
});
Which works, but seems very fragile. If they change the class assigned to checkboxes, it'll break. Also, it prohibits me using more than one set of dojo checkboxes because I don't have a good way to tell the difference. (Note, the IDs of the checkboxes added by the SelectableLegend are dijit_form_CheckBox_0, dijit_form_CheckBox_1, etc, which also gives no useful information as to what they are related to). I thought I might be able to use the legend placeholder div as a way to select the descendant checkboxes, but it appears that Dojo replaces the placeholder entirely with a table.
i looked into the dojo code and found the area in which the shapes are toggled on & off whitin the SelectableLegend.js :
var legendCheckBox = query(".dijitCheckBox", legend)[0];
hub.connect(legendCheckBox, "onclick", this, function(e){
this._toggle(shapes, i, legend.vanished, originalDyn, seriesName, plotName);
legend.vanished = !legend.vanished;
e.stopPropagation();
});
The toggling process is very complex and is based on many local attributes:
_toggle: function(shapes, index, isOff, dyn, seriesName, plotName){
arrayUtil.forEach(shapes, function(shape, i){
var startFill = dyn.fills[i],
endFill = this._getTransitionFill(plotName),
startStroke = dyn.strokes[i],
endStroke = this.transitionStroke;
if(startFill){
if(endFill && (typeof startFill == "string" || startFill instanceof Color)){
fx.animateFill({
shape: shape,
color: {
start: isOff ? endFill : startFill,
end: isOff ? startFill : endFill
}
}).play();
}else{
shape.setFill(isOff ? startFill : endFill);
}
}
if(startStroke && !this.outline){
shape.setStroke(isOff ? startStroke : endStroke);
}
}, this);
}
I tried also checking & unchecking the dijit/form/Checkbox in a legend manually, but that does not trigger the _toggle function in any case, even if you do a render() / fullrender() on the chart.
With that in mind it seems that there is no other possibilty to toggle the series on and off than by firing the onclick events manually.
To make your code less fragile, you could access the Checkbox widgets within the legend manually using:
query(".dijitCheckBox", legend); // Should deliver an array containing
the widgets.
and triggering the onclick event on them. Their keynumber in the array should correspond to the order the series where added...
Dojo is a fine piece of work, please dont stop working with it !
dojox/charting/Series has an attribute called dirty which according to the API docs is a "flag indicating whether or not this element needs to be rendered".
Alternately, if you are limiting the display of some series you can write a separate interface for adding them. For example, loop over the first 5. Then create a select box or list of check boxes with all entries and an onchange event that calls chart.addSeries.
Keeping a reference to each series you create will allow you to later call destroy() or destroyRecursive() on it if the user no longer wishes it displayed.
So while ideally you could toggle the display of these series, the worst case senerio is that you just add, destroy, and read based on some user input.
Using a templated widget will allow you to keep this interface and the chart tightly linked and support reuse.
BTW, consider using "dojo/_base/array" and "dojo/query" in place of the jquery
I think i've got it !
I found another way to access the checkboxes ! It's the same way dojo uses internally to connect the "toggle code" to the onclick event. First take a look at this from SelectableLegend.js (Lines 150 - 156):
// toggle action
var legendCheckBox = query(".dijitCheckBox", legend)[0];
hub.connect(legendCheckBox, "onclick", this, function(e){
this._toggle(shapes, i, legend.vanished, originalDyn, seriesName, plotName);
legend.vanished = !legend.vanished;
e.stopPropagation();
});
It looks like they use the ".dijitCheckBox" class to find the checkbox dom element and connect to it using dojo/connect. Now based on that, i made this function:
function toggleSeries (legend,num) {
dojo.query("*",legend.legends[num])[0].click();
dijit.findWidgets(legend.legends[num])[0]._onClick(); }
It doesn't use any class definition (because of the *) and it accesses the areas where the checkboxes are from within the SelectableLegend. It needs the SelectableLegend and the number of the series you want to deactivate as parameters. Here the jsfiddle example with this function & hiding all 4 of your series with it:
http://jsfiddle.net/luciancd/92Dzv/17/
Also please notice the "onDomReady" Option in jsfiddle, without it: doesnt work in IE.
And the ready function within the code !
Lucian
I have updated your code http://jsfiddle.net/92Dzv/18/
Here is the key to toogle.
dom.byId(le._cbs[0].id).click();
dom.byId(le._cbs[2].id).click();
Choose the index of your legend and set to _cbs.
By this way le._cbs[0].id you will get the real id of checkbox (that inside in the widget) and then just use click()
Note : le is came from here.
var le = new Legend({
chart: chart,
horizontal: false
}, legend);