In react-grid-layout i am displaying name,image and a checkbox. The checkbox will be checked by default. The thing i want to do is onClicking the grid I want to change the checkbox status, here onCellClick() function is not working.
Here is the code
var Student= React.createClass({
getDefaultProps:function() {
return {
className: "layout",
rowHeight: 16,
cols: 16,
width:1200,
isDraggable: false,
isResizable:false,
verticalCompact:false
};
},
onCellClick:function(){
if(document.getElementById("stdattendance").checked==false){
document.getElementById("stdattendance").checked=true;
}else{
document.getElementById("stdattendance").checked=false;
}
},
generateDOM:function() {
console.log(this.props.student+_.range(this.props.items)+new Array(this.props.student));
var clickfun=this.click;
return _.map(this.props.student, function(item, i) {
var keyint=item.id;
idval.push(item.id);
var checkid=item.id+"-id";
var divid=item.id+"-id";
console.log("key"+keyint+idval);
console.log("x after : " + i * 2 % 16);
console.log("y after : " + Math.floor(i / 8) * 8);
return (<div key={i} id={divid} onClick={this.onCellClick} data-grid={{x: i * 2 % 16, y: Math.floor(i / 8) * 8, w: 2, h: 6,static: true }}><span className="group-class1"> {item.name}</span>
<div id="check">
<input type="checkbox" id="stdattendance" name="stdattendance" checked/>
</div>
<Image src="../images/No_image.png"/>
</div>);
});
},
render: function() {
// This prints the correct data
console.log(this.props.student);
return (
<div>
{(this.props.student.length)?
<div>
<ReactGridLayout
{...this.props}>
{this.generateDOM()}
</ReactGridLayout>
</div>:""
}
</div>
);
}
});
Reason, why all grid is getting selected, is you are using a single state variable for all rows, use an array, each entry will attached to each row, Try this:
var Student= React.createClass({
getInitialState: function() {
return {
checked: []
}
},
getDefaultProps:function() {
return {
className: "layout",
rowHeight: 16,
cols: 16,
width:1200,
isDraggable: false,
isResizable:false,
verticalCompact:false
};
},
onCellClick:function(index){
let checked = this.state.checked;
checked[index] = !checked[index];
this.setState({checked: checked});
}
generateDOM:function() {
console.log(this.props.student+_.range(this.props.items)+new Array(this.props.student));
var clickfun=this.click;
return _.map(this.props.student, function(item, i) {
var keyint=item.id;
idval.push(item.id);
var checkid=item.id+"-id";
var divid=item.id+"-id";
console.log("key"+keyint+idval);
console.log("x after : " + i * 2 % 16);
console.log("y after : " + Math.floor(i / 8) * 8);
return (<div key={i} id={divid} onClick={this.onCellClick(i)} data-grid={{x: i * 2 % 16, y: Math.floor(i / 8) * 8, w: 2, h: 6,static: true }}><span className="group-class1"> {item.name}</span>
<div id="check">
<input type="checkbox" ref="stdattendance" name="stdattendance" checked={!this.state.checked[i]}/>
</div>
<Image src="../images/No_image.png"/>
</div>);
}.bind(this));
},
render: function() {
// This prints the correct data
console.log(this.props.student);
return (
<div>
{(this.props.student.length)?
<div>
<ReactGridLayout {...this.props}>
{this.generateDOM()}
</ReactGridLayout>
</div>:""
}
</div>);
}
});
Instead of using the Javascript DOM you should do it the react way and make use of refs
<input type="checkbox" ref="stdattendance" name="stdattendance" checked/>
onCellClick:function(){
if(React.findDOMNode(this.refs.stdattendance).checked == false){
React.findDOMNode(this.refs.stdattendance).checked=true;
}else{
React.findDOMNode(this.refs.stdattendance).checked=false;
}
}
Although the above approach is enough but I would suggest you to make use a controlled checkbox component
var Student= React.createClass({
getInitialState: function() {
return {
checked: true
}
},
getDefaultProps:function() {
return {
className: "layout",
rowHeight: 16,
cols: 16,
width:1200,
isDraggable: false,
isResizable:false,
verticalCompact:false
};
},
onCellClick:function(divid){
var val;
console.log("val"+divid);
var inputElements = document.getElementsByClassName('checkboxgrp');
for(var i=0; i<inputElements.length; i++){
console.log(document.getElementsByClassName('checkboxgrp')[i].value);
if(document.getElementsByClassName('checkboxgrp')[i].value==divid){
if(document.getElementsByClassName('checkboxgrp')[i].checked==true){
document.getElementsByClassName('checkboxgrp')[i].checked=false;
}else{
document.getElementsByClassName('checkboxgrp')[i].checked=true
}}}
},
generateDOM:function() {
console.log(this.props.student+_.range(this.props.items)+new Array(this.props.student));
var clickfun=this.click;
return _.map(this.props.student, function(item, i) {
var keyint=item.id;
idval.push(item.id);
var checkid=item.id+"-id";
var divid=item.id+"-id";
console.log("key"+keyint+idval);
console.log("x after : " + i * 2 % 16);
console.log("y after : " + Math.floor(i / 8) * 8);
return (<div key={i} id={divid} onClick={this.onCellClick.bind(this, divid)} data-grid={{x: i * 2 % 16, y: Math.floor(i / 8) * 8, w: 2, h: 6,static: true }}><span className="group-class1"> {item.name}</span>
<div id="check">
<input type="checkbox" ref="stdattendance" name="stdattendance" className="checkboxgrp" value={item.user} checked={this.state.checked}/>
</div>
<Image src="../images/No_image.png"/>
</div>);
}.bind(this));
},
render: function() {
// This prints the correct data
console.log(this.props.student);
return (
<div>
{(this.props.student.length)?
<div>
<ReactGridLayout
{...this.props}>
{this.generateDOM()}
</ReactGridLayout>
</div>:""
}
</div>
);
}
});
Related
thanks for anybody reading me here ,
I have got this code from my prof and I want ,need to calculate automatically the sum , the total of the players in the html I mean being displayed.
I'm really new to this , can anybody help me out ?
Want to understand The Vue.js math functions in order to progress in my studies and in math as well.
Last..so full of doubt here , sorry guys , Vue.js is a js library ..so I cannot put a js script inside vue.js right ?
Thanks
var players = [
{ label: 'A', value: 100 },
{ label: 'B', value: 100 },
{ label: 'C', value: 100 },
{ label: 'D', value: 100 },
{ label: 'E', value: 100 },
{ label: 'F', value: 100 }
]
Vue.component("polygraph", {
template: "#polygraphComponent",
props: ["stats", "width"],
computed: {
radius() { return (this.width / 2); },
viewbox() {
var size = this.width;
var min = -(size / 2);
return [min, min, size, size].join(" ");
},
points() {
var total = this.stats.length
return this.stats.map((stat, i) => {
var point = valueToPoint(stat.value, i, total)
return point.x + "," + point.y
}).join(" ")
}
},
components: {
axisLabel: {
template: "#axisLabelComponent",
props: {
stat: Object,
index: Number,
total: Number
},
computed: {
point() {
return valueToPoint(
this.stat.value,
this.index,
this.total
)
}
}
}
}
})
new Vue({
el: "#app",
data: {
newLabel: "",
players: players,
width: 600
},
methods: {
add(evt) {
evt.preventDefault()
if (!this.newLabel) return
this.players.push({
label: this.newLabel,
value: 100
})
this.newLabel = ""
},
remove(stat) {
if (this.players.length > 3) {
this.players.$remove(stat)
} else {
alert("Can't remove more!")
}
}
},
components: {
scoreControl: {
template: "#scoreControlComponent",
props: {
stat: Object,
index: Number,
total: Number
},
computed: {
point() {
return valueToPoint(
this.stat.value,
this.index,
this.total
)
},
style() {
var angle = this.point.angle;
return {
transform: "rotate(" + angle + "rad)"
}
}
}
}
}
})
// math helper...
function valueToPoint(value, index, total) {
var maxV = 100
var maxR = 300 * 0.9
var r = maxR / maxV * value
var angle = Math.PI * 2 / total * index + Math.PI / 2
var cos = Math.cos(angle)
var sin = Math.sin(angle)
var tx = r * cos
var ty = r * sin
return {
angle: angle,
radius: r,
x: tx,
y: ty
}
}
whenever my layout changes, it will save the new changes into localstorage and update my layout state
onLayoutChange(layouts) {
saveToLS("layouts", layouts);
}
However, the issue occurs When the page is refreshed. layout was updated before it was fetched from local storage, this means it discard all the changes and reset the layout to default. The image below shows what i mean
What should I do to prevent this from happening?? I am following this guide. It is working on the guide but not for me, really appreciate any help
Here is the full code I am using
const originalLayouts = getFromLS("layouts") || {};
const ResponsiveReactGridLayout = WidthProvider(Responsive);
class MinMaxLayout extends React.PureComponent {
static defaultProps = {
margin:[0,0],
className:"layout",
cols: { lg: 1, md: 10 },
rowHeight: 100
};
constructor(props) {
super(props);
this.state = {
layouts: JSON.parse(JSON.stringify(originalLayouts)),
inputWidthVal: "",
inputHeightVal:"",
items: [0, 1, 2, 3, 4].map(function (i, key, list) {
return {
id: uuidV4(),
i: i.toString(),
x: i * 2,
y: 0,
w: 1,
h: 1
};
}),
charts: [0].map(function (i, key, list) {
return {
id: uuidV4(),
i: i.toString(),
x: i,
y: 0,
w: 4,
h: 3
};
}),
newCounter: 0,
chartCounter:0
};
this.onAddItem = this.onAddItem.bind(this);
this.onChartItem = this.onChartItem.bind(this);
this.onBreakpointChange = this.onBreakpointChange.bind(this);
}
createElement(el) {
const removeStyle = {
position: "absolute",
left: "11px",
top: 0,
cursor: "pointer"
};
const i = el.i;
return (
<div key={el.id} data-grid={el} >
<span
className="remove"
style={removeStyle}
onClick={this.onRemoveItem.bind(this, i)}
>
x
</span>
</div>
);
}
// this is the charts that was created when the DOM was render
createChart(el) {
const removeStyle = {
position: "absolute",
left: "11px",
top: 0,
cursor: "pointer"
};
const i = el.i;
return (
// <div key={el.id} data-grid={el} onClick={((e) => this.handleClick(e))}>
<div key={el.id} data-grid={el} className="graph">
<Newvsresturnvisitors />
<span
className="remove"
style={removeStyle}
onClick={this.onRemoveChartItem.bind(this, i)}
>
x
</span>
</div>
);
}
onAddItem() {
this.setState({
// Add a new item. It must have a unique key!
items: this.state.items.concat({
id: uuidV4(),
i: "n" + this.state.newCounter,
x: (this.state.items.length * 2) % (this.state.cols || 12),
y: Infinity, // puts it at the bottom
w: 1,
h: 1
}),
// Increment the counter to ensure key is always unique.
newCounter: this.state.newCounter + 1
});
}
onChartItem() {
this.setState({
// Add a new item. It must have a unique key!
charts: this.state.charts.concat({
id: uuidV4(),
i: "n" + this.state.chartCounter,
x: (this.state.charts.length * 2) % (this.state.cols || 12),
y: 0, // puts it at the bottom
w: 4,
h: 3
}),
// Increment the counter to ensure key is always unique.
chartCounter: this.state.chartCounter + 1
});
}
// We're using the cols coming back from this to calculate where to add new items.
onBreakpointChange(breakpoint, cols) {
this.setState({
breakpoint: breakpoint,
cols: cols
});
}
onRemoveItem(i) {
this.setState({ items: _.reject(this.state.items, { i: i }) });
}
clearAllItem = ()=>{
this.setState({ items: [], charts: [] });
}
onRemoveChartItem(i){
this.setState({ charts: _.reject(this.state.charts, { i: i }) });
}
inputCanvasDimension = e =>{
const re = /^[0-9\b]+$/;
if (e.target.value === '' || re.test(e.target.value)) {
if(e.currentTarget.className === "inputWidth"){
this.setState({inputWidthVal: e.currentTarget.value});
}else if(e.currentTarget.className === "inputHeight"){
this.setState({inputHeightVal: e.currentTarget.value});
}
}
}
setCanvasDimension = () =>{
var canvas = document.getElementById("DetailLocationContainer");
if((this.state.inputWidthVal < 1000) || (this.state.inputHeightVal < 3000)){
alert("Width should not be less than 1000 and height should not be less than 3000");
}else {
canvas.style.width= this.state.inputWidthVal + "px";
canvas.style.height= this.state.inputHeightVal + "px";
}
}
saveToLS(key, value) {
var secondObject = Object.entries(value)[1];
if (global.localStorage) {
global.localStorage.setItem(
"rgl-8",
JSON.stringify({
[key]: value
})
);
}
}
onLayoutChange(layout, layouts) {
this.saveToLS("layouts", layouts);
}
onDrop = (layout, layoutItem, _event) => {
if(_event.dataTransfer.mozSourceNode.className === "textwidget"){
this.setState({
items: this.state.items.concat({
id: uuidV4(),
i: "n" + this.state.newCounter,
x: layoutItem.x,
y: layoutItem.y,
w: 1,
h: 1
}),
newCounter: this.state.newCounter + 1
});
}else if(_event.dataTransfer.mozSourceNode.className === "chart"){
this.setState({
// Add a new item. It must have a unique key!
charts: this.state.charts.concat({
id: uuidV4(),
i: "n" + this.state.chartCounter,
x: (this.state.charts.length * 2) % (this.state.cols || 12),
y: Infinity, // puts it at the bottom
w: 5,
h: 6
}),
// Increment the counter to ensure key is always unique.
chartCounter: this.state.chartCounter + 1
});
}
};
reset = () =>{
// window.location.reload(true);
this.setState({ layouts: {} });
}
render() {
return (
<div className="container" id="container">
<div className="btn_container">
<div>
<span>Width </span>
<input className="inputWidth" value={this.state.inputWidthVal} onChange={this.inputCanvasDimension}/>
<span> Height </span>
<input className="inputHeight" value={this.state.inputHeightVal} onChange={this.inputCanvasDimension}/>
<button onClick={this.setCanvasDimension}>Apply</button>
<button onClick={this.reset}><CachedIcon style={{fontSize: '14px'}}/></button>
<button onClick={openFullscreen}><FullscreenSharpIcon style={{fontSize: '14px'}}/></button>
</div>
</div>
<button id="createItemBtn" onClick={this.onAddItem}>Add Item</button>
<button id="createChartBtn" onClick={this.onChartItem}>Add Chart</button>
<button onClick={this.clearAllItem}>Clear All</button>
<div className="widgetcontainer">
<WidgetThumbnail
className="chart"
/>
<WidgetThumbnail
className="textwidget"
/>
</div>
<div className='DetailLocationContainer' id="DetailLocationContainer" >
<ResponsiveReactGridLayout
cols={{ lg: 1, md: 10, sm: 6, xs: 4, xxs: 2 }}
rowHeight={100}
onDrop={this.onDrop}
isDroppable={true}
isBounded={true}
layouts={this.state.layouts}
onLayoutChange={(layout, layouts) =>
this.onLayoutChange(layout, layouts)
}
onBreakpointChange={this.onBreakpointChange}
{...this.props}
>
{_.map(this.state.items, (el) => this.createElement(el))}
{_.map(this.state.charts, (el) => this.createChart(el))}
</ResponsiveReactGridLayout>
</div>
</div>
);
}
}
export default MinMaxLayout;
const rootElement = document.getElementById("root");
ReactDOM.render(<MinMaxLayout />, rootElement);
This is my getFrinLS
export function getFromLS(key) {
let md = {};
if (global.localStorage) {
try {
md = JSON.parse(global.localStorage.getItem("rgl-8")) || {};
} catch (e) {
/*Ignore*/
}
// console.log("return value ", md[key]);
return md[key];
}
}
Looks like incremental keys are needed to apply updated layout. Change the key value from el.id to i
createElement(el) {
const removeStyle = {
position: "absolute",
left: "11px",
top: 0,
cursor: "pointer"
};
const i = el.i;
return (
<div key={i} data-grid={el} >
<span
className="remove"
style={removeStyle}
onClick={this.onRemoveItem.bind(this, i)}
>
x
</span>
</div>
);
}
I want to get the effect of something like this:
And here is my best attempt as a combo graph:
The problem is I need to vastly ramp up the number of bars in this chart. However, when I try to do this the bars disappear.
Here is my code as a typescript reactjs setup:
import './App.css';
import React from 'react';
import { Bar, Line } from 'react-chartjs-2';
const createRandomFollowersData = () => {
const maxDate = new Date();
const minDate = new Date(maxDate.valueOf() - 5 * 365 * 24 * 60 * 60 * 1000);
const dataPoints = Array.from({ length: 500 }).map(() => ({
timestamp: new Date(
Math.floor(Math.random() * (maxDate.valueOf() - minDate.valueOf())) +
minDate.valueOf()
).toISOString(),
followers: Math.floor(Math.random() * 1000000) + 0,
}));
return dataPoints.sort(
(a, b) => new Date(a.timestamp).valueOf() - new Date(b.timestamp).valueOf()
);
};
const createRandomAssetData = () => {
const maxDate = new Date();
const minDate = new Date(maxDate.valueOf() - 5 * 365 * 24 * 60 * 60 * 1000);
const dataPoints = Array.from({ length: 500 }).map(() => ({
timestamp: new Date(
Math.floor(Math.random() * (maxDate.valueOf() - minDate.valueOf())) +
minDate.valueOf()
).toISOString(),
price: Math.floor(Math.random() * 45) + 1,
}));
return dataPoints.sort(
(a, b) => new Date(a.timestamp).valueOf() - new Date(b.timestamp).valueOf()
);
};
const followersData = createRandomFollowersData();
const yAxisFollowers = {
type: 'linear',
id: 'followers',
};
const yAxisDelta = {
type: 'linear',
position: 'right',
id: 'change',
};
const yAxisRank = {
type: 'linear',
id: 'rank',
ticks: {
reverse: true,
},
};
const yAxisAssets = {
type: 'linear',
position: 'right',
id: 'assets',
};
const selectChartAxes = (
containsFollowers: boolean,
containsRank: boolean,
showDelta: boolean,
showAssets: boolean
) => {
const yAxes = [];
if (containsFollowers) yAxes.push(yAxisFollowers);
if (containsRank) yAxes.push(yAxisRank);
if (showDelta) yAxes.push(yAxisDelta);
if (showAssets) yAxes.push(yAxisAssets);
return yAxes;
};
const decimateChart = (
data: {
t: Date;
y: number;
}[],
numBuckets: number,
startDate?: Date,
endDate?: Date
) => {
if (!startDate) {
startDate = data[0].t;
}
if (!endDate) {
endDate = data[data.length - 1].t;
}
// create evenly spaced dates
const dt = endDate.valueOf() - startDate.valueOf();
const startValue = startDate.valueOf();
const spacedDates = Array.from({ length: numBuckets + 1 }).map((_, idx) => {
return new Date(startValue + (idx * dt) / numBuckets);
});
// make buckets
const buckets = Array.from({ length: numBuckets + 2 }).map(() => []) as {
t: Date;
y: number;
}[][];
const filteredData = data.filter(
(e) => e.t >= spacedDates[0] && e.t <= spacedDates[spacedDates.length - 1]
);
// place data into buckets
let jdx = 0;
spacedDates.forEach((e, idx) => {
for (; jdx < filteredData.length; ) {
const e = filteredData[jdx];
const date = new Date(e.t);
if (date >= spacedDates[idx] && date <= spacedDates[idx + 1]) {
buckets[idx].push({
t: date,
y: e.y,
});
++jdx;
} else break;
}
});
// one plot per bucket
return buckets.map((bucket, idx) => {
const date = spacedDates[idx];
if (bucket.length === 0) {
return {
t: date,
y: NaN,
};
}
return bucket[bucket.length - 1];
});
};
const chartMappedFollowersData = followersData.map((followerData) => ({
t: new Date(followerData.timestamp),
y: followerData.followers,
}));
// const decimatedData = decimateChart(chartMappedFollowersData, 75);
const decimatedData = decimateChart(chartMappedFollowersData, 75).map(
(e, idx) => {
if (idx > 1 && idx < 10) {
return {
t: e.t,
y: NaN,
};
}
if (idx > 30 && idx < 45) {
return {
t: e.t,
y: NaN,
};
}
return e;
}
);
const decimatedDataToBars = (
data: {
t: Date;
y: number;
}[]
) => {
if (data.length < 2) {
return {
t: data[0].t,
y: data[0].y,
};
}
const bars = [];
const indexedData = data.map((e, idx) => ({
...e,
idx,
}));
const filteredIndexedData = indexedData.filter((e) => !isNaN(e.y));
for (let idx = 0; idx < filteredIndexedData.length - 1; ++idx) {
const dt = data[idx + 1].t.valueOf() - data[idx].t.valueOf();
for (
let idy = 0;
idy < filteredIndexedData[idx + 1].idx - filteredIndexedData[idx].idx;
++idy
) {
const t = new Date(filteredIndexedData[idx].t.valueOf() + idy * dt);
const deltaY =
(filteredIndexedData[idx + 1].y - filteredIndexedData[idx].y) /
(filteredIndexedData[idx + 1].idx - filteredIndexedData[idx].idx);
bars.push({
t,
y: deltaY,
});
}
}
return bars;
};
const chartOptionsLinear = {
scales: {
yAxes: selectChartAxes(true, false, true, true),
xAxes: [
{
type: 'time',
time: {
unit: 'day',
displayFormats: { day: 'MMM DD, Y' },
min: chartMappedFollowersData[0].t,
max: chartMappedFollowersData[chartMappedFollowersData.length - 1].t,
},
ticks: {
source: 'labels',
},
},
],
maintainAspectRatio: false,
},
};
const chartData = {
labels: decimatedData.map((e) => e.t).filter((_, idx) => idx % 3 === 0),
datasets: [
{
yAxisID: 'followers',
cubicInterpolationMode: 'monotone',
backgroundColor: 'rgb(54, 162, 235)',
borderColor: 'rgb(88, 88, 88)',
fill: false,
type: 'line',
label: 'followers',
spanGaps: true,
data: decimatedData,
},
{
yAxisID: 'change',
type: 'bar',
backgroundColor: 'rgb(235, 54, 162)',
label: 'delta',
data: decimatedDataToBars(decimatedData),
barThickness: 1,
},
],
};
function App(): JSX.Element {
return (
<div style={{ margin: '1em' }}>
<Bar data={chartData} options={chartOptionsLinear} />
</div>
);
}
export default App;
If you swap out data: decimatedDataToBars(decimatedData), to data: decimatedDataToBars(chartMappedFollowersData), you can see the effect; The bars disappear. Does anyone have any insight into this problem and how I can fix it?
So the issue was a bug in 2.8.0 that caused the bars to not show. Upgrading to 2.9.4 fixed the issue for me (but broke some other functionality of why I was using 2.8.0 in the first place.)
I implemented a chart with legend based on Echarts libary. What i want to develop now is tooltip for each data on chart legend. Data are prepared as array of object and each name have corresponding description which i want to show on tooltip. In other word, i want tooltip from picture below to be shown after mouse hover on legend names.
<div class="card grid-stack-item-content cd-example" id="dashboard-header">
<div class="card-header container-fluid">
<div class="row dashboard-row">
<div class="col-3 dashboard-icon-div text-center">
<h1 class="dashboard-h1"><i class="fa fa-tags dashboard-logo"></i></h1>
</div>
<div class="col-5">
<h4 class="card-title dashboard-card-title">{{trans('app.icd10_codes')}}</h4>
<h6 class="card-subtitle text-muted">
#if (count($binnedIcds['targetIcds']['codes']) > 0)
<span class="info-box-number">
{{count($binnedIcds['targetIcds']['codes'])}}
{{trans('app.skin_disease_groups')}}
</span>
#endif
</h6>
</div>
</div>
</div>
<div class="card-body">
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12">
<div id="pie-chart" style="width:100%; min-height: 480px;"></div>
</div>
</div>
</div>
</div>
NewIcdTile.js
class NewIcdChart
{
constructor(ctx, targetsLabels, othersLabel, undefLabel, targetsTooltips, othersTooltip,
undefTooltip, nTargets, nOthers, nTotal)
{
this.othersColor = '#888888';
this.undefColor = '#cccccc';
var labels = {
targetsLabels,
othersLabel,
undefLabel
};
var tooltips = {
targetsTooltips,
othersTooltip,
undefTooltip,
};
var nTargetImages = nTargets.reduce((a,b) => a + b, 0);
var nUndef = nTotal - nTargetImages - nOthers;
var counts = {
nTargets,
nOthers,
nTotal,
nUndef,
};
this.chart;
this.hasOthers = false;
this.hasUndef = false;
this.drawChart(ctx, labels, tooltips, counts);
}
drawChart(ctx, labels, tooltips, counts){
var otherValue=counts.nOthers;
var otherLabel=labels.othersLabel;
var otherTooltip=tooltips.othersTooltip;
var undefinedValue=counts.nUndef;
var undefinedLabel=labels.undefLabel;
var undefinedTooltip=tooltips.undefTooltip;
var targetValues=counts.nTargets;
var targetLabels=labels.targetsLabels;
var targetTooltip=tooltips.targetsTooltips;
var finalChartValue=[];
for(var i=0; i<targetValues.length; i++){
for(var i=0; i<targetLabels.length; i++){
for(var i=0; i<targetTooltip.length; i++){
var obj = {"value": targetValues[i], "name": targetLabels[i], "tooltip": targetTooltip[i]};
finalChartValue.push(obj);
}
}
}
var otherObject={
value: otherValue,
name : otherLabel,
tooltip : otherTooltip
};
var undefinedObject={
value: undefinedValue,
name : undefinedLabel,
tooltip : undefinedTooltip
};
finalChartValue.unshift(otherObject, undefinedObject);
console.log("finalChartValue", finalChartValue);
var finalChartLables=[];
finalChartValue.forEach(function(res) {
finalChartLables.push(res.name);
});
// specify chart configuration item and data
var option = {
tooltip: {
trigger: 'item',
formatter: "{a} <br/>{b} : {c}",
},
legend: {
x : 'center',
y : 'bottom',
padding: 1,
formatter: function(name) {
var data = this.getSeries()[0].data;
var totalValue = data.reduce((acc, item) => {
acc += item.value;
return acc;
}, 0)
var targetValue;
var targetTooltip;
data.map(item => {
if (item.name == name) {
targetValue = item.value;
targetTooltip= item.tooltip;
}
})
var p = (targetValue / totalValue * 100).toFixed(2);
console.log("name", name);
return name + ' ' + p + '%';
},
data:finalChartLables
},
toolbox: {
show: true,
feature: {
dataView: { show: true, readOnly: false },
magicType: {
show: true,
type: ['pie']
},
restore: { show: true },
saveAsImage: { show: true }
}
},
color: ["#f62d51", "#dddddd", "#ffbc34", "#7460ee", "#009efb", "#2f3d4a", "#90a4ae", "#55ce63"],
calculable: true,
series: [{
name: 'ICD',
type: 'pie',
radius: [20, 180],
center : ['50%', '50%'],
roseType: 'radius',
itemStyle: {
normal: {
label: {
show: false,
formatter: "{b} : \n ({c})",
fontWeight: 100
},
labelLine: {
show: false,
formatter: "{b} : \n ({c})",
fontWeight: 100
}
},
emphasis: {
label: {
show: true,
formatter: "{b} : \n ({c})",
fontWeight: 100
},
labelLine: {
show: true,
formatter: "{b} : \n ({c})",
fontWeight: 100
}
}
},
data: finalChartValue
},
]
};
// use configuration item and data specified to show chart
ctx.setOption(option, true), $(function() {
function resize() {
setTimeout(function() {
ctx.resize()
}, 100)
}
$(window).on("resize", resize), $(".sidebartoggler").on("click", resize)
});
console.log("ctx", ctx);
}
}
you can add a tooltip option, and add a formatter function intolegend option, that will show a tooltip on top of the legend when mouse hover. for example:
var chart1 = echarts.init(document.getElementById("chart1"));
var option = {
tooltip: {
show: true,
formatter: "{a} <br/>{b} : {c} ({d}%)"
},
series: [
{
name: "WHATEVER",
type: "pie",
data: [
{ name: "A", value: 100 },
{ name: "B", value: 150 }
]
}
],
legend: {
data: ["A", "B"],
tooltip: {
show: true,
formatter: function (params) {
var total = 0,
cur_item = null;
var _selected = chart1.getOption().legend[0].selected;
if (_selected[params.name] === false) return; // no tooltip if legend unchecked.
for (var i = 0; i < option.series[0].data.length; i++) {
var item = option.series[0].data[i];
if (_selected[item.name] !== false) total += item.value; // get total amount checked only
if (item.name == params.name) cur_item = item;
}
if (!cur_item) return;
var format = "{a} <br/>{b} : {c} ({d}%)";
format = format.replace("{a}", option.series[0].name);
format = format.replace("{b}", cur_item.name);
format = format.replace("{c}", cur_item.value);
format = format.replace(
"{d}",
((cur_item.value / total) * 100).toFixed(2)
);
return format;
}
}
}
};
chart1.setOption(option);
Codepen
I have slick grid in 10 columns .but i need to display only 3 columns only.how is it possible pls any one help me urgent.here my slick grid here slick grid code. This code display all columns default but i want to display only 3 columns.
CSS
.slick-row.selected .cell-selection {
background-color: transparent; /* show default selected row background */
}
HTML
<div style="position:relative">
<div style="width:600px;">
<div class="grid-header" style="width:100%">
<label>SlickGrid</label>
<span style="float:right" class="ui-icon ui-icon-search" title="Toggle search panel"
onclick="toggleFilterRow()"></span>
</div>
<div id="myGrid" style="width:100%;height:500px;"></div>
<div id="pager" style="width:100%;height:20px;"></div>
</div>
<div class="options-panel">
<b>Search:</b>
<hr/>
<div style="padding:6px;">
<label style="width:200px;float:left">Show tasks with % at least: </label>
<div style="padding:2px;">
<div style="width:100px;display:inline-block;" id="pcSlider"></div>
</div>
<br/>
<label style="width:200px;float:left">And title including:</label>
<input type=text id="txtSearch" style="width:100px;">
<br/><br/>
<button id="btnSelectRows">Select first 10 rows</button>
<br/>
<h2>Demonstrates:</h2>
<ul>
<li>a filtered Model (DataView) as a data source instead of a simple array</li>
<li>grid reacting to model events (onRowCountChanged, onRowsChanged)</li>
<li><b>FAST</b> DataView recalculation and <b>real-time</b> grid updating in response to data changes.<br/>The grid holds <b>50'000</b> rows, yet you are able to sort, filter, scroll, navigate and edit as if it had 50 rows.</li>
<li>adding new rows, bidirectional sorting</li>
<li>column options: cannotTriggerInsert</li>
<li>events: onCellChange, onAddNewRow, onKeyDown, onSelectedRowsChanged, onSort</li>
<li><font color=red>NOTE:</font> all filters are immediately applied to new/edited rows</li>
<li>Handling row selection against model changes.</li>
<li>Paging.</li>
<li>inline filter panel</li>
</ul>
<h2>View Source:</h2>
<ul>
<li><A href="https://github.com/mleibman/SlickGrid/blob/gh-pages/examples/example4-model.html"
target="_sourcewindow"> View the source for this example on
Github</a></li>
</ul>
</div>
</div>
</div>
<div id="inlineFilterPanel" style="display:none;background:#dddddd;padding:3px;color:black;">
Show tasks with title including <input type="text" id="txtSearch2"> and % at least
<div style="width:100px;display:inline-block;" id="pcSlider2"></div>
</div>
JavaScript
<script src="slick.grid/lib/firebugx.js"></script>
<script> var dataView; var grid; var data = []; var columns = [
{id: "sel", name: "#", field: "num", behavior: "select", cssClass:
"cell-selection", width: 40, cannotTriggerInsert: true, resizable:
false, selectable: false }, {id: "title", name: "Title", field:
"title", width: 120, minWidth: 120, cssClass: "cell-title", editor:
Slick.Editors.Text, validator: requiredFieldValidator, sortable:
true}, {id: "duration", name: "Duration", field: "duration",
editor: Slick.Editors.Text, sortable: true}, {id: "%",
defaultSortAsc: false, name: "% Complete", field: "percentComplete",
width: 80, resizable: false, formatter:
Slick.Formatters.PercentCompleteBar, editor:
Slick.Editors.PercentComplete, sortable: true}, {id: "start", name:
"Start", field: "start", minWidth: 60, editor: Slick.Editors.Date,
sortable: true}, {id: "finish", name: "Finish", field: "finish",
minWidth: 60, editor: Slick.Editors.Date, sortable: true}, {id:
"effort-driven", name: "Effort Driven", width: 80, minWidth: 20,
maxWidth: 80, cssClass: "cell-effort-driven", field: "effortDriven",
formatter: Slick.Formatters.Checkmark, editor:
Slick.Editors.Checkbox, cannotTriggerInsert: true, sortable: true} ];
var options = { editable: true, enableAddRow: true,
enableCellNavigation: true, asyncEditorLoading: true,
forceFitColumns: false, topPanelHeight: 25 };
var sortcol = "title"; var sortdir = 1; var percentCompleteThreshold
= 0; var searchString = "";
function requiredFieldValidator(value) { if (value == null || value
== undefined || !value.length) {
return {valid: false, msg: "This is a required field"}; } else {
return {valid: true, msg: null}; } }
function myFilter(item, args) { if (item["percentComplete"] <
args.percentCompleteThreshold) {
return false; }
if (args.searchString != "" &&
item["title"].indexOf(args.searchString) == -1) {
return false; }
return true; }
function percentCompleteSort(a, b) { return a["percentComplete"] -
b["percentComplete"]; }
function comparer(a, b) { var x = a[sortcol], y = b[sortcol];
return (x == y ? 0 : (x > y ? 1 : -1)); }
function toggleFilterRow() {
grid.setTopPanelVisibility(!grid.getOptions().showTopPanel); }
$(".grid-header .ui-icon")
.addClass("ui-state-default ui-corner-all")
.mouseover(function (e) {
$(e.target).addClass("ui-state-hover")
})
.mouseout(function (e) {
$(e.target).removeClass("ui-state-hover")
});
$(function () { // prepare the data for (var i = 0; i < 50000;
i++) {
var d = (data[i] = {});
d["id"] = "id_" + i;
d["num"] = i;
d["title"] = "Task " + i;
d["duration"] = "5 days";
d["percentComplete"] = Math.round(Math.random() * 100);
d["start"] = "01/01/2009";
d["finish"] = "01/05/2009";
d["effortDriven"] = (i % 5 == 0); }
dataView = new Slick.Data.DataView({ inlineFilters: true }); grid
= new Slick.Grid("#myGrid", dataView, columns, options); grid.setSelectionModel(new Slick.RowSelectionModel());
var pager = new Slick.Controls.Pager(dataView, grid, $("#pager"));
var columnpicker = new Slick.Controls.ColumnPicker(columns, grid,
options); // columnpicker = new Slick.Controls.ColumnPicker(Columns,
Grid, GridOptions); //grid.setSelectedcolumn([]); // move the
filter panel defined in a hidden div into grid top panel
$("#inlineFilterPanel")
.appendTo(grid.getTopPanel())
.show();
grid.onCellChange.subscribe(function (e, args) {
dataView.updateItem(args.item.id, args.item); });
grid.onAddNewRow.subscribe(function (e, args) {
var item = {"num": data.length, "id": "new_" + (Math.round(Math.random() * 10000)), "title": "New task",
"duration":
"1 day", "percentComplete": 0, "start": "01/01/2009", "finish":
"01/01/2009", "effortDriven": false};
$.extend(item, args.item);
dataView.addItem(item); });
grid.onKeyDown.subscribe(function (e) {
// select all rows on ctrl-a
if (e.which != 65 || !e.ctrlKey) {
return false;
}
var rows = [];
for (var i = 0; i < dataView.getLength(); i++) {
rows.push(i);
}
grid.setSelectedRows(rows);
e.preventDefault(); });
grid.onSort.subscribe(function (e, args) {
sortdir = args.sortAsc ? 1 : -1;
sortcol = args.sortCol.field;
if ($.browser.msie && $.browser.version <= 8) {
// using temporary Object.prototype.toString override
// more limited and does lexicographic sort only by default, but can be much faster
var percentCompleteValueFn = function () {
var val = this["percentComplete"];
if (val < 10) {
return "00" + val;
} else if (val < 100) {
return "0" + val;
} else {
return val;
}
};
// use numeric sort of % and lexicographic for everything else
dataView.fastSort((sortcol == "percentComplete") ? percentCompleteValueFn : sortcol, args.sortAsc);
} else {
// using native sort with comparer
// preferred method but can be very slow in IE with huge datasets
dataView.sort(comparer, args.sortAsc);
} });
// wire up model events to drive the grid
dataView.onRowCountChanged.subscribe(function (e, args) {
grid.updateRowCount();
grid.render(); });
dataView.onRowsChanged.subscribe(function (e, args) {
grid.invalidateRows(args.rows);
grid.render(); });
dataView.onPagingInfoChanged.subscribe(function (e, pagingInfo) {
var isLastPage = pagingInfo.pageNum == pagingInfo.totalPages - 1;
var enableAddRow = isLastPage || pagingInfo.pageSize == 0;
var options = grid.getOptions();
if (options.enableAddRow != enableAddRow) {
grid.setOptions({enableAddRow: enableAddRow});
} });
var h_runfilters = null;
// wire up the slider to apply the filter to the model
$("#pcSlider,#pcSlider2").slider({
"range": "min",
"slide": function (event, ui) {
Slick.GlobalEditorLock.cancelCurrentEdit();
if (percentCompleteThreshold != ui.value) {
window.clearTimeout(h_runfilters);
h_runfilters = window.setTimeout(updateFilter, 10);
percentCompleteThreshold = ui.value;
}
} });
// wire up the search textbox to apply the filter to the model
$("#txtSearch,#txtSearch2").keyup(function (e) {
Slick.GlobalEditorLock.cancelCurrentEdit();
// clear on Esc
if (e.which == 27) {
this.value = "";
}
searchString = this.value;
updateFilter(); });
function updateFilter() {
dataView.setFilterArgs({
percentCompleteThreshold: percentCompleteThreshold,
searchString: searchString
});
dataView.refresh(); }
$("#btnSelectRows").click(function () {
if (!Slick.GlobalEditorLock.commitCurrentEdit()) {
return;
}
var rows = [];
for (var i = 0; i < 10 && i < dataView.getLength(); i++) {
rows.push(i);
}
grid.setSelectedRows(rows); });
// initialize the model after all the events have been hooked up
dataView.beginUpdate(); dataView.setItems(data);
dataView.setFilterArgs({
percentCompleteThreshold: percentCompleteThreshold,
searchString: searchString }); dataView.setFilter(myFilter); dataView.endUpdate();
// if you don't want the items that are not visible (due to being
filtered out // or being on a different page) to stay selected,
pass 'false' to the second arg dataView.syncGridSelection(grid,
true);
$("#gridContainer").resizable(); }) </script>
I think the easiest way is to only add the 3 columns you want to be visible to the "columns" variable.
If you want to show more columns at a later time you can add more columns on the fly (refer to this stackoverflow question on how to do this: Can I add a column to slickgrid on on the fly? )
Update: Example to only show the first 3 columns
insert this line:
columns = columns.slice(0, 3);
before the following line:
grid = new Slick.Grid("#myGrid", dataView, columns, options);