Bar chart in Javascript: stacked bars + grouped bars - charts

I'm looking for a Javascript solution to mix Grouped and Stacked Bars with a beautiful graph, such as those provided by Protovis.
For example if I want to compare downloads on Apple (iPads+iPhones) devices to Android devices, I might have (excuse my terrible ascii art)
60k | ^
50k | # ^ ^
40k |# # ^ #^
30k |# #^ ^ #^
20k |#^ #^ #^ #^
10k |#^ #^ #^ #^
=================
Jan Feb Mar Apr
Legend
#: iPad Downloads
#: iPhone Downloads
^: Android Downloads

Checkout Google Chart Tools and Google Visualization
for instance you can specify the following:
cht=bvs
chco=4D89F9,C6D9FD
chd=t:10,50,60,80,40|
50,60,100,40,20
chds=0,160
let's say if you change the chd to
cht=bvs
chs=250x150
chco=4D89F9,C6D9FD
chd=t:0,50,0,80,0, 10, 50, 40
60,0,100,0,20, 50, 100, 60
chds=0,160
Take a look at the chart above (as if its a group chart, but actually its stacked). Then you can append data after to create stacked 'looking' group as the graph is intended.

Hey I just developed grouped+stacked bar chart on d3.js.
Source
Demo

Since no one's mentioned C3.js yet, here it is, with a stacked+grouped demo (source)
var chart = c3.generate({
bindto: "#chart",
data: {
columns: [
['data1', -30, 200, 200, 400, -150, 250],
['data2', 130, 100, -100, 200, -150, 50],
['data3', -230, 200, 200, -300, 250, 250]
],
type: 'bar',
groups: [
['data1', 'data2']
]
},
grid: {
y: {
lines: [{value:0}]
}
}
});
setTimeout(function () {
chart.groups([['data1', 'data2', 'data3']])
}, 1000);
setTimeout(function () {
chart.load({
columns: [['data4', 100, -50, 150, 200, -300, -100]]
});
}, 2000);
setTimeout(function () {
chart.groups([['data1', 'data2', 'data3', 'data4']])
}, 3000);
/*-- Chart --*/
/*-- From https://github.com/masayuki0812/c3/blob/0.4.10/c3.css --*/
/*-- Chart --*/
.c3 svg {
font: 10px sans-serif; }
.c3 path, .c3 line {
fill: none;
stroke: #000; }
.c3 text {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none; }
.c3-legend-item-tile, .c3-xgrid-focus, .c3-ygrid, .c3-event-rect, .c3-bars path {
shape-rendering: crispEdges; }
.c3-chart-arc path {
stroke: #fff; }
.c3-chart-arc text {
fill: #fff;
font-size: 13px; }
/*-- Axis --*/
/*-- Grid --*/
.c3-grid line {
stroke: #aaa; }
.c3-grid text {
fill: #aaa; }
.c3-xgrid, .c3-ygrid {
stroke-dasharray: 3 3; }
/*-- Text on Chart --*/
.c3-text.c3-empty {
fill: #808080;
font-size: 2em; }
/*-- Line --*/
.c3-line {
stroke-width: 1px; }
/*-- Point --*/
.c3-circle._expanded_ {
stroke-width: 1px;
stroke: white; }
.c3-selected-circle {
fill: white;
stroke-width: 2px; }
/*-- Bar --*/
.c3-bar {
stroke-width: 0; }
.c3-bar._expanded_ {
fill-opacity: 0.75; }
/*-- Focus --*/
.c3-target.c3-focused {
opacity: 1; }
.c3-target.c3-focused path.c3-line, .c3-target.c3-focused path.c3-step {
stroke-width: 2px; }
.c3-target.c3-defocused {
opacity: 0.3 !important; }
/*-- Region --*/
.c3-region {
fill: steelblue;
fill-opacity: 0.1; }
/*-- Brush --*/
.c3-brush .extent {
fill-opacity: 0.1; }
/*-- Select - Drag --*/
/*-- Legend --*/
.c3-legend-item {
font-size: 12px; }
.c3-legend-item-hidden {
opacity: 0.15; }
.c3-legend-background {
opacity: 0.75;
fill: white;
stroke: lightgray;
stroke-width: 1; }
/*-- Tooltip --*/
.c3-tooltip-container {
z-index: 10; }
.c3-tooltip {
border-collapse: collapse;
border-spacing: 0;
background-color: #fff;
empty-cells: show;
-webkit-box-shadow: 7px 7px 12px -9px #777777;
-moz-box-shadow: 7px 7px 12px -9px #777777;
box-shadow: 7px 7px 12px -9px #777777;
opacity: 0.9; }
.c3-tooltip tr {
border: 1px solid #CCC; }
.c3-tooltip th {
background-color: #aaa;
font-size: 14px;
padding: 2px 5px;
text-align: left;
color: #FFF; }
.c3-tooltip td {
font-size: 13px;
padding: 3px 6px;
background-color: #fff;
border-left: 1px dotted #999; }
.c3-tooltip td > span {
display: inline-block;
width: 10px;
height: 10px;
margin-right: 6px; }
.c3-tooltip td.value {
text-align: right; }
/*-- Area --*/
.c3-area {
stroke-width: 0;
opacity: 0.2; }
/*-- Arc --*/
.c3-chart-arcs-title {
dominant-baseline: middle;
font-size: 1.3em; }
.c3-chart-arcs .c3-chart-arcs-background {
fill: #e0e0e0;
stroke: none; }
.c3-chart-arcs .c3-chart-arcs-gauge-unit {
fill: #000;
font-size: 16px; }
.c3-chart-arcs .c3-chart-arcs-gauge-max {
fill: #777; }
.c3-chart-arcs .c3-chart-arcs-gauge-min {
fill: #777; }
.c3-chart-arc .c3-gauge-value {
fill: #000;
/* font-size: 28px !important;*/ }
<!-- link href="https://raw.githubusercontent.com/masayuki0812/c3/0.4.10/c3.min.css" rel="stylesheet"/-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://raw.githubusercontent.com/masayuki0812/c3/0.4.10/c3.min.js"></script>
<div id="chart"></div>

See also the Dojo toolkit's Dojox Charting API: Dojox charting

Related

Slider Feature using flutter

I tried to recreate the sliding image feature on the website superlist.com using html and I found a tutorial that made it work.
HTML
<div id="left-side" class="side">
<h2 class="title">
Sometimes a simple header is
<span class="fancy">better</span>
</h2>
</div>
<div id="right-side" class="side">
<h2 class="title">
Sometimes a simple header is
<span class="fancy">better</span>
</h2>
</div>
<a id="source-link" class="meta-link" href="https://superlist.com" target="_blank">
<i class="fa-solid fa-link"></i>
<span class="roboto-mono">Source</span>
</a>
<a id="yt-link" class="meta-link" href="https://youtu.be/zGKNMm4L-r4" target="_blank">
<i class="fa-brands fa-youtube"></i>
<span>2 min tutorial</span>
</a>
CSS
:root {
--yellow: rgb(253, 216, 53);
--blue: rgb(98, 0, 234);
--dark: rgb(20, 20, 20);
}
body {
background-color: var(--dark);
margin: 0px;
}
.side {
display: grid;
height: 100vh;
overflow: hidden;
place-items: center;
position: absolute;
width: 100%;
}
.side .title {
font-family: "Rubik", sans-serif;
font-size: 8vw;
margin: 0px 10vw;
width: 80vw;
}
.side .fancy {
font-family: "Lobster", cursive;
font-size: 1.3em;
line-height: 0.8em;
}
#left-side {
background-color: var(--blue);
width: 60%;
z-index: 2;
}
#left-side .title {
color: white;
}
#left-side .fancy {
color: var(--yellow);
}
#right-side {
background-color: var(--yellow);
}
#right-side .title {
color: var(--dark);
}
#right-side .fancy {
color: white;
}
/* -- YouTube Link Styles -- */
#source-link {
top: 60px;
}
#source-link > i {
color: rgb(94, 106, 210);
}
#yt-link {
top: 10px;
}
#yt-link > i {
color: rgb(239, 83, 80);
}
.meta-link {
align-items: center;
backdrop-filter: blur(3px);
background-color: rgba(40, 40, 40, 0.9);
border-radius: 6px;
box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.1);
cursor: pointer;
display: inline-flex;
gap: 5px;
left: 10px;
padding: 10px 20px;
position: fixed;
text-decoration: none;
transition: background-color 350ms, border-color 350ms;
z-index: 10000;
}
.meta-link:hover {
background-color: rgb(40, 40, 40);
}
.meta-link > i, .meta-link > span {
height: 20px;
line-height: 20px;
}
.meta-link > span {
color: white;
font-family: "Rubik", sans-serif;
transition: color 600ms;
}
JS
const left = document.getElementById("left-side");
const handleMove = e => {
left.style.width = `${e.clientX / window.innerWidth * 100}%`;
}
document.onmousemove = e => handleMove(e);
document.ontouchmove = e => handleMove(e.touches[0]);
I used the code and it worked fine but I was wondering whether you could do the same using flutter. I tried searching for specific widgets that allow you to make this kind of slider, but until now I haven't found anything satisfying, so I'm guessing you'd need a custom solution here.
How can I make this feature possible using flutter?
https://drive.google.com/file/d/1_FxXK2Ymo1GLRRIiNzmfIt95-DsYy1O2/view?usp=sharing
you can see a UI example above

How to apply grid to the individual sidebar listing in Mapbox map?

I'm using this example from mapbox.
I want to create something similar to the sidebar listings that can be seen on Airbnb and Zillow
:example
I was able to apply columns to the sidebar itself, but not a grid to the individual listings.
See in here:N
before
after
I tried changes in html, css, js as well. No success. Does anybody know how to do it?
<div id="map"></div>
<div class="map-overlay">
<div class="listing-box">
<div id="feature-listing" class="listing"></div>
</div>
</div>
#map {
position: absolute;
left: 50%;
width: 50%;
top: 0;
bottom: 0;
}
.map-overlay {
position: absolute;
width: 50%;
top: 0;
bottom: 0;
left: 0;
font: 12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif;
background-color: #fff;
max-height: 100%;
overflow: auto;
}
.map-overlay input {
display: block;
border: none;
width: 100%;
border-radius: 3px;
padding: 10px;
margin: 0px;
box-sizing: border-box;
}
.map-overlay .listing-box {
display: block;
margin: 10px;
}
.map-overlay .listing {
postiton: absolute;
display: inline-block;
width: 100%;
padding-bottom: 0px;
-webkit-column-count: 2; /* Chrome/Opera, Safari */
-moz-column-count: 2; /* Mozilla Firefox */
column-count: 2;
-webkit-column-gap: 10px; /* Chrome/Opera, Safari */
-moz-column-gap: 10px; /* Mozilla Firefox */
column-gap: 10px;
-webkit-column-rule: 1px single grey; /* Chrome/Opera, Safari */
-moz-column-rule: 1px single grey; /* Mozilla Firefox */
column-rule: 1px single grey;
}
.map-overlay .listing > * {
display: block;
height: 150px;
padding: 5px 10px;
margin-bottom: 10px;
}
.map-overlay .listing a {
display: block;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
color: #404;
text-decoration: none;
background: red;
}
.map-overlay .listing a:last-child {
border: none;
}
.map-overlay .listing a:hover {
background: #f0f0f0;
}
listingEl.innerHTML = "";
if (features.length) {
features.forEach(function(feature) {
var prop = feature.properties;
var item = document.createElement("a");
item.href = prop.wikipedia;
item.target = "_blank";
item.textContent = prop.name + " (" + prop.abbrev + ")";
item.addEventListener("mouseover", function() {
The whole project can be found here.
It seems like your problem is CSS only and you need to remove certain style's to get the view of the listing given on https://docs.mapbox.com/mapbox-gl-js/example/filter-features-within-map-view/
Remove .map-overlay .listing { CSS as it divide your grid with column-count: 2;
.map-overlay .listing a {
display: block;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
color: #404;
text-decoration: none;
/* background: red; */ //<---remove
}
.map-overlay .listing > * {
display: block;
/* height: 150px; */ //<---remove
padding: 5px 10px;
/* margin-bottom: 10px; */ //<---remove
}
Screenshot:
Good Luck!

Not adding custom marker with added css with leaflet map and L.Routing.control

I am trying to add custom markers to a leaflet map when drawing a route on the map using L.Routing.control. I have it working fine but when I try to add a marker with some custom css it does not do anything and I cant work out why because I get no console errors?
This is the code for adding my custom markers which works
route = L.Routing.control({
waypoints: [
L.latLng(window.my_lat, window.my_lng),
L.latLng(window.job_p_lat, window.job_p_lng)
],show: true, units: 'imperial',
router: L.Routing.mapbox('API-KEY HERE'),
createMarker: function(i, wp, nWps) {
if (i === 0 || i === nWps + 1) {
return mymarker = L.marker(wp.latLng, {
icon: redIcon
});
} else {
return job_start = L.marker(wp.latLng, {
icon: greenIcon
});
}
}
}).addTo(map);
var greenIcon = new L.Icon({
iconUrl: 'assets/marker-yellow.png',
shadowUrl: 'assets/marker-shadow.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowSize: [41, 41]
});
var redIcon = new L.Icon({
iconUrl: 'assets/marker-red.png',
shadowUrl: 'assets/marker-shadow.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowSize: [41, 41]
});
And the CSS and code for the new marker I am trying to add and does not work
CSS
.css-icon {
}
.gps_ring {
border: 3px solid #999;
-webkit-border-radius: 30px;
height: 18px;
width: 18px;
-webkit-animation: pulsate 1s ease-out;
-webkit-animation-iteration-count: infinite;
/*opacity: 0.0*/
}
#-webkit-keyframes pulsate {
0% {-webkit-transform: scale(0.1, 0.1); opacity: 0.0;}
50% {opacity: 1.0;}
100% {-webkit-transform: scale(1.2, 1.2); opacity: 0.0;}
}
The JS
var cssIcon = new L.divIcon({
// Specify a class name we can refer to in CSS.
className: 'css-icon',
html: '<div class="gps_ring"></div>'
// Set marker width and height
,iconSize: [22,22]
// ,iconAnchor: [11,11]
});
But when I add 'icon: cssIcon' It displays nothing?
Any help would be great thanks
.gps_ring {
position: absolute;
border: 3px solid #999;
-webkit-border-radius: 30px;
height: 18px;
width: 18px;
-webkit-animation: pulsate 1s ease-out;
-webkit-animation-iteration-count: infinite;
/*opacity: 0.0*/
}
And Or
.css-icon {
position relative;
}
#-webkit-keyframes pulsate {
position: absolute;
z-index:9999;
0% {-webkit-transform: scale(0.1, 0.1);
opacity: 0.0;}
50% {opacity: 1.0;}
100% {-webkit-transform: scale(1.2, 1.2); opacity: 0.0;} }
Ok, I have managed to do it this way which works good apart from on the top left hand side of the marker box there is a line and I cannot find out why its there?
JS
var jobicon = L.divIcon({
html:'<div style="background-image: url(img/avatar-small.png);height:46px;width:46px" class="map-label-content"></div><div class="map-label-arrow"></div>'
});
CSS
.map-label {
position: absolute;
bottom: 0;left: -50%;
display: flex;
flex-direction: column;
text-align: center;
}
/*Wrap the content of the divicon (text) in this class*/
.map-label-content {
order: 1;
position: relative; left: -50%;
background-color: #fff;
border-radius: 5px;
border-width: 2px;
border-style: solid;
border-color: #444;
padding: 0px;
white-space: wrap;
}
/*Add this arrow*/
.map-label-arrow {
order: 2;
width: 0px; height: 0px; left: 50%;
border-style: solid;
border-color: #444 transparent transparent transparent;
border-width: 10px 6px 0 6px; /*[first number is height, second/fourth are rigth/left width]*/
margin-left: 14px;
}
/*Instance classes*/
.map-label.inactive {
opacity: 0.9;
}

Chart.js multiTooltip Labels in Pie

I want to show multiple values in pie tool tip. Example:
Horror: 30%
Action : 45%
Comedy : 15%
Drama : 10%
When hover on the section this should display in tooltip.
Is this possible with Chart.js or any other library ?
Plz help. Thanks.
You use the customTooltips option. Here is an example adapted from https://github.com/nnnick/Chart.js/blob/master/samples/pie-customTooltips.html
HTML
<canvas id="myChart" width="400" height="200"></canvas>
<div id="chartjs-tooltip"></div>
CSS
#chartjs-tooltip {
opacity: 0;
position: absolute;
background: rgba(0, 0, 0, .7);
color: white;
padding: 3px;
border-radius: 3px;
-webkit-transition: all .1s ease;
transition: all .1s ease;
pointer-events: none;
-webkit-transform: translate(-50%, 0);
transform: translate(-50%, 0);
}
#chartjs-tooltip.above {
-webkit-transform: translate(-50%, -100%);
transform: translate(-50%, -100%);
}
#chartjs-tooltip.above:before {
border: solid;
border-color: #111 transparent;
border-color: rgba(0, 0, 0, .8) transparent;
border-width: 8px 8px 0 8px;
bottom: 1em;
content:"";
display: block;
left: 50%;
top: 100%;
position: absolute;
z-index: 99;
-webkit-transform: translate(-50%, 0);
transform: translate(-50%, 0);
}
JS
var ctx = $("#myChart").get(0).getContext("2d");
var data = [{
value: 300,
color: "#F7464A",
highlight: "#FF5A5E",
label: "Red",
otherData: "<div>Horror: 10%</div><div>Romance: 30%</div><div>Rest: 70%</div>"
}, {
value: 50,
color: "#46BFBD",
highlight: "#5AD3D1",
label: "Green",
otherData: "<div>Horror: 25%</div><div>Romance: 25%</div><div>Rest: 50%</div>"
}, {
value: 100,
color: "#FDB45C",
highlight: "#FFC870",
label: "Yellow",
otherData: "<div>Horror: 1%</div><div>Romance: 3%</div><div>Rest: 96%</div>"
}]
var tot = 0;
data.forEach(function (item) {
tot += item.value;
})
tot *= 0.01;
var myPieChart = new Chart(ctx).Pie(data, {
tooltipTemplate: "<%=label%>",
customTooltips: function (tooltip) {
// Tooltip Element
var tooltipEl = $('#chartjs-tooltip');
// Hide if no tooltip
if (!tooltip) {
tooltipEl.css({
opacity: 0
});
return;
}
// Set caret Position
tooltipEl.removeClass('above below');
tooltipEl.addClass(tooltip.yAlign);
// Set Text
data.forEach(function(item) {
if (item.label == tooltip.text)
tooltipEl.html(item.otherData);
})
// Find Y Location on page
var top = tooltip.y - tooltip.caretHeight - tooltip.caretPadding;
// Display, position, and set styles for font
tooltipEl.css({
opacity: 1,
left: tooltip.chart.canvas.offsetLeft + tooltip.x + 'px',
top: tooltip.chart.canvas.offsetTop + top + 'px',
fontFamily: tooltip.fontFamily,
fontSize: tooltip.fontSize,
fontStyle: tooltip.fontStyle,
});
}
});
Fiddle - http://jsfiddle.net/u463hctb/1/

How to hide gwt-dialog box border completely?

How could I hide border of dialog box in GWT completely or we can say that hide the dialog box's caption portion completely. I tried to use .gwt-DialogBox .Caption {} in css
but I couldn't find any option which could hide the border fully.
Thanks in advance!
Don't use gwt-DialogBox name for css to change dialog box. it will not apply. try to apply different style name with same style like:
.gwt-DialogBoxNew
{
border: 8px solid #7F7F7F;
border-radius: 6px 6px 6px 6px;
box-shadow: none;
line-height: 7px;
opacity: 1;
z-index: 1000;
background-color : #FFFFFF;
}
.gwt-DialogBoxNew .Caption {
background: none repeat scroll 0 0 #E4E4E4;
border: medium none #D4D4D4;
cursor: default;
font-family: Arial Unicode MS, Arial, sans-serif !important;
font-size: 18px;
font-weight: 400;
line-height: 27px;
padding:2px 0px 0px 0px;
}
.gwt-DialogBoxNew .dialogContent {
}
.gwt-DialogBoxNew .dialogMiddleCenter {
padding: 3px;
background: white;
}
.gwt-DialogBoxNew .dialogBottomCenter {
}
.gwt-DialogBoxNew .dialogMiddleLeft {
/* background: url(images/vborder.png) repeat-y -31px 0px; */
}
.gwt-DialogBoxNew .dialogMiddleRight {
/* background: url(images/vborder.png) repeat-y -32px 0px;
}
.gwt-DialogBoxNew .dialogTopLeftInner {
width: 10px;
height: 8px;
zoom: 1;
background: none repeat scroll 0 0 #E4E4E4;
}
.gwt-DialogBoxNew .dialogTopRightInner {
width: 12px;
zoom: 1;
background: none repeat scroll 0 0 #E4E4E4;
}
.gwt-DialogBoxNew .dialogBottomLeftInner {
width: 10px;
height: 12px;
zoom: 1;
}
.gwt-DialogBoxNew .dialogBottomRightInner {
width: 12px;
height: 12px;
zoom: 1;
}
.gwt-DialogBoxNew .dialogTopLeft {
/* background: url(images/circles.png) no-repeat -20px 0px;
-background: url(images/circles_ie6.png) no-repeat -20px 0px; */
background: none repeat scroll 0 0 #E4E4E4;
}
.gwt-DialogBoxNew .dialogTopRight {
/* background: url(images/circles.png) no-repeat -28px 0px;
-background: url(images/circles_ie6.png) no-repeat -28px 0px; */
background: none repeat scroll 0 0 #E4E4E4;
}
.gwt-DialogBoxNew .dialogBottomLeft {
/* background: url(images/circles.png) no-repeat 0px -36px;
-background: url(images/circles_ie6.png) no-repeat 0px -36px; */
}
.gwt-DialogBoxNew .dialogBottomRight {
/* background: url(images/circles.png) no-repeat -8px -36px;
-background: url(images/circles_ie6.png) no-repeat -8px -36px; */
}
Remove border style from it as you concern here.
A DialogBox is basically a DecoratedPopupPanel with a caption. You want neither the decoration nor the caption, so how about using a PopupPanel instead? (AFAICT, the only difference will be how you size the panel)