How do i stop iterating tough this array at "pgn[46]"?
I want to be unable to go to the next move when i click the button. because this array will start back from 0 and if a piece is on the square it will move again. i need some more text to post this question here. I love you all, peace
$('#move1Btn').on('click', function () {
board.move(pgn[intpgnIndex])
})
var pgn = new Array()
pgn[0] = ""
pgn[1] = "e2-e4"
pgn[2] = "e7-e5"
pgn[3] = "f2-f4"
pgn[4] = "e5-f4"
pgn[5] = "f1-c4"
pgn[6] = "d8-h4"
pgn[7] = "e1-f1"
pgn[8] = "b7-b5"
pgn[9] = "c4-b5"
pgn[10] = "g8-f6"
pgn[11] = "g1-f3"
pgn[12] = "h4-h6"
pgn[13] = "d2-d3"
pgn[14] = "f6-h5"
pgn[15] = "f3-h4"
pgn[16] = "h6-g5"
pgn[17] = "h4-f5"
pgn[18] = "c7-c6"
pgn[19] = "g2-g4"
pgn[20] = "h5-f6"
pgn[21] = "h1-g1"
pgn[22] = "c6-b5"
pgn[23] = "h2-h4"
pgn[24] = "g5-g6"
pgn[25] = "h4-h5"
pgn[26] = "g6-g5"
pgn[27] = "d1-f3"
pgn[28] = "f6-g8"
pgn[29] = "c1-f4"
pgn[30] = "g5-f6"
pgn[31] = "b1-c3"
pgn[32] = "f8-c5"
pgn[33] = "c3-d5"
pgn[34] = "f6-b2"
pgn[35] = "f4-d6"
pgn[36] = "c5-g1"
pgn[37] = "e4-e5"
pgn[38] = "b2-a1"
pgn[39] = "f1-e2"
pgn[40] = "b8-a6"
pgn[41] = "f5-g7"
pgn[42] = "e8-d8"
pgn[43] = "f3-f6"
pgn[44] = "g8-f6"
pgn[45] = "d6-e7"
pgn[46] = ""
pgn[47] = ""
pgn[48] = ""
pgn[49] = ""
var intpgnIndex = 0;
function writeThing() {
if ( intpgnIndex == pgn.length ) intpgnIndex = 0;
intpgnIndex++;
}
I would check the value at the index and see if it is an empty string:
$('#move1Btn').on('click', function () {
var move = pgn[intpgnIndex];
if (move) {
board.move(move);
}
})
Here is a recommended approach:
const initialState = [
{ color: 'black', type: 'king', cells: ['e8'] },
{ color: 'black', type: 'queen', cells: ['d8'] },
{ color: 'black', type: 'rook', cells: ['a8', 'h8'] },
{ color: 'black', type: 'bishop', cells: ['c8', 'f8'] },
{ color: 'black', type: 'knight', cells: ['b8', 'g8'] },
{ color: 'black', type: 'pawn', cells: ['a7', 'b7', 'c7', 'd7', 'e7', 'f7', 'g7', 'h7'] },
{ color: 'white', type: 'king', cells: ['e1'] },
{ color: 'white', type: 'queen', cells: ['d1'] },
{ color: 'white', type: 'rook', cells: ['a1', 'h1'] },
{ color: 'white', type: 'bishop', cells: ['c1', 'f1'] },
{ color: 'white', type: 'knight', cells: ['b1', 'g1'] },
{ color: 'white', type: 'pawn', cells: ['a2', 'b2', 'c2', 'd2', 'e2', 'f2', 'g2', 'h2'] },
];
const moveList = ['e2-e4', 'e7-e5', 'f2-f4', 'e5-f4', 'f1-c4', 'd8-h4', 'e1-f1', 'b7-b5', 'c4-b5', 'g8-f6', 'g1-f3', 'h4-h6', 'd2-d3', 'f6-h5', 'f3-h4', 'h6-g5', 'h4-f5', 'c7-c6', 'g2-g4', 'h5-f6', 'h1-g1', 'c6-b5', 'h2-h4', 'g5-g6', 'h4-h5', 'g6-g5', 'd1-f3', 'f6-g8', 'c1-f4', 'g5-f6', 'b1-c3', 'f8-c5', 'c3-d5', 'f6-b2', 'f4-d6', 'c5-g1', 'e4-e5', 'b2-a1', 'f1-e2', 'b8-a6', 'f5-g7', 'e8-d8', 'f3-f6', 'g8-f6', 'd6-e7'];
const
$board = $('.chess-board'),
$moveInfo = $('.move-info');
let currentIndex = 0;
const currentPlayer = () => currentIndex % 2 === 0 ? 'white' : 'black';
const generateBoard = () => {
for (let i = 0; i < 100; i++) {
const
row = Math.floor(i / 10),
col = i % 10,
isOdd = ((row % 2 === 1) ^ (col % 2 === 0)) === 0,
$cell = $('<div>', { class: 'cell' });
if (row === 0 || row === 9) {
$cell.addClass('boundry');
if (col > 0 && col < 9) {
$cell.attr('data-index', String.fromCharCode(97 + col - 1));
}
} else if (col === 0 || col === 9) {
$cell.addClass('boundry');
if (row > 0 && row < 9) {
$cell.attr('data-index', 9 - row);
}
} else {
const
dr = 10 - row - 1, dc = String.fromCharCode(97 + col - 1),
code = `${dc}${dr}`;
$cell.attr('data-code', code).toggleClass('is-odd', isOdd);
}
$board.append($cell);
}
};
const initializePieces = () => {
initialState.forEach(({ color, type, cells }) => {
cells.forEach(code => {
$board
.find(`.cell[data-code="${code}"]`)
.attr('data-type', type)
.attr('data-color', color);
});
});
};
const resetBoard = () => {
currentIndex = 0;
$board.find('.cell')
.removeAttr('data-color')
.removeAttr('data-type');
initializePieces();
$moveInfo.find('[data-move-index]').text('');
$moveInfo.find('[data-move-value]').text('');
$moveInfo.find('[data-move-atk-color]').text('');
$moveInfo.find('[data-move-atk-type]').text('');
$moveInfo.find('[data-move-def-color]').text('');
$moveInfo.find('[data-move-def-type]').text('');
};
const nextMove = () => {
let move = moveList[currentIndex];
if (!move) {
alert('No more moves, reseting...');
resetBoard();
return;
}
const [from, to] = move.split('-');
const $prev = $board.find(`.cell[data-code="${from}"]`);
const $curr = $board.find(`.cell[data-code="${to}"]`);
const atkColor = $prev.attr('data-color');
const atkType = $prev.attr('data-type');
const defColor = $curr.attr('data-color') || '';
const defType = $curr.attr('data-type') || '';
$moveInfo.find('[data-move-index]').text(currentIndex + 1);
$moveInfo.find('[data-move-value]').text(move);
$moveInfo.find('[data-move-atk-color]').text(atkColor);
$moveInfo.find('[data-move-atk-type]').text(atkType);
$moveInfo.find('[data-move-def-color]').text(defColor);
$moveInfo.find('[data-move-def-type]').text(defType);
$prev.removeAttr('data-color').removeAttr('data-type');
$curr.attr('data-color', atkColor).attr('data-type', atkType);
currentIndex++;
};
generateBoard();
initializePieces();
$('#move-btn').on('click', nextMove);
*, *::before, *::after {
box-sizing: border-box;
}
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
body {
display: flex;
align-items: center;
justify-content: center;
gap: 1em;
background: #222;
}
.chess-board {
display: grid;
grid-template-columns: repeat(10, auto);
border: thin solid LightYellow;
}
.cell {
width: 16px;
height: 16px;
font-size: 1rem;
display: flex;
align-items: center;
justify-content: center;
background: LightYellow;
}
.cell.is-odd {
background: LightSalmon;
}
.cell.is-active {
color: green;
}
.cell[data-color="white"] { color: FireBrick }
.cell[data-color="black"] { color: FireBrick }
.cell[data-color="white"][data-type="king"]:after { content: "\2654" }
.cell[data-color="white"][data-type="queen"]:after { content: "\2655" }
.cell[data-color="white"][data-type="rook"]:after { content: "\2656" }
.cell[data-color="white"][data-type="bishop"]:after { content: "\2657" }
.cell[data-color="white"][data-type="knight"]:after { content: "\2658" }
.cell[data-color="white"][data-type="pawn"]:after { content: "\2659" }
.cell[data-color="black"][data-type="king"]:after { content: "\265A" }
.cell[data-color="black"][data-type="queen"]:after { content: "\265B" }
.cell[data-color="black"][data-type="rook"]:after { content: "\265C" }
.cell[data-color="black"][data-type="bishop"]:after { content: "\265D" }
.cell[data-color="black"][data-type="knight"]:after { content: "\265E" }
.cell[data-color="black"][data-type="pawn"]:after { content: "\265F" }
.cell[data-index]:after { content: attr(data-index); }
.cell.boundry { background: FireBrick; color: LightYellow; font-size: smaller; }
.sidebar {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 0.5rem;
min-width: 10rem;
border: thin solid FireBrick;
padding: 0.5rem;
background: LightYellow;
}
.move-info {
display: grid;
grid-template-columns: repeat(2, auto);
gap: 0.25rem;
font-family: monospace;
font-size: smaller;
text-transform: uppercase;
}
.move-info strong { text-align: right; }
.move-info strong:after { content: ":"; }
.move-info .details { display: flex; gap: 0.25rem; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="chess-board"></div>
<div class="sidebar">
<div class="move-info">
<strong>Move</strong>
<div class="details">
<span data-move-index></span>
<span data-move-value></span>
</div>
<strong>Attacker</strong>
<div class="details">
<span data-move-atk-color></span>
<span data-move-atk-type></span>
</div>
<strong>Defender</strong>
<div class="details">
<span data-move-def-color></span>
<span data-move-def-type></span>
</div>
</div>
<button id="move-btn">Next</button>
</div>
Related
I want to implement a chart like below.
But my problem is collision of the numbers in this chart and I couldn't find a suitable solution for this. For example when two or three values are very close together, the collision happens. (the image below)
<template>
<div style="width: 100%">
<div class="box" style="width: 100%">
<div :style="{ left: `${bound1.spaceLeft}%` }" class="box__q1-line" />
<div :style="{ left: `${bound2.spaceLeft}%` }" class="box__q2-line" />
<div :style="{ width: `${theValue.width}%` }" class="box__value" />
</div>
<div class="box__values-container">
<div
v-for="(item, i) in sorted"
:key="i"
class="box__amount"
:style="{ left: `${item.spaceLeft}%` }"
>
{{ item.realValue }}
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, ref, watch } from "#vue/composition-api";
function round(number: number) {
return Math.floor(number * 1000) / 1000;
}
export default defineComponent({
setup(props) {
const bound1 = ref({
realValue: 0,
spaceLeft: 0,
});
const bound2 = ref({
realValue: 0,
spaceLeft: 0,
});
const theValue = ref({
realValue: 0,
spaceLeft: 0,
width: 0,
});
const eachWidth = 6;
type ChartData = { realValue: number; spaceLeft: number };
const sorted = ref<Array<ChartData>>();
function compare(obj1: ChartData, obj2: ChartData) {
if (obj1.spaceLeft < obj2.spaceLeft) return -1;
if (obj1.spaceLeft > obj2.spaceLeft) return 1;
return 0;
}
watch(
props,
() => {
bound1.value.realValue = props.q1!;
bound2.value.realValue = props.q2!;
theValue.value.realValue = props.value!;
bound1.value.spaceLeft = round((props.q1! / props.max!) * 100);
bound2.value.spaceLeft = round((props.q2! / props.max!) * 100);
theValue.value.spaceLeft = round((props.value! / props.max!) * 100);
theValue.value.width = round((props.value! / props.max!) * 100);
sorted.value = [bound1.value, bound2.value, theValue.value].sort(
compare
);
if (
sorted.value[1].spaceLeft + eachWidth >
sorted.value[2].spaceLeft
) {
sorted.value[1].spaceLeft = sorted.value[2].spaceLeft - eachWidth;
}
if (
sorted.value[0].spaceLeft + eachWidth >
sorted.value[1].spaceLeft
) {
sorted.value[0].spaceLeft = sorted.value[1].spaceLeft - eachWidth;
}
if (theValue.value.width < 0) theValue.value.width = 3;
if (bound1.value.spaceLeft < 0) bound1.value.spaceLeft = 3;
if (bound2.value.spaceLeft < 0) bound2.value.spaceLeft = 3;
},
{ deep: true, immediate: true }
);
return {
bound1,
bound2,
theValue,
sorted,
};
},
props: {
q1: {
type: Number,
},
q2: {
type: Number,
},
max: {
type: Number,
},
value: {
type: Number,
},
},
});
</script>
<style>
.box {
width: 100%;
height: 50px;
position: relative;
border-radius: 5px;
border: 2px solid #fff;
background: #b8d0de;
overflow: hidden;
}
.box__q1-line,
.box__q2-line {
position: absolute;
width: 2px;
background: #fff;
height: 100%;
}
.box__value {
background: #3c8dbc;
height: 100%;
}
.box__amount {
position: absolute;
width: 60px;
bottom: -25px;
}
.box__values-container {
position: relative;
}
</style>
I considered two thin divs with absolute position for the two lines and I set the left property of them according to their values and another div for the amount and I set the width of it according to its value.
I have a problem
When i move a item on another slot, the item will block, and can't be moved.
Code:
$(function() {
function log(string) {
console.log(Date.now(), string);
}
function makeGrid() {
log("Make Grid...");
for (var i = 0; i < 36; i++) {
$("<div>", {
class: "slot"
}).data({
count: 0,
stackable: true
}).appendTo(".slots");
}
log("-* Grid Complete *-");
}
function makeDraggable(target) {
log("Make Drag, Current Class: " + $(target).attr("class"));
console.log(target);
$(target).draggable({
scroll: false,
helper: "clone",
cursor: "pointer",
zIndex: 27,
revert: "invalid"
});
log("After Make Drag, Current Class: " + $(target).attr("class"));
console.log(target);
}
function refreshSlot(target) {
log("Refresh Slot");
$(".size", target).html($(target).data("count"));
}
function addItem(slot, item) {
log("Add Item " + item.id);
$.extend(item, {
stackable: (item.category != 0),
count: (item.count == undefined ? 1 : item.count)
});
slot = $(slot);
var newItem = $("<div>", {
class: "item",
id: item.id,
})
.data(item)
.css("background-image", "url(" + item.img + ")");
newItem.appendTo(slot);
$("<div>", {
class: "size"
}).appendTo(slot);
slot.data({
count: item.count,
stackable: item.stackable
});
log("Item Added - Refreshing");
refreshSlot(slot);
}
function emptySlot(target) {
log("Empty Slot " + $(target).index());
$(target).data({
count: 0,
stackable: true
}).empty();
}
function loadPlayerItems(items) {
log("Loading Player Items...");
$.each(items, function(index, item) {
addItem($(".slots > .slot").eq(index), item);
});
log("-* Loading Complete *-");
}
function isAcceptable(item) {
if ($(this).children().length == 0 || $(".item", this).data("stackable")) {
return true;
}
return false;
}
var pItems = {
playerItems: [{
img: 'https://i.imgur.com/5cjSI9X.png',
name: 'bat',
id: 1,
category: 0
},
{
img: 'https://i.imgur.com/HLQORBk.png',
name: 'axe',
id: 2,
category: 1
},
{
img: 'https://i.imgur.com/HLQORBk.png',
name: 'axe',
id: 3,
category: 1
}
]
};
makeGrid();
loadPlayerItems(pItems.playerItems);
makeDraggable(".item");
$(".slots > .slot").droppable({
accept: isAcceptable,
drop: function(event, ui) {
var origin = ui.draggable.parent();
var target = $(this);
log("Drop Accepted; From: " + origin.index() + ", To: " + target.index());
// Increase the Count
target.data("count", target.data("count") + 1);
// Check for Stack
if (target.children().length == 0) {
addItem(target, ui.draggable.data());
} else {
refreshSlot(target);
}
// Check Orginal Stack
if (origin.data("count") > 1) {
origin.data("count", origin.data("count") - 1);
refreshSlot(origin);
} else {
emptySlot(origin);
}
makeDraggable($(".item", this));
}
});
});
body {
display: flex;
justify-content: space-between;
}
#inventory {
width: 100vw;
height: 56.25vw;
background: rgba(0,0,0,.5);
}
.list-slots {
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0,0,0,.7);
width: 41.667vw;
height: 41.667vw;
max-width: 80%;
}
.slots {
max-width: 87%;
margin: auto;
padding-top: 3.125vw;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.slots .slot {
width: 100px;
height: calc(100px + 1em);
background-color: #ccc;
margin-bottom: 0.781vw;
}
.slots .slot .item {
background-repeat: no-repeat;
width: 100px;
height: 100px;
}
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div id="inventory">
<div class="list-slots">
<div class="slots"></div>
</div>
</div>
I was trying to add two legends containers for the same graph(sunburst drill-down). one on the left side and another on the right side of the graph.
After lots of research, I found the solution but it was for piechart not for sunburst drill down. I want the same solution for sunburst drill down.
Below is the Image of the solution which I found.
enter image description here
code for above image:
Js, CSS, HTML
/**
* ---------------------------------------
* This demo was created using amCharts 4.
*
* For more information visit:
* https://www.amcharts.com/
*
* Documentation is available at:
* https://www.amcharts.com/docs/v4/
* ---------------------------------------
*/
am4core.useTheme(am4themes_animated);
// Create chart instance
var chart = am4core.create("chartdiv", am4charts.PieChart);
// Add data
chart.data =
[{
"country": "Lithuania",
"litres": 501.9
}, {
"country": "Czechia",
"litres": 301.9
}, {
"country": "Ireland",
"litres": 201.1
}, {
"country": "Germany",
"litres": 165.8
}, {
"country": "Australia",
"litres": 139.9
}, {
"country": "Austria",
"litres": 128.3
}, {
"country": "UK",
"litres": 99
}, {
"country": "Belgium",
"litres": 60
}, {
"country": "The Netherlands",
"litres": 50
}];
// Add and configure Series
var pieSeries = chart.series.push(new am4charts.PieSeries());
pieSeries.dataFields.value = "litres";
pieSeries.dataFields.category = "country";
pieSeries.labels.template.disabled = true;
radius = am4core.percent(95);
chart.legend = new am4charts.Legend();
chart.legend.position = "left";
chart.legend.scrollable = true;
// Create custom legend
chart.events.on("ready", function(event) {
// populate our custom legend when chart renders
chart.customLegend = document.getElementById('legend');
pieSeries.dataItems.each(function(row, i) {
var color = chart.colors.getIndex(i);
var percent = Math.round(row.values.value.percent * 100) / 100;
var value = row.value;
legend.innerHTML += '<div class="legend-item" id="legend-item-' + i + '" onclick="toggleSlice(' + i + ');" onmouseover="hoverSlice(' + i + ');" onmouseout="blurSlice(' + i + ');" style="color: ' + color + ';"><div class="legend-marker" style="background: ' + color + '"></div>' + row.category + '<div class="legend-value">' + value + ' | ' + percent + '%</div></div>';
});
});
function toggleSlice(item) {
var slice = pieSeries.dataItems.getIndex(item);
if (slice.visible) {
slice.hide();
}
else {
slice.show();
}
}
function hoverSlice(item) {
var slice = pieSeries.slices.getIndex(item);
slice.isHover = true;
}
function blurSlice(item) {
var slice = pieSeries.slices.getIndex(item);
slice.isHover = false;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}
#chartdiv {
width: 530px;
height: 450px;
font-size: 11px;
border: 1px solid #eee;
float: left;
}
#legend {
width: 200px;
height: 450px;
border: 1px solid #eee;
margin-left: 10px;
float: left;
}
#legend .legend-item {
margin: 10px;
font-size: 15px;
font-weight: bold;
cursor: pointer;
}
#legend .legend-item .legend-value {
font-size: 12px;
font-weight: normal;
margin-left: 22px;
}
#legend .legend-item .legend-marker {
display: inline-block;
width: 12px;
height: 12px;
border: 1px solid #ccc;
margin-right: 10px;
}
#legend .legend-item.disabled .legend-marker {
opacity: 0.5;
background: #ddd;
}
<script src="https://cdn.amcharts.com/lib/4/core.js"></script>
<script src="https://cdn.amcharts.com/lib/4/charts.js"></script>
<script src="https://cdn.amcharts.com/lib/4/themes/animated.js"></script>
<div id="chartdiv"></div>
<div id="legend"></div>
I tried to solve my problem with the above solution but it didn't work.
Below are the details for my changes :
enter image description here
/**
* ---------------------------------------
* This demo was created using amCharts 4.
*
* For more information visit:
* https://www.amcharts.com/
*
* Documentation is available at:
* https://www.amcharts.com/docs/v4/
* ---------------------------------------
*/
// Themes begin
am4core.useTheme(am4themes_animated);
// Themes end
// create chart
var chart = am4core.create("chartdiv", am4plugins_sunburst.Sunburst);
chart.padding(0, 0, 0, 0);
chart.radius = am4core.percent(98);
data1 = [{
name: "First",
children: [
{ name: "A1", value: 100 },
{ name: "A2", value: 60 }
]
},
{
name: "Second",
children: [
{ name: "B1", value: 135 },
{ name: "B2", value: 98 }
]
},
{
name: "Third",
children: [
{
name: "C1",
children: [
{ name: "EE1", value: 130 },
{ name: "EE2", value: 87 },
{ name: "EE3", value: 55 }
]
},
{ name: "C2", value: 148 },
{
name: "C3", children: [
{ name: "CC1", value: 53 },
{ name: "CC2", value: 30 }
]
},
{ name: "C4", value: 26 }
]
},
{
name: "Fourth",
children: [
{ name: "D1", value: 415 },
{ name: "D2", value: 148 },
{ name: "D3", value: 89 }
]
},
{
name: "Fifth",
children: [
{
name: "E1",
children: [
{ name: "EE1", value: 33 },
{ name: "EE2", value: 40 },
{ name: "EE3", value: 89 }
]
},
{
name: "E2",
value: 148
}
]
}];
let dt1 = [];
for(var i=0;i<data1.length;i++){
dt1[i] = {"name":data1[i].name,"fill":"#72A6B2"};
}
chart.data = data1;
chart.colors.step = 2;
chart.fontSize = 11;
chart.innerRadius = am4core.percent(20);
// define data fields
chart.dataFields.value = "value";
chart.dataFields.name = "name";
chart.dataFields.children = "children";
var level0SeriesTemplate = new am4plugins_sunburst.SunburstSeries();
chart.seriesTemplates.setKey("0", level0SeriesTemplate)
// this makes labels to be hidden if they don't fit
level0SeriesTemplate.labels.template.truncate = true;
level0SeriesTemplate.labels.template.hideOversized = true;
level0SeriesTemplate.showOnInit = false;
level0SeriesTemplate.usePercentHack = false;
level0SeriesTemplate.radius = am4core.percent(100);
level0SeriesTemplate.innerRadius = am4core.percent(0);
let selectedState = level0SeriesTemplate.states.create("selected");
selectedState.properties.opacity = 0.7;
level0SeriesTemplate.defaultState.properties.radius = am4core.percent(100);
var currentlySelected;
level0SeriesTemplate.slices.template.events.on("over", function(event) {
if(event.target.dataItem.sunburstDataItem.children){
event.target.cursorOverStyle = am4core.MouseCursorStyle.pointer;
}
})
level0SeriesTemplate.slices.template.events.on("hit", function(event) {
zoomOutButton.show();
var hitSlice = event.target;
if (hitSlice.dataItem.sunburstDataItem.children) {
var series = event.target.dataItem.component;
if (!series.dummyData) {
series.tooltip.disabled = true;
hitSlice.dataItem.label.radius = (hitSlice.radius - hitSlice.pixelInnerRadius) - 7;
hitSlice.dataItem.label.bent = true;
hitSlice.dataItem.label.rotation = -180;
currentlySelected = hitSlice;
series.dummyData = true;
series.setState("selected");
hitSlice.dataItem.sunburstDataItem.series.show();
series.slices.each(function(slice) {
if (slice != event.target) {
slice.dataItem.hide();
}
})
}
else {
drillUp(hitSlice);
}
}
})
level0SeriesTemplate.labels.template.adapter.add("rotation", function(rotation, target) {
target.maxWidth = target.dataItem.slice.radius - target.dataItem.slice.innerRadius - 10;
target.maxHeight = Math.abs(target.dataItem.slice.arc * (target.dataItem.slice.innerRadius + target.dataItem.slice.radius) / 2 * am4core.math.RADIANS);
return rotation;
})
var level1SeriesTemplate = level0SeriesTemplate.clone();
level1SeriesTemplate.hidden = true;
level1SeriesTemplate.innerRadius = am4core.percent(10);
chart.seriesTemplates.setKey("1", level1SeriesTemplate)
level1SeriesTemplate.fillOpacity = 0.75;
var level2SeriesTemplate = level0SeriesTemplate.clone();
level2SeriesTemplate.hidden = true;
level2SeriesTemplate.innerRadius = am4core.percent(20);
chart.seriesTemplates.setKey("2", level2SeriesTemplate)
level0SeriesTemplate.hiddenInLegend = false;
level1SeriesTemplate.hiddenInLegend = true;
level2SeriesTemplate.hiddenInLegend = true;
var zoomOutButton = chart.seriesContainer.createChild(am4core.ZoomOutButton);
zoomOutButton.visible = false;
zoomOutButton.horizontalCenter = "middle";
zoomOutButton.verticalCenter = "middle";
zoomOutButton.events.on("hit", function() {
drillUp(currentlySelected)
})
function drillUp(slice) {
collapse(slice);
var series = slice.dataItem.component;
series.tooltip.disabled = false;
series.dummyData = false;
series.setState("default");
series.slices.each(function(slice) {
if (slice != event.target) {
slice.dataItem.show();
}
})
if (series.parentDataItem.seriesDataItem) {
currentlySelected = series.parentDataItem.seriesDataItem.slice;
}
else {
zoomOutButton.hide();
}
}
function collapse(slice) {
slice.dataItem.label.bent = false;
slice.dataItem.label.radius = 10;
if (slice.dataItem.sunburstDataItem.children) {
slice.dataItem.sunburstDataItem.children.each(function(child) {
child.seriesDataItem.component.setState("hidden");
collapse(child.seriesDataItem.slice);
})
}
}
/* var legend = new am4charts.Legend();
legend.position = "right";
legend.scrollable = true;
legend.parent = chart.chartContainer;
legend.background.fill = am4core.color("#000");
legend.background.fillOpacity = 0.05;
legend.width = 120;
legend.align = "right";
legend.data = dt1; */
/*
[{
"name": "2016",
"fill":"#72A6B2"
}, {
"name": "2017",
"fill": "#667E93"
}, {
"name": "2018",
"fill": "#488BB2"
}];*/
chart.legend = new am4charts.Legend();
//chart.legend.parent = chart.chartContainer;
//chart.legend.itemContainers.template.togglable = true;
chart.legend.position = "left";
chart.legend.scrollable = true;
// Create custom legend
chart.events.on("ready", function(event) {
// populate our custom legend when chart renders
chart.customLegend = document.getElementById('legend');
/* level0SeriesTemplate.slices.dataItems.each(function(row, i) { */
level0SeriesTemplate.dataItems.each(function(row, i) {
var color = chart.colors.getIndex(i);
var percent = Math.round(row.values.value.percent * 100) / 100;
var value = row.value;
legend.innerHTML += '<div class="legend-item" id="legend-item-' + i + '" onclick="toggleSlice(' + i + ');" onmouseover="hoverSlice(' + i + ');" onmouseout="blurSlice(' + i + ');" style="color: ' + color + ';"><div class="legend-marker" style="background: ' + color + '"></div>' + row.name + '<div class="legend-value">' + value + ' | ' + percent + '%</div></div>';
});
});
function toggleSlice(item) {
var slice = level0SeriesTemplate.dataItems.getIndex(item);
if (slice.visible) {
slice.hide();
}
else {
slice.show();
}
}
function hoverSlice(item) {
var slice = level0SeriesTemplate.slices.getIndex(item);
slice.isHover = true;
}
function blurSlice(item) {
var slice = level0SeriesTemplate.slices.getIndex(item);
slice.isHover = false;
}
/* var legendContainer = am4core.create("legend", am4core.Container);
legendContainer.width = am4core.percent(100);
legendContainer.height = am4core.percent(100);
legend = new am4charts.Legend();
legend.parent = legendContainer;
legend.position = "middle";
legend.valign = "middle";
legend.data = dt1;
legend.scrollable = true;
let Label1 = legendContainer.createChild(am4core.Label);
//Label1.height = 50;
Label1.fontWeight = "600";
Label1.align = "left";
Label1.paddingTop = 6;
Label1.paddingBottom = 6;
Label1.text = "Non-Reco Analytics"; */
/*
chart.legend.data = [{
"name": "2016",
"fill":"#72A6B2"
}, {
"name": "2017",
"fill": "#667E93"
}, {
"name": "2018",
"fill": "#488BB2"
}]; */
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}
#chartdiv {
width: 530px;
height: 450px;
font-size: 11px;
border: 1px solid #eee;
float: left;
}
#legend {
width: 200px;
height: 450px;
border: 1px solid #eee;
margin-left: 10px;
float: left;
}
#legend .legend-item {
margin: 10px;
font-size: 15px;
font-weight: bold;
cursor: pointer;
}
#legend .legend-item .legend-value {
font-size: 12px;
font-weight: normal;
margin-left: 22px;
}
#legend .legend-item .legend-marker {
display: inline-block;
width: 12px;
height: 12px;
border: 1px solid #ccc;
margin-right: 10px;
}
#legend .legend-item.disabled .legend-marker {
opacity: 0.5;
background: #ddd;
}
<script src="https://cdn.amcharts.com/lib/4/core.js"></script>
<script src="https://cdn.amcharts.com/lib/4/charts.js"></script>
<script src="https://cdn.amcharts.com/lib/4/plugins/sunburst.js"></script>
<script src="https://cdn.amcharts.com/lib/4/themes/animated.js"></script>
<div id="chartdiv"></div>
<div id="legend"></div>
objective: I want legends for the 1st layer of the sunburst on the right side and the 2nd layer on the left side of the chart.
I hope you get enough understanding of my problem.
I'm trying to build a carousel in JS that uses an array to store my data.
I want my box on the left to show the value for "Client" and the box on the right to show the value for "Candidate".
I can't seem to get it working despite what I believe is all correct?
let testimonials = [{
client: "Raphel",
candidate: "male"
},
{
client: "Tom",
candidate: "male"
},
{
client: "Jerry",
candidate: "male"
},
{
client: "Dorry",
candidate: "female"
}
];
var i = 0;
function nextItem() {
i = i + 1;
i = i % testimonials.length;
return testimonials[i].candidate;
}
function prevItem() {
if (i === 0) {
i = testimonials.length;
}
i = i - 1;
return testimonials[i].client;
}
window.addEventListener('load', function() {
$('.client-box').html(testimonials[i].client);
$('.candidate-box').html(testimonials[i].candidate);
$('.left-btn').on('click', function(e) {
$('.client-box').html(prevItem());
$('.candidate-box').html(prevItem());
});
$('.right-btn').on('click', function(e) {
$('.client-box').html(nextItem());
$('.candidate-box').html(nextItem());
});
});
https://jsfiddle.net/cL5mok3f/
Fixing the code:
let testimonials = [{
client: "Raphel",
candidate: "male"
},
{
client: "Tom",
candidate: "male"
},
{
client: "Jerry",
candidate: "male"
},
{
client: "Dorry",
candidate: "female"
}
];
var i = 0;
function nextItem() {
i = i + 1;
i = i % testimonials.length;
return testimonials[i];
}
function prevItem() {
if (i === 0) {
i = testimonials.length;
}
i = i - 1;
return testimonials[i];
}
window.addEventListener('load', function() {
$('.client-box').html(testimonials[i].client);
$('.candidate-box').html(testimonials[i].candidate);
$('.left-btn').on('click', function(e) {
var prev = prevItem();
$('.client-box').html(prev.client);
$('.candidate-box').html(prev.candidate);
});
$('.right-btn').on('click', function(e) {
var next = nextItem();
$('.client-box').html(next.client);
$('.candidate-box').html(next.candidate);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="client-box"></div>
<div class="candidate-box"></div>
<input type="button" class="left-btn" value="Prev" />
<input type="button" class="right-btn" value="Next" />
To achieve expected result, use below option
Issue: PrevItem and nextItem methods are called twice on clicking left and right which creates inconsistent carousel
Code sample
let testimonials = [
{client: "Raphel", candidate: "male"},
{client: "Tom", candidate: "male"},
{client: "Jerry", candidate: "male"},
{client: "Dorry", candidate: "female"}
];
var i = 0;
$('.client-box').text(testimonials[0].client);
$('.candidate-box').text(testimonials[1].candidate);
function nextItem() {
i = i + 1;
if (i === testimonials.length) {
i = i % testimonials.length;
}
return testimonials[i];
}
function prevItem() {
if (i === 0) {
i = testimonials.length;
}
i = i - 1;
console.log("prev", i)
return testimonials[i];
}
$('.left-btn').on('click', function(e){
let val = prevItem()
$('.client-box').text(val.client);
$('.candidate-box').text(val.candidate);
});
$('.right-btn').on('click', function(e){
let val = nextItem()
$('.client-box').text(val.client);
$('.candidate-box').text(val.candidate);
});
.testimonial-carousel {
position: relative;
width: 1000px;
}
.testimonial-carousel::after {
content: "";
display: block;
clear: both;
}
.testimonial-carousel .testimonial-box {
width: 500px;
height: 100px;
float: left;
background: #999999;
}
.testimonial-carousel .testimonial-box.candidate-box {
background: white;
margin-top: 2rem;
box-shadow: 0 0 1rem rgba(0, 0, 0, 0.2);
}
.testimonial-carousel .buttons {
position: absolute;
bottom: -60px;
right: 20px;
}
.testimonial-carousel .buttons::after {
content: "";
display: block;
clear: both;
}
.testimonial-carousel .buttons .btn {
background: black;
width: 60px;
height: 60px;
float: left;
margin-right: 5px;
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="testimonial-carousel">
<div class="testimonial-box client-box"></div>
<div class="testimonial-box candidate-box"></div>
<div class="buttons">
LEFT
RIGHT
</div>
</div>
codepen - https://codepen.io/nagasai/pen/wLKoVv
Here is my HTLM Page:
<!DOCTYPE html>
<script src="Scripts/knockout-3.4.2.js" type="text/javascript"></script>
<script src="Scripts/jquery-3.1.1.min.js"></script>
<script src="Scripts/knockout.simpleGrid.js"></script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Knockout GridView Örnek</title>
<style>
body { font-family: arial; font-size: 14px; }
.liveExample { padding: 1em; background-color: #EEEEDD; border: 1px solid #CCC; max-width: 655px; }
.liveExample input { font-family: Arial; }
.liveExample b { font-weight: bold; }
.liveExample p { margin-top: 0.9em; margin-bottom: 0.9em; }
.liveExample select[multiple] { width: 100%; height: 8em; }
.liveExample h2 { margin-top: 0.4em; }
.ko-grid { margin-bottom: 1em; width: 25em; border: 1px solid silver; background-color:White; }
.ko-grid th { text-align:left; background-color: Black; color:White; }
.ko-grid td, th { padding: 0.4em; }
.ko-grid tr:nth-child(odd) { background-color: #DDD; }
.ko-grid-pageLinks { margin-bottom: 1em; }
.ko-grid-pageLinks a { padding: 0.5em; }
.ko-grid-pageLinks a.selected { background-color: Black; color: White; }
.liveExample { height:20em; overflow:auto }
li { list-style-type: disc; margin-left: 20px; }
</style>
</head>
<body>
<div data-bind='simpleGrid: gridViewModel'></div>
<div>Ad: </div> <input data-bind="value: Ad" /> <br />
<div>Satılan: </div> <input data-bind="value: Satis" /> <br />
<div>Fiyat: </div> <input data-bind="value: tutar" /> <br />
<button data-bind='click: addItem'>
Add item
</button>
<button data-bind='click: deleteFirst'>Delete first Row</button>
<button data-bind='click: deleteLast'>Delete Last Row</button>
<button data-bind='click: sortByName'>
Sort by name
</button>
<button data-bind='click: jumpToFirstPage, enable: gridViewModel.currentPageIndex'>
Jump to first page
</button>
</body>
</html>
Here is my JavaScript:
<script type="text/javascript">
var initialData = [
{ name: "Well-Travelled Kitten", sales: 352, price: 75.95 },
{ name: "Speedy Coyote", sales: 89, price: 190.00 },
{ name: "Furious Lizard", sales: 152, price: 25.00 },
{ name: "Indifferent Monkey", sales: 1, price: 99.95 },
{ name: "Brooding Dragon", sales: 0, price: 6350 },
{ name: "Ingenious Tadpole", sales: 39450, price: 0.35 },
{ name: "Optimistic Snail", sales: 420, price: 1.50 }
];
var PagedGridModel = function (items) {
this.items = ko.observableArray(items);
this.sortByName = function () {
this.items.sort(function (a, b) {
return a.name < b.name ? -1 : 1;
});
};
this.jumpToFirstPage = function () {
this.gridViewModel.currentPageIndex(0);
};
this.deleteFirst = function () {
this.items.shift();
}
this.deleteLast = function () {
this.items.pop();
}
this.removeGift = function (item) {
this.initialData.remove(item);
};
this.gridViewModel = new ko.simpleGrid.viewModel({
data: this.items,
columns: [
{ headerText: "Item Name", rowText: "name" },
{ headerText: "Sales Count", rowText: "sales" },
{ headerText: "Price", rowText: function (item) { return "$" + item.price.toFixed(2) } }
],
pageSize: 4
});
this.Ad = ko.observable("");
this.Satis = ko.observable("");
this.tutar = ko.observable("");
this.addItem = function () {
if (this.Ad() != "" && this.Satis() != "" && this.tutar() != "") {
this.tutar(Number(this.tutar()));
this.Satis(Number(this.Satis()));
this.items.push({ name: this.Ad(), sales: this.Satis(), price: this.tutar() });
this.Ad("");
this.Satis("");
this.tutar("");
}
}.bind(this);
};
ko.applyBindings(new PagedGridModel(initialData));
</script>
Here is my Grid JS:
(function () {
// Private function
function getColumnsForScaffolding(data) {
if ((typeof data.length !== 'number') || data.length === 0) {
return [];
}
var columns = [];
for (var propertyName in data[0]) {
columns.push({ headerText: propertyName, rowText: propertyName });
}
return columns;
}
ko.simpleGrid = {
// Defines a view model class you can use to populate a grid
viewModel: function (configuration) {
this.data = configuration.data;
this.currentPageIndex = ko.observable(0);
this.pageSize = configuration.pageSize || 5;
// If you don't specify columns configuration, we'll use scaffolding
this.columns = configuration.columns || getColumnsForScaffolding(ko.unwrap(this.data));
this.itemsOnCurrentPage = ko.computed(function () {
var startIndex = this.pageSize * this.currentPageIndex();
return ko.unwrap(this.data).slice(startIndex, startIndex + this.pageSize);
}, this);
this.maxPageIndex = ko.computed(function () {
return Math.ceil(ko.unwrap(this.data).length / this.pageSize) - 1;
}, this);
}
};
// Templates used to render the grid
var templateEngine = new ko.nativeTemplateEngine();
templateEngine.addTemplate = function (templateName, templateMarkup) {
document.write("<script type='text/html' id='" + templateName + "'>" + templateMarkup + "<" + "/script>");
};
templateEngine.addTemplate("ko_simpleGrid_grid", "\
<table class=\"ko-grid\" cellspacing=\"0\">\
<thead>\
<tr data-bind=\"foreach: columns\">\
<th data-bind=\"text: headerText\"></th>\
</tr>\
</thead>\
<tbody data-bind=\"foreach: itemsOnCurrentPage\">\
<tr data-bind=\"foreach: $parent.columns\">\
<td data-bind=\"text: typeof rowText == 'function' ? rowText($parent) : $parent[rowText] \"></td>\
<td>Delete</td>\
</tr>\
</tbody>\
</table>");
templateEngine.addTemplate("ko_simpleGrid_pageLinks", "\
<div class=\"ko-grid-pageLinks\">\
<span>Page:</span>\
<!-- ko foreach: ko.utils.range(0, maxPageIndex) -->\
<a href=\"#\" data-bind=\"text: $data + 1, click: function() { $root.currentPageIndex($data) }, css: { selected: $data == $root.currentPageIndex() }\">\
</a>\
<!-- /ko -->\
</div>");
// The "simpleGrid" binding
ko.bindingHandlers.simpleGrid = {
init: function () {
return { 'controlsDescendantBindings': true };
},
// This method is called to initialize the node, and will also be called again if you change what the grid is bound to
update: function (element, viewModelAccessor, allBindings) {
var viewModel = viewModelAccessor();
// Empty the element
while (element.firstChild)
ko.removeNode(element.firstChild);
// Allow the default templates to be overridden
var gridTemplateName = allBindings.get('simpleGridTemplate') || "ko_simpleGrid_grid",
pageLinksTemplateName = allBindings.get('simpleGridPagerTemplate') || "ko_simpleGrid_pageLinks";
// Render the main grid
var gridContainer = element.appendChild(document.createElement("DIV"));
ko.renderTemplate(gridTemplateName, viewModel, { templateEngine: templateEngine }, gridContainer, "replaceNode");
// Render the page links
var pageLinksContainer = element.appendChild(document.createElement("DIV"));
ko.renderTemplate(pageLinksTemplateName, viewModel, { templateEngine: templateEngine }, pageLinksContainer, "replaceNode");
}
};
})();
I want like this
But Delete not working and repeat 3 times always 1 line. I want it 1 Line 1 delete and I want to delete it. How I can do this ? I need your help guys. Thank you in advance.