I am using Cytoscape for network visualization.
I have found this example of grouped nodes that you can expand and contract.
My question is, is it possible to highlight nodes and then dynamically add/remove them to a group on an ad-hoc basis?
I am yet to find an examples online of someone actually trying this and all the examples I have found like the aforementioned already have the groups predefined in the initial data load.
You can use the drag and drop extension of cytoscape.
Also, there is the clipboard extension, where you can select multiple elements via ctrl + mousedrag.
var cy = window.cy = cytoscape({
container: document.getElementById('cy'),
style: [{
selector: 'node',
style: {
'label': 'data(id)'
}
},
{
selector: 'node:parent',
style: {
'label': ''
}
},
{
selector: 'edge',
style: {
'curve-style': 'bezier',
'target-arrow-shape': 'triangle'
}
},
{
selector: '.cdnd-grabbed-node',
style: {
'background-color': 'red'
}
},
{
selector: '.cdnd-drop-sibling',
style: {
'background-color': 'red'
}
},
{
selector: '.cdnd-drop-target',
style: {
'border-color': 'red',
'border-style': 'dashed'
}
}
],
elements: {
nodes: [{
data: {
id: 'a'
}
},
{
data: {
id: 'b'
}
},
{
data: {
id: 'c'
}
},
{
data: {
id: 'd',
parent: 'p'
}
},
{
data: {
id: 'p'
}
}
],
edges: [
]
}
});
var cdnd = cy.compoundDragAndDrop();
var removeEmptyParents = false;
var isParentOfOneChild = function(node) {
return node.isParent() && node.children().length === 1;
};
var removeParent = function(parent) {
parent.children().move({
parent: null
});
parent.remove();
};
var removeParentsOfOneChild = function() {
cy.nodes().filter(isParentOfOneChild).forEach(removeParent);
};
// custom handler to remove parents with only 1 child on drop
cy.on('cdndout', function(event, dropTarget) {
if (removeEmptyParents && isParentOfOneChild(dropTarget)) {
removeParent(dropTarget);
}
});
// custom handler to remove parents with only 1 child (on remove of drop target or drop sibling)
cy.on('remove', function(event) {
if (removeEmptyParents) {
removeParentsOfOneChild();
}
});
// toggle check handler
document.getElementById('remove-1ch-parents').addEventListener('click', function() {
removeEmptyParents = !removeEmptyParents;
if (removeEmptyParents) {
removeParentsOfOneChild();
}
});
body {
font-family: helvetica neue, helvetica, liberation sans, arial, sans-serif;
font-size: 14px;
}
#cy {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: 1;
}
h1 {
opacity: 0.5;
font-size: 1em;
font-weight: bold;
}
#options {
z-index: 2;
position: absolute;
right: 0;
top: 0;
margin: 0.5em;
}
<head>
<title>cytoscape-compound-drag-and-drop demo</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
<script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/cytoscape-compound-drag-and-drop#1.0.0/cytoscape-compound-drag-and-drop.min.js"></script>
</head>
<body>
<h1>cytoscape-compound-drag-and-drop</h1>
<div id="cy"></div>
<div id="options">
<input id="remove-1ch-parents" type="checkbox" value="false" />
<label for="remove-1ch-parents">Remove parents with only one child</label>
</div>
</body>
The question itself is not that clear requirenment-wise, so if there is still something unclear, please edit it to be more precise (and maybe your code so that we can use that as a base. THX
Related
I have this problem when I try to load my map(Don't pay attention to the look of the sidebar, I'll fix it later). Everything looks fine but when I try to click on my markers,it finds the correct marker , but after 1-2 sec I am getting this error:"page doesn't exist enter a valid url and try again"
I did a lot of research,and now understand that the problem is in "appendchild". Also,If I am correct ,I can replace this functionality with " template for:each",right? I tried to do different options , but I am not sure If I am doing it correct... Can someone help me with this error? I put the code that worked before error:
css
body {
color: #404040;
margin: 0;
padding: 0;
-webkit-font-smoothing: antialiased;
}
.sidebar {
position: absolute;
width: 33.3333%;
height: 100%;
top: 0;
left: 15;
overflow: hidden;
border-right: 1px solid rgba(0, 0, 0, 0.25);
color: rgb(19, 7, 48);
}
.map {
position: absolute;
left: 15%;
width: 85%;
top: 0;
bottom: 0;
}
js
import { LightningElement } from 'lwc';
import { loadScript, loadStyle } from 'lightning/platformResourceLoader';
import mapbox from '#salesforce/resourceUrl/MapBoxJs';
export default class Test extends LightningElement {
connectedCallback() {
Promise.all([
loadStyle(this, mapbox + '/mapbox.css'),
loadScript(this, mapbox + '/mapbox.js'),
]).then(() => {
this.InitMap()
;
})
}
InitMap(){
L.mapbox.accessToken =
"pk*****";
const geojson = {
type: "FeatureCollection",
features: [
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [-108.99664191330069,45.27431839321315],
},
properties: {
title: "BUS 95",
description: "95 bus is coming",
"marker-color": "#FEF9A7",
"marker-size": "medium",
"marker-symbol": "95",
},
},
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [-109.04996965964688,45.238656126154666],
},
properties: {
title: "Bus 28",
description: "Bus 28 is coming...",
"marker-color": "#F5DF27",
"marker-size": "medium",
"marker-symbol": "28",
},
},
],
};
const map = L.mapbox
.map(
this.template.querySelector('.map')
)
.setView([45.281072930532304,-109.01104040481425], 14)
.addLayer(L.mapbox.styleLayer("mapbox://styles/mapbox/streets-v11"));
const listings = this.template.querySelector('.listings');
const locations = L.mapbox.featureLayer().addTo(map);
locations.setGeoJSON(geojson);
function setActive(el) {
const siblings = listings.getElementsByTagName("div");
for (const sibling of siblings) {
sibling.classList.remove("active");
}
el.classList.add("active");
}
locations.eachLayer((locale) => {
const prop = locale.feature.properties;
let popup = `<h3>${prop.title}</h3><div>${prop.description}`;
const listing = listings.appendChild(document.createElement("div"));
listing.className = "item";
const link = listing.appendChild(document.createElement("a"));
link.href = "title";
link.className = "title";
link.innerHTML = `${prop.title}`;
link.onclick = function () {
setActive(listing);
map.setView(locale.getLatLng(), 16);
locale.openPopup();
return false;
};
locale.on("click", () => {
map.panTo(locale.getLatLng());
setActive(listing);
});
locale.bindPopup(popup);
});
}
}
html
<template>
<div class="sidebar">
<div class="heading">
<h2>two busses</h2>
</div>
<div class="listings" lwc:dom="manual"></div>
</div>
<div class="map" lwc:dom="manual"></div>
</template>
I have searched a lot and included a thousand separator in tooltips. But I would like to make it work everywhere there is text. Where I live we use "." to separate thousands and "," for decimal.
I didn't find a simple way to put the title in the middle of the doughnut.
This is what I have:
Chart.defaults.global.defaultFontColor = '#7792b1';
var ctx = document.getElementById('myChart').getContext('2d');
var dataset = [{
label: 'Volume de Operações',
data: [254000.87, 355000.57],
backgroundColor: ['#4bb8df', '#6290df']
}]
var chart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: ['CALL', 'PUT'],
datasets: dataset
},
options: {
rotation: 1 * Math.PI,
circumference: 1 * Math.PI,
legend: {
display: false
},
cutoutPercentage: 60,
plugins: {
labels: [{
render: 'label',
arc: true,
fontStyle: 'bold',
position: 'outside'
}, {
render: 'percentage',
fontColor: '#ffffff',
precision: 1
}],
},
title: {
display: true,
fontSize: 15,
text: [
dataset.reduce((t, d) => t + d.data.reduce((a, b) => a + b), 0),
'Volume Total'
],
position: 'bottom'
},
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var dataLabel = data.labels[tooltipItem.index];
var value = ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index].toLocaleString();
if (Chart.helpers.isArray(dataLabel)) {
dataLabel = dataLabel.slice();
dataLabel[0] += value;
} else {
dataLabel += value;
}
return dataLabel;
}
}
}
}
});
<canvas id="myChart" style="max-width: 450px"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.8.0"></script>
<script src="https://cdn.jsdelivr.net/gh/emn178/chartjs-plugin-labels/src/chartjs-plugin-labels.js"></script>
In short:
Global thousand separator: (.)
Title in the middle of doughnut
Tooltip without label: Only value
To not show a title in your tooltip you will have to only return the value in your custom label calback. So your callback will become this:
label: function(tooltipItem, data) {
return data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index].toLocaleString();
}
There is no build in way to get the title in the middle of the circle, you will have to write a custom plugin for that.
To replace the thousand serperator in the percentage label, you will have to write a custom render. So instead render: 'percentage'. You will get something like this:
// custom render
{
render: function (args) {
// args will be something like:
// { label: 'Label', value: 123, percentage: 50, index: 0, dataset: {...} }
return '$' + args.value;
}
}
You will have to make the logic so the value gets transformed to a percentage still
EDIT custom tooltip so you dont see the color in front.
Chart.defaults.global.defaultFontColor = '#7792b1';
var ctx = document.getElementById('myChart').getContext('2d');
var dataset = [{
label: 'Volume de Operações',
data: [254000.87, 355000.57],
backgroundColor: ['#4bb8df', '#6290df']
}]
var chart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: ['CALL', 'PUT'],
datasets: dataset
},
options: {
rotation: 1 * Math.PI,
circumference: 1 * Math.PI,
legend: {
display: false
},
cutoutPercentage: 60,
plugins: {
labels: [{
render: 'label',
arc: true,
fontStyle: 'bold',
position: 'outside'
}, {
render: 'percentage',
fontColor: '#ffffff',
precision: 1
}],
},
title: {
display: true,
fontSize: 15,
text: [
dataset.reduce((t, d) => t + d.data.reduce((a, b) => a + b), 0),
'Volume Total'
],
position: 'bottom'
},
tooltips: {
enabled: false,
custom: function(tooltipModel) {
// Tooltip Element
var tooltipEl = document.getElementById('chartjs-tooltip');
// Create element on first render
if (!tooltipEl) {
tooltipEl = document.createElement('div');
tooltipEl.id = 'chartjs-tooltip';
tooltipEl.innerHTML = '<table></table>';
document.body.appendChild(tooltipEl);
}
// Hide if no tooltip
if (tooltipModel.opacity === 0) {
tooltipEl.style.opacity = 0;
return;
}
// Set caret Position
tooltipEl.classList.remove('above', 'below', 'no-transform');
if (tooltipModel.yAlign) {
tooltipEl.classList.add(tooltipModel.yAlign);
} else {
tooltipEl.classList.add('no-transform');
}
function getBody(bodyItem) {
return bodyItem.lines[0].split(': ')[1].replace('.', ',');
}
// Set Text
if (tooltipModel.body) {
var titleLines = tooltipModel.title || [];
var bodyLines = tooltipModel.body.map(getBody);
var innerHtml = '<thead>';
innerHtml += '</thead><tbody>';
bodyLines.forEach(function(body, i) {
var colors = tooltipModel.labelColors[i];
var style = 'background:' + colors.backgroundColor;
style += '; border-color:' + colors.borderColor;
style += '; border-width: 2px';
var span = '<span style="' + style + '"></span>';
innerHtml += '<tr><td>' + span + body + '</td></tr>';
});
innerHtml += '</tbody>';
var tableRoot = tooltipEl.querySelector('table');
tableRoot.innerHTML = innerHtml;
}
// `this` will be the overall tooltip
var position = this._chart.canvas.getBoundingClientRect();
// Display, position, and set styles for font
tooltipEl.style.opacity = 1;
tooltipEl.style.position = 'absolute';
tooltipEl.style.left = position.left + window.pageXOffset + tooltipModel.caretX + 'px';
tooltipEl.style.top = position.top + window.pageYOffset + tooltipModel.caretY + 'px';
tooltipEl.style.fontFamily = tooltipModel._bodyFontFamily;
tooltipEl.style.fontSize = tooltipModel.bodyFontSize + 'px';
tooltipEl.style.fontStyle = tooltipModel._bodyFontStyle;
tooltipEl.style.padding = tooltipModel.yPadding + 'px ' + tooltipModel.xPadding + 'px';
tooltipEl.style.pointerEvents = 'none';
}
/*
callbacks: {
label: function(tooltipItem, data) {
return data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index].toLocaleString();
},
}*/
}
}
});
#chartjs-tooltip {
opacity: 1;
position: absolute;
background: rgba(0, 0, 0, .7);
color: white;
border-radius: 3px;
-webkit-transition: all .1s ease;
transition: all .1s ease;
pointer-events: none;
-webkit-transform: translate(-50%, 0);
transform: translate(-50%, 0);
}
<canvas id="myChart" style="max-width: 450px"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.8.0"></script>
<script src="https://cdn.jsdelivr.net/gh/emn178/chartjs-plugin-labels/src/chartjs-plugin-labels.js"></script>
You might want to add some dots as thousand seperators in the tooltip but thats up to you. Best place to do it is in the getBody method.
I wanted to create a context menu on my line graph. When the user hovers across a point, they can right click and will see a context menu so that they can trigger more action.
Is this possible with chart.js?
Thanks,
Derek
AFAIK there is no native support for context menu from Chart.js, but you can create it using HTML and handle it.
This is an example:
var timestamp = [],
speed = [10, 100, 20, 30, 40, 100, 40, 60];
for (var k = speed.length; k--; k>0) {
timestamp.push(new Date().getTime()-60*60*1000*k);
}
var canvas = document.getElementById('chart');
var BB = canvas.getBoundingClientRect(),
offsetX = BB.left,
offsetY = BB.top;
var ctx = canvas.getContext("2d");
var data = {
labels: timestamp,
datasets: [{
data: speed,
label: "speed",
backgroundColor: ['rgba(0, 9, 132, 0.2)'],
borderColor: ['rgba(0, 0, 192, 1)'],
borderWidth: 1,
}
]
};
var options = {
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
}
}],
xAxes: [{
type: 'time',
}]
}
};
var chart = new Chart(ctx, {
type: 'line',
data: data,
options: options
});
var $menu = $('#contextMenu');
canvas.addEventListener('contextmenu', handleContextMenu, false);
canvas.addEventListener('mousedown', handleMouseDown, false);
function handleContextMenu(e){
e.preventDefault();
e.stopPropagation();
var x = parseInt(e.clientX-offsetX);
var y = parseInt(e.clientY-offsetY);
$menu.css({left:x,top:y});
$menu.show();
return(false);
}
function handleMouseDown(e){
$menu.hide();
}
menu = function(n){
console.log("select menu "+n);
$menu.hide();
}
#chart {
width: 100%;
height: 100%;
}
#contextMenu{
position:absolute;
border:1px solid red;
background:white;
list-style:none;
padding:3px;
}
.menu-item:hover {
background: #dddddd;
text-decoration: underline;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id=canvasContainer>
<canvas id="chart"></canvas>
<ul id="contextMenu" style="display:none;">
<li class="menu-item" onclick="menu(1)">Menu 1</li>
<li class="menu-item" onclick="menu(2)">Menu 2</li>
</ul>
</div>
For anyone looking for this, #beaver's answer does not have access to the clicked item (data point), you can save the state in onHover and use it in contextmenu.
options: {
events: ['click', 'mousemove'],
onHover: function(e, fields){
const lx = e.layerX;
const bars = fields.filter(({_view: {x,width}}) => (x - width/2) <= lx && lx <= (x + width/2));
const data = bars.map(({_index, _datasetIndex}) => this.data.datasets[_datasetIndex].data[_index]);
this.hoveredItem = {bars, data, fields};
},
},
plugins: [
{
afterInit: (chart) =>
{
var menu = document.getElementById("contextMenu");
chart.canvas.addEventListener('contextmenu', handleContextMenu, false);
chart.canvas.addEventListener('mousedown', handleMouseDown, false);
function handleContextMenu(e){
e.preventDefault();
e.stopPropagation();
menu.style.left = e.clientX + "px";
menu.style.top = e.clientY + "px";
menu.style.display = "block";
console.log(chart.hoveredItem);
return(false);
}
function handleMouseDown(e){
menu.style.display = "none";
}
}
}
],
https://codepen.io/elizzk/pen/xxZjQvJ
I have below Piechart using chartjs. I need to show a "No Data" message on it when there is nothing to show.
But I am unable to find such a way in chartjs tutorials. Can someone please help?
Pie Chart HTML
<div id="canvas-holder-CT" style="width:46%;float:right;position: absolute; left: 0px; top: 700px;">
<canvas id="chart-area-CT" width="350" height="450" style="display: block; margin-left:2em">
</canvas>
<center> <b><details>
<summary>Distribution by Call Types</summary>
</details> </b></center>
</div>
Pie chart script
var configCT = {
type : 'pie',
data : {
datasets : [{
data : valuesCT,
backgroundColor : coloringCT,
label : 'Distribution by Call Types'
}
],
labels : labelsCT
},
options : {
segmentShowStroke : false,
legend : false,
animateScale : true,
responsive : true,
showAllTooltips : false,
tooltips : {
custom : function (tooltip) {
if (!tooltip)
return;
tooltip.displayColors = false;
}
}
}
};
var ctxCT = document.getElementById("chart-area-CT").getContext("2d");
if (myPieCT != null) {
myPieCT.destroy();
}
myPieCT = new Chart(ctxCT, configCT);
Have you checked this open issue?
And the relative solution proposed by etimberg user:
Chart.plugins.register({
afterDraw: function(chart) {
if (chart.data.datasets.length === 0) {
// No data is present
var ctx = chart.chart.ctx;
var width = chart.chart.width;
var height = chart.chart.height
chart.clear();
ctx.save();
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.font = "16px normal 'Helvetica Nueue'";
ctx.fillText('No data to display', width / 2, height / 2);
ctx.restore();
}
}
});
See: https://jsfiddle.net/x04ptfuu/
Could be handle by CSS display property.
foo.html
<div id="showId" class="showData">
<canvas id="myChart"></canvas>
</div>
<div id="noId" class="noData">
<span>No Data Available</span>
<div>
foo.css
.showData {
display: block;
}
.noData {
display: none;
}
foo.js
// ...code
if(chartData) {
document.getElementById("showId").classList.add("showData");
document.getElementById("noId").classList.remove("noData");
} else {
document.getElementById("showId").classList.remove("showData");
document.getElementById("noId").classList.add("noData");
}
Looking through http://foundation.zurb.com/docs/components/section.html, is there anyway I can add horizontal scroll for Section headers ( Tabs) . I am looking something like http://www.seyfertdesign.com/jquery/ui.tabs.paging.html in foundation sections with horizontal scroll and continue to use accordion in small screen
I found a solution for those interested : https://codepen.io/gdyrrahitis/pen/BKyKGe
.tabs {
overflow-x: auto;
white-space: nowrap;
-webkit-overflow-scrolling: touch;
.tabs-title {
float: none;
display: inline-block;
}
}
if someone needs an angularjs with jquery implementation, below code can help you, for pure jquery replace angularjs directive method with a native js method with respective attributes.
I tried to search for similar implementation but found nothing, so I have written a simple angular directive which can transform a foundation CSS tabs to scrollable tabs
angular.module("app.directives.scrollingTabs", [])
.directive("scrollingTabs", ScrollingTabsDirective);
//#ngInject
function ScrollingTabsDirective($timeout, $window) {
return {
restrict: 'A',
link: function (scope, element, attr) {
if(attr.scrollingTabs == "true"){
element.addClass('scrolling-tabs-container');
element.find('.nav-buttons').remove();
element.append('<div class="scrolling-tabs nav-buttons nav-buttons-left"></div>');
element.append('<div class="scrolling-tabs nav-buttons nav-buttons-right"></div>');
let scrolledDiv = $(element).find('.tabs');
let scrolled;
let scrolling;
let scrollFn = (step, animationTime, cb) => {
scrolled = Math.max(scrolled + step, 0);
scrolledDiv.animate({
scrollLeft: scrolled
}, animationTime, ()=>{
if (scrolling) {
scrollFn(step, animationTime, cb)
}else{
if(cb){cb()}
}
});
};
let checkActiveNavButtonsClasses = () => {
scrolled = scrolledDiv.scrollLeft();
let scrollWidth = scrolledDiv.get(0).scrollWidth;
let scrolledDivWidth = scrolledDiv.get(0).clientWidth;
if(scrollWidth > scrolledDivWidth){
element.addClass('nav-active');
scrollWidth = scrolledDiv.get(0).scrollWidth;
if(scrolled == 0){
element.removeClass('nav-active-left').addClass('nav-active-right')
}else if(scrolled > 0 && scrolled + scrollWidth < scrolledDivWidth){
element.addClass('nav-active-left').addClass('nav-active-right');
}else if(scrolled > 0 && scrolled + scrollWidth >= scrolledDivWidth){
element.addClass('nav-active-left').removeClass('nav-active-right');
}else{
element.removeClass('nav-active-left').removeClass('nav-active-right')
}
}else{
element.removeClass('nav-active-left').removeClass('nav-active-right').removeClass('nav-active');
}
};
let scrollToActiveTab = () => {
let activeDD = scrolledDiv.find('dd.active');
let tabsOffset = scrolledDiv.offset();
let activeTaboffset = activeDD.offset();
let activeTabwidth = activeDD.width();
let scrolledStep = activeTaboffset.left - tabsOffset.left - scrolledDiv.width() + activeTabwidth;
scrollFn(scrolledStep, 100, checkActiveNavButtonsClasses);
};
element.find(".nav-buttons.nav-buttons-left")
.off("click.scrolling")
.on("click.scrolling", (event)=>{
event.preventDefault();
scrolling = false;
scrollFn(-100, 100, checkActiveNavButtonsClasses);
})
.off("mouseover.scrolling")
.on("mouseover.scrolling", function (event) {
scrolling = true;
scrollFn(-2, 1, checkActiveNavButtonsClasses);
})
.off("mouseout.scrolling")
.on("mouseout.scrolling", function (event) {
scrolling = false;
});
element.find(".nav-buttons.nav-buttons-right")
.off("click.scrolling")
.on("click.scrolling", (event)=>{
event.preventDefault();
scrolling = false;
scrollFn(100, 100, checkActiveNavButtonsClasses);
})
.off("mouseover.scrolling")
.on("mouseover.scrolling", function (event) {
scrolling = true;
scrollFn(2, 1, checkActiveNavButtonsClasses);
})
.off("mouseout.scrolling")
.on("mouseout.scrolling", function (event) {
scrolling = false;
});
$timeout(()=>{
checkActiveNavButtonsClasses();
scrollToActiveTab()
},1000);
$($window).off('resize.scrolling').on('resize.scrolling', _.debounce(()=> {
checkActiveNavButtonsClasses();
}, 500));
scope.$on('$destroy', function() {
$($window).off('resize.scrolling');
});
}
}
}}
css:
.scrolling-tabs-container {
position: relative;
.tabs {
overflow-x: hidden;
white-space: nowrap;
-webkit-overflow-scrolling: touch;
display: block;
margin-right: 18px;
dd {
display: inline-block;
float: none;
margin: 0px -3px 0px 0px;
}
.tabs-title {
float: none;
display: inline-block;
}
}
.scrolling-tabs {
&.nav-buttons {
display: none;
position: absolute;
width: 19px;
height: 38px;
border: 1px solid #c1c1c1;
top: 1px;
background-color: rgba(255, 255, 255, 0.5);
opacity: 0.4;
cursor: pointer;
&:hover {
opacity: 1;
&:before {
color: #444;
}
}
&:before {
position: absolute;
left: 7px;
top: 8px;
color: #777;
}
&.nav-buttons-left {
left: 0;
&:before {
content: '<';
}
}
&.nav-buttons-right {
right: 18px;
&:before {
content: '>';
}
}
}
}
&.nav-active{
.tabs{
margin-right: 36px;
margin-left: 18px;
}
.scrolling-tabs {
&.nav-buttons {
display: inline-block !important;
}
}
}
&.nav-active-left{
.scrolling-tabs{
&.nav-buttons-left{
opacity: 0.8;
}
}
}
&.nav-active-right{
.scrolling-tabs{
&.nav-buttons-right{
opacity: 0.8;
}
}}}
HTML: Foundation Tabs template.
<tabset class="list-tabs" scrolling-tabs="true">
<tab heading="tab1"></tab>
<tab heading="tab2"></tab>
<tab heading="tab2"></tab>
</tabset>
Before you start you'll want to verify that both jQuery (or Zepto) and foundation.js are available on your page. These come with foundation package so just uncomment them in your footer or include them accordingly.
<div class="section-container auto" data-section>
<section class="active">
<p class="title" data-section-title>Section 1</p>
<div class="content" data-section-content>
<p>Content of section 1.</p>
</div>
</section>
<section>
<p class="title" data-section-title>Section 2</p>
<div class="content" data-section-content>
<p>Content of section 2.</p>
</div>
</section>
</div>
The foundation documentation has all of the information for this :
http://foundation.zurb.com/docs/components/section.html#panel2
This will get you your section tabular headers. You then want to manage the content to be scrollable.
<div class="content" data-section-content>
<p>Content of section 1.</p>
</div>
This content here will be the area to work on, try adding a new class called .scrollable
Within this class use something like:
.scrollable{
overflow:scroll;
}
You may want to add some more to this however this will get you started. Your HTML should now look like this :
<div class="content scrollable" data-section-content>
<p>Content of section 1. This content will be scrollable when the content has exceeded that of the div size. </p>
</div>
This this is what you are looking for.