C3.js - Show/hide points independently for a data series - d3.js

I am creating a line chart for a data series using C3.js.
I am struggling in trying to show the "points" only for one of the series.
Basically, first I am creating a multiple series line chart with some reference data, and then I am loading (with char.load) a new particular data line in which I want to show points, only for that particular line while the other reference lines remain with hidden points.
Is that possible via C3.js? If so, could you instruct me to do so, thanks!
Also, any method to do so using D3.js while using C3.js is welcome.
This is the official example in which all points are hidden for a data series, just for reference:
http://c3js.org/samples/point_show.html

c3.js provides comprehensive class attributes on all its elements so you can customize them with CSS. For example to hide the points on the 2nd series add this CSS:
#chart .c3-circles-data2 {
display: none;
}
Example here.

Here's an example of using the show and hide methods of a chart object to selectively display lines:
<!DOCTYPE html>
<html lang="en">
<head>
<title>show hide</title>
<meta charset="utf-8" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.js"></script>
</head>
<body>
<div id="chart"></div>
<script>
var chart = c3.generate({
bindto: '#chart',
data: {
x: 'x',
columns: [
['x', 1, 2, 3, 4, 5],
['y1', 3, 5, 6, 4, 5],
['y2', 2, 4, 7, 6, 5]
]
}
});
function cbclick(a){
var lineData = "y" + a;
var cbID = "cb" + a
var cb = document.getElementById(cbID);
if (cb.checked) {
chart.show([lineData]);
} else {
chart.hide([lineData]);
}
}
</script>
<div align="center">
<input type="checkbox" id="cb1" onclick="cbclick(1)" checked="true">y1</input>
<input type="checkbox" id="cb2" onclick="cbclick(2)" checked="true">y2</input>
</div>
</body>

There are a code for this purpose in the C3.js library:
point: {
show: false,
}
You can check this at here

Related

Different colours for dc.js barchart

I am trying to create a barchart (not rowchart) using d3.js and dc.js. I can create the bars ok, but they are all the same colour.
I have tried :
ordinalColors()
scaleOrdinal.range()
Renderlet
colorAccessor
but they all give the one colour for all bars, except colorAccessor which displays no bars at all.
I am using dc.js (version 3.0.2) and d3.js (version 5.4.0) and crossfilter (version 1.3.5).
Could someone please tell me an approach that will work to get different colours on each of my bars please?
Here is my code:
fruits = [{
"name": "apple",
"cnt": 10
},
{
"name": "orange",
"cnt": 15
},
{
"name": "banana",
"cnt": 12
},
{
"name": "grapefruit",
"cnt": 2
},
{
"name": "grapefruit",
"cnt": 4
},
{
"name": "pomegranate",
"cnt": 1
},
{
"name": "lime",
"cnt": 12
},
{
"name": "grape",
"cnt": 50
}
];
var ndx = crossfilter(fruits);
fruitDimension = ndx.dimension(function(d) {
return d.name;
}),
sumGroup = fruitDimension.group().reduceSum(function(d) {
return d.cnt;
});
fruitColours = d3.scaleOrdinal().range(["red", "yellow", "purple", "pink", "green", "orange", "blue"]);
barChart
// .ordinalColors(["red", "yellow", "purple", "pink", "green", "orange", "blue"])
// .ordinalColors(fruitColours)
// .ordinalColors(["#79CED7", "#66AFB2", "#C96A23", "#D3D1C5", "#F5821F"])
.width(768)
.height(380)
.x(d3.scaleBand())
.xUnits(dc.units.ordinal)
.brushOn(false)
.xAxisLabel('Fruit')
.yAxisLabel('Quantity Sold')
.dimension(fruitDimension)
.barPadding(0.1)
.outerPadding(0.05)
.group(sumGroup)
.colorAccessor(["#79CED7", "#66AFB2", "#C96A23", "#D3D1C5", "#F5821F", "grey", "purple"])
// .on("renderlet", function(chart){
// var colors =d3.scaleOrdinal().domain(["apple", "orange", "banana", "grapefruit", "pomegranate", "lime", "grape"])
// .range(["steelblue", "brown", "red", "green", "yellow", "grey", "purple"]);
// chart.selectAll('rect.bar').each(function(d){
//// d3.select(this).attr("style", "fill: " + colors(d.key)); // use key accessor if you are using a custom accessor
// d3.select(this).attr("style", "fill: " + colors(d.name)); // use key accessor if you are using a custom accessor
// });
// });
;
dc.renderAll();
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>School Donations Dashboard</title>
<link rel="stylesheet" href="vendor/css/bootstrap.min.css" />
<link rel="stylesheet" href="vendor/css/dc.css" />
<link rel="stylesheet" href="vendor/css/keen-dashboards.css" />
<link rel="stylesheet" href="css/custom.css" />
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="index.xhtml">Dashboard</a>
</div>
</div>
</div>
<div id="outer" class="container-fluid">
<!-- Test Bar Chart -->
<div class="chartWrapper">
<div class="chartTitle">
Bar Chart
</div>
<div class="chartStage">
<div id="barChart"></div>
</div>
</div>
<!-- Test Bar Chart -->
</div>
<!-- /outer -->
<hr />
<script src="vendor/js/jquery.min.js">
</script>
<script src="vendor" name="js/bootstrap.min.js">
</script>
<script src="vendor" name="js/crossfilter.js">
</script>
<script src="vendor/js/d3-v5.min.js">
</script>
<script src="vendor/js/d3-scale.min.js">
</script>
<script src="vendor/js/dc.js">
</script>
<script src="vendor/js/queue.js">
</script>
<script src="vendor/js/keen.min.js">
</script>
<script src="js/graph.js">
</script>
</body>
</html>
It looks like the problem you ran into is confusion between the role of the color accessor (.colorAccessor()) and the color scale (.colors()).
In all dc.js charts, an accessor function will be used to fetch the value that should determine the color. Then this value will be passed through a color scale in order to determine the actual color.
This is handy because for the most part your data is not going to have actual colors in it. The color scale takes some value from your data and maps it to a color.
When you specify the colorAccessor you need to give it a function which takes the data supplied by the group, in {key, value} form, and extracts the value you want mapped to a color.
If you want to change the colors used, you can use .colors(), supplying a d3 scale appropriate for your data, or you can use the convenience functions .ordinalColors() or .linearColors() and give the colors you want.
That's all you need for most charts. But for stacked charts (bar and line), you also need to specify the color accessor. This is because by default the stack mixin uses the layer (stack name) to key the color:
_chart.colorAccessor(function (d) {
var layer = this.layer || this.name || d.name || d.layer;
return layer;
});
(source)
So if you want unique colors for each bar, basing the color accessor on the group key is a good bet:
chart
.colorAccessor(d => d.key)
.ordinalColors(["#79CED7", "#66AFB2", "#C96A23", "#D3D1C5", "#F5821F", "grey", "purple"]);
However you'll need to make sure to specify at least as many ordinal colors as there are bars because an ordinal scale will repeat when the domain is larger size than the range.
Demo fiddle.

Adding a D3.js Liquid Fill gauge in a Leaflet popup

I'm trying to add a D3.js liquid fill gauge (http://bl.ocks.org/brattonc/5e5ce9beee483220e2f6) in a Leaflet popup without succeeding.
Here is my code:
var map = L.map('map').setView([47.261491,-1.549244], 16);
var dataCenterIcon = L.icon({
iconUrl: 'images/datacenter-icon.png',
iconSize: [20, 20] // size of the icon
});
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap'
}).addTo(map);
d3.json("data/datacentersSigma.json",function (data){L.geoJson(data,{
pointToLayer: function (feature,latlng){return L.marker(latlng,{icon:dataCenterIcon});},
onEachFeature : function (feature, layer) {
var div = $('<div class="popupGraph" style="width: 200px; height:200px;"><svg id="gauge"/></svg></div>')[0];
var popup = L.popup().setContent(div);
layer.bindPopup(popup);
// var svg = d3.select(div).select("svg").attr("width", 200).attr("height", 200);
// svg.append("rect").attr("width", 150).attr("height", 150).style("fill", "lightBlue");
loadLiquidFillGauge("gauge",55);
}}).addTo(map);});
d3.json("data/trajetsFibreDCSigma.json",function (data){
L.geoJson(data, {
style: function(feature){return {color : feature.properties.stroke};}
}).addTo(map);
});
<!DOCTYPE html>
<html>
<head>
<title>Yepee</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/leaflet.css" />
<script src="js/leaflet.js"></script>
<script src="js/d3.js"></script>
<script src="js/liquidFillGauge.js"></script>
<script src="js/jquery-1.11.3.min.js"></script>
</head>
<body>
<div id="map" style="width: 800px; height: 600px"></div>
<!-- <svg id="gauge"/>-->
<script src="js/yepee.js" type="text/javascript"></script>
</body>
</html>
When I'm trying to display my map, I can't even see the markers and I've got this error:
TypeError: d3_window(...) is null
I can also load a liquid fill gauge on a svg element which isn't on my map.
I've tried to add just a simple svg square in the popup by following an example (http://jsfiddle.net/2XfVc/132/) and it worked.
The goal is to put that gauge in the leaflet popup and despite searching for a long time, I can't find what the problem is.
Thank you in advance for your answers.
You're trying to initialize the gauge when the actual SVG element isn't added to the DOM yet. Once the popup opens, the content gets added to the DOM, that's when you should initialize the gauge.
// Have same content for all your popups
var content = '<svg id="gauge" width="100" height="100"></svg>'
// Set markers with popup, include content and set value as option
new L.Marker([0, -45]).bindPopup(content, {'value': 33}).addTo(map)
new L.Marker([0, 45]).bindPopup(content, {'value': 66}).addTo(map)
// Catch popup open event
map.on('popupopen', function (e) {
// Initialize the gauge with current popup option's value
loadLiquidFillGauge('gauge', e.popup.options.value);
})
Demo on Plunker: http://embed.plnkr.co/2hMjBt/preview

D3 Dimple - How to show multiple dimple charts on same page?

I'm making an html page with several examples of charts that I will be using. On the page I have a Dimple line graph, a pie chart, a wordcloud etc. When I try to add a second dimple graph - this time a bar graph, the first dimple line graph that I already have on the page is drawn on top of my bar graph:
My HTML file looks like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>D3 Graphs</title>
<link rel="stylesheet" type="text/css" href="_/base.css">
<link rel="stylesheet" type="text/css" href="_/c3CSS.css">
<script type="text/javascript" src="_/d3.min.js"></script>
<script type="text/javascript" src="_/dimple.v2.1.0.min.js"></script>
<script type="text/javascript" src="_/c3.min.js"></script>
<script type="text/javascript" src="_/d3.layout.cloud.js"></script>
</head>
<body>
<div id="chartContainer">
<h1>Hot Topics Line</h1>
<script type="text/javascript" src=CurvyLine.js></script>
</div>
<h1>Hot Topics Pie</h1>
<div id="chart">
<script type="text/javascript" src=Pie.js></script>
</div>
<div id="wordCloud">
<h1>Clickable Word Cloud</h1>
<script type="text/javascript" src=WordCloud.js></script>
</div>
<div id="bar">
<h1>Clickable Word Cloud</h1>
<script type="text/javascript" src=WeekBar.js></script>
</div>
</body>
</html>
Without adding the bar chart at the end, the line graph displays properly at the top of the page above the pie chart. However, with the bar chart added, both the line and bar graph are drawn inside the "bar" div. Can anyone help with this please? Here is my line graph js file:
var svg = dimple.newSvg("#chartContainer", 590, 400);
d3.tsv("data/tweet_example.tsv", function (data) {
//data = dimple.filterData(data, "Owner", ["Aperture", "Black Mesa"])
var myChart = new dimple.chart(svg, data);
myChart.setBounds(60, 30, 505, 305);
var x = myChart.addCategoryAxis("x", "Month");
x.addOrderRule("Date");
myChart.addMeasureAxis("y", "Tweets");
var s = myChart.addSeries("Topic", dimple.plot.line);
s.interpolation = "cardinal";
myChart.addLegend(60, 10, 500, 20, "right");
myChart.draw();
});
and here is my bar graph js file:
var svg = dimple.newSvg("#bar", 800, 410);
d3.tsv("data/tweet_example2.tsv", function (data) {
//data = dimple.filterData(data, "Owner", ["Aperture", "Black Mesa"])
var barChart = new dimple.chart(svg, data);
barChart.addCategoryAxis("x", ["Day", "Topic"]);
barChart.addMeasureAxis("y", "Tweets");
barChart.addSeries("Topic", dimple.plot.bar);
barChart.addLegend(65, 10, 510, 20, "right");
barChart.draw();
barChart.draw();
});
Your problem is that you are using the same global name svg to hold references to two different charts. When your second piece of code runs, it overwrites the svg value that you had from the first piece of code, and when the .tsv() callback returns, it finds a reference to the second graph.
Simplest solution: use different names for svg variable in both pieces of code: svg1 and svg2 will be fine.
Most elegant solution: use some kind of namespace management, such as wrapping both pieces of code in immediately called functions:
function() {
// your first chunk of code here
}()
function() {
// your second chunk of code here
}()
This way you will have two svg variables local to their own scopes

d3.js not working on local server

d3.js is not appending the div as expected. Debuggin on FF 18+ and Firebug.
The d3 Object is returned (on alert message) but the chart object returns blank.
The d3.js lib is loading ok.
Here's the code
<?php header('Content-type: text/html; charset=utf-8');?>
<!DOCTYPE html>
<html>
<head>
<script type='text/javascript' src='js/d3.v3.js'></script>
<script type='text/javascript'>
var data = [4, 8, 15, 16, 23, 42];
var chart = d3.select("#hurtme").append("div").attr("class", "chart");
alert (d3);
//chart.selectAll("div").data(data).enter().append("div").style("width", function(d) { return d * 10 + "px"; }).text(function(d) { return d; });
</script>
</head>
<body>
<div id='hurtme'></div>
hello
</body>
</html>
What am I missing?
PS: I've discarted the browser imcompatibility since other examples from the web works fine.
PS2: Also tried using d3.v2.js and loading from source on <script src="http://d3js.org/d3.v3.min.js"></script>, no success so far.
Your script is loaded and executed before the div comes into existence. Try moving the script tags after the div:
<div id='hurtme'></div>
<script> type='text/javascript'>
var data = [4, 8, 15, 16, 23, 42];
var chart = d3.select("#hurtme").append("div").attr("class", "chart");
</script>
Or use an 'onload' function: window.onload vs document.onload

how to animate jqplot bar chart like example

Has anyone had any luck with this?
I copied and pasted the exact example code here http://www.jqplot.com/deploy/dist/examples/barTest.html into my text editor. I added all the .js files and .css file required. when I run the page in any browser, I am not seeing the bars or the animation. I have looked at the source code on the above URL as well to see how it works. Could someone tell me why I can the animated bar chart on the URL but not from my desktop? What's different? Here is the exact code I copied:
<html>
<title>Untitled Document</title>
<link rel="stylesheet" href="js/jquery.jqplot.min.css" type="text/css" />
<!--[if lt IE 9]><script language="javascript" type="text/javascript" src="js/excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script language="javascript" type="text/javascript" src="js/jquery.jqplot.min.js"></script>
<script language="javascript" type="text/javascript" src="js/excanvas.min.js"></script>
<script language="javascript" type="text/javascript" src="plugins/jqplot.barRenderer.min.js"></script>
<script>
$(document).ready(function(){
$.jqplot.config.enablePlugins = true;
var s1 = [2, 6, 7, 10];
var ticks = ['a', 'b', 'c', 'd'];
plot1 = $.jqplot('chart1', [s1], {
// Only animate if we're not using excanvas (not in IE 7 or IE 8)..
animate: !$.jqplot.use_excanvas,
seriesDefaults:{
renderer:$.jqplot.BarRenderer,
pointLabels: { show: true }
},
axes: {
xaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
ticks: ticks
}
},
highlighter: { show: false }
});
$('#chart1').bind('jqplotDataClick',
function (ev, seriesIndex, pointIndex, data) {
$('#info1').html('series: '+seriesIndex+', point: '+pointIndex+', data: '+data);
}
);
});
</script>
</head>
<body>
<div id="chart1" style="margin-top: 20px; margin-left: 20px;width: 300px; height: 300px; position: relative;"></div>
<div><span>Moused Over: </span><span id="info1">Nothing</span></div>
</body>
</html>
here is what I see in the browser after running that code:
Thanks
For anyone interested, I've found the answer. The example code taken from the barchart.html page in my post doesn't appear to need the conditional syntax (below) in order to animate the bars:
$.jqplot.config.enablePlugins = true;
// Only animate if we're not using excanvas (not in IE 7 or IE 8)..
animate: !$.jqplot.use_excanvas,
From the animate example on the examples page , the following code will do the trick:
animate: true,
// Will animate plot on calls to plot1.replot({resetAxes:true})
animateReplot: true,
I read the entire documentation and was doing a lot of playing around with the code. Eventually, I got to the full "examples" page (not the few listed on the tests and examples page which I initially viewed since it was listed first in the documentation). I really wanted to understand the plugin code since the developer took so much time to really provide a ton of info, comments and updates to his code base.

Resources