A minimal demonstration of how to create an legend
Step1:-complete the createLegend function
- add div element with class chart in your html file where you want to add graph
<div class="chart"></div>
<!--link d3 -->
<script src="https://d3js.org/d3.v6.min.js" charset="utf-8"></script>
first create createLegend function and add require parameters selection-selection is basically svg element ,data- it's legend data what you want display,graphWidth and graphHeight it's height and width of your graph,legendConfig-general configuration for graph
first we will check whether config data is there or not inside our createLegend function
if(!legendConfig){
legendConfig={
horizental:{
isRequired:false,
position:'top', //bottom or random positionPoint 20,30
},
position:'top',
vertical:{
isRequired:false,
positionAlongX:0,
positionAlongY:50
},
legendColor:'',
legendText:{
length:15,
fullword:true
}
}
}
- now we have to create a default color so if developer will not pass the color array we will consider the default color
//default color
// d3.schemeCategory10
let colorScale = d3.scaleOrdinal(data, d3.schemeCategory10)
- now let's create the toolTip
let svgCon=selection.append('g')
//legendConfig.vertical.isRequired used to consider legend should be vertical or horizental
.attr(`transform`,legendConfig.vertical.isRequired?
/**`translate(${legendConfig.vertical.positionAlongX},${legendConfig.vertical.positionAlongY})` where legend should be placed if it's vertiacll**/
`translate(${legendConfig.vertical.positionAlongX},${legendConfig.vertical.positionAlongY})`:`translate(20,50)`)
.selectAll('g')
.data(data)
.enter()
.append('g')
.attr('id',(d,i) => `tooltip${i}`)
.attr(`transform`,(d,i)=>rectPosition(legendConfig,i,graphHeight));
svgCon.append('text')
.text((d,i) =>
//legendText function is used how text should be display
legendText(d,legendConfig?.legendText?.length,legendConfig?.legendText?.fullword))
.attr('x', legendConfig.vertical.isRequired?20: (d,i) => {
if(i===0){
return 20;
}else{
return calculateWidth(i);
}
})
svgCon.append('rect')
.attr('width',20)
.attr('height',20)
.attr('fill', (d,i) =>{
return !legendConfig.legendColor[i]? colorScale(d):legendConfig.legendColor[i]
})
.attr('y',-15).attr('x',legendConfig.vertical.isRequired?-5:(d,i) => i===0?-5:calculateRectWidth(i))
}
- overall code for createLegend function
const rectPosition =(legendConfig,index,graphHeight) => {
if(legendConfig.vertical.isRequired){
return `translate(0,${index*25})`
}
if(legendConfig.horizental.position.includes(',')){
return `translate(${legendConfig.horizental.position})`
}
return `translate(0,${legendConfig.horizental.position==='top'?0:legendConfig.horizental.position==='bottom'?graphHeight-60:0})`
}
const legendText=(text,count=15,fullword=false) => {
let result =''
if(fullword){
result =text;
}else if(text.length>count && !fullword ){
result = text.substring(0,count).concat('...')
}else{
result =text;
}
return result;
}
const createLegend= (selection,data,graphWidth,graphHeight) => {
//default config
if(!legendConfig){
legendConfig={
horizental:{
isRequired:false,
position:'top', //bottom or random positionPoint 20,30
},
position:'top',
vertical:{
isRequired:false,
positionAlongX:0,
positionAlongY:50
},
legendColor:'',
legendText:{
length:15,
fullword:true
}
}
}
//default color
// d3.schemeCategory10
let colorScale = d3.scaleOrdinal(data, d3.schemeCategory10)
const calculateWidth = (length) => {
let sum=0;
for(let i=length-1;i>=0;i--){
let text_element = d3.select(`#tooltip${i}`)
sum= sum+ text_element.node().getBBox().width+60;
}
return sum;
}
const calculateRectWidth = (length) => {
return d3.select(`#tooltip${length}`).select('text').attr('x')-25
}
let svgCon=selection.append('g')
.attr(`transform`,legendConfig.vertical.isRequired?`translate(${legendConfig.vertical.positionAlongX},${legendConfig.vertical.positionAlongY})`:`translate(20,50)`)
.selectAll('g')
.data(data)
.enter()
.append('g')
.attr('id',(d,i) => `tooltip${i}`)
.attr(`transform`,(d,i)=>rectPosition(legendConfig,i,graphHeight));
svgCon.append('text')
.text((d,i) => legendText(d,legendConfig?.legendText?.length,legendConfig?.legendText?.fullword))
.attr('x', legendConfig.vertical.isRequired?20: (d,i) => {
if(i===0){
return 20;
}else{
return calculateWidth(i);
}
})
svgCon.append('rect')
.attr('width',20)
.attr('height',20)
.attr('fill', (d,i) =>{
return !legendConfig.legendColor[i]? colorScale(d):legendConfig.legendColor[i]
})
.attr('y',-15).attr('x',legendConfig.vertical.isRequired?-5:(d,i) => i===0?-5:calculateRectWidth(i))
}
Step2:-initialize all require value
<div class="chart"></div>
<!--link d3 -->
<script src="https://d3js.org/d3.v6.min.js" charset="utf-8"></script>
var data1 = ['Class A','Class B ','Class C','Class D','Class Matriculation','Class 12'];
let width=900;
let height =600;
let svgContainer =d3.select(".chart").append('svg').attr('width',width).attr('height',height)
let legendConfig={
horizental:{
position:'top', //bottom top or random positionPoint 20,30
},
position:'top',
vertical:{
isRequired:true,
positionAlongX:450,
positionAlongY:300
},
legendColor:['green','red','orange','yellow','pink'],
legendText:{
length:15,
fullword:true
}
}
// legendConfig.horizental.position
const rectPosition =(legendConfig,index,graphHeight) => {
if(legendConfig.vertical.isRequired){
return `translate(0,${index*25})`
}
if(legendConfig.horizental.position.includes(',')){
return `translate(${legendConfig.horizental.position})`
}
return `translate(0,${legendConfig.horizental.position==='top'?0:legendConfig.horizental.position==='bottom'?graphHeight-60:0})`
}
const legendText=(text,count=15,fullword=false) => {
let result =''
if(fullword){
result =text;
}else if(text.length>count && !fullword ){
result = text.substring(0,count).concat('...')
}else{
result =text;
}
return result;
}
const createLegend= (selection,data,graphWidth,graphHeight) => {
//default config
if(!legendConfig){
legendConfig={
horizental:{
isRequired:false,
position:'top', //bottom or random positionPoint 20,30
},
position:'top',
vertical:{
isRequired:false,
positionAlongX:0,
positionAlongY:50
},
legendColor:'',
legendText:{
length:15,
fullword:true
}
}
}
//default color
// d3.schemeCategory10
let colorScale = d3.scaleOrdinal(data, d3.schemeCategory10)
const calculateWidth = (length) => {
let sum=0;
for(let i=length-1;i>=0;i--){
let text_element = d3.select(`#tooltip${i}`)
sum= sum+ text_element.node().getBBox().width+60;
}
return sum;
}
const calculateRectWidth = (length) => {
return d3.select(`#tooltip${length}`).select('text').attr('x')-25
}
let svgCon=selection.append('g')
.attr(`transform`,legendConfig.vertical.isRequired?`translate(${legendConfig.vertical.positionAlongX},${legendConfig.vertical.positionAlongY})`:`translate(20,50)`)
.selectAll('g')
.data(data)
.enter()
.append('g')
.attr('id',(d,i) => `tooltip${i}`)
.attr(`transform`,(d,i)=>rectPosition(legendConfig,i,graphHeight));
svgCon.append('text')
.text((d,i) => legendText(d,legendConfig?.legendText?.length,legendConfig?.legendText?.fullword))
.attr('x', legendConfig.vertical.isRequired?20: (d,i) => {
if(i===0){
return 20;
}else{
return calculateWidth(i);
}
})
svgCon.append('rect')
.attr('width',20)
.attr('height',20)
.attr('fill', (d,i) =>{
return !legendConfig.legendColor[i]? colorScale(d):legendConfig.legendColor[i]
})
.attr('y',-15).attr('x',legendConfig.vertical.isRequired?-5:(d,i) => i===0?-5:calculateRectWidth(i))
}
Step3:-call the function
createLegend(svgContainer,data1,width,height)
Step4:-change graph configuration according to your requirement
legend config for the horizontal legend at top
let legendConfig={
horizental:{
position:'200,90', //bottom top or random positionPoint 20,30
},
position:'top',
vertical:{
isRequired:false,
positionAlongX:450,
positionAlongY:300
},
legendColor:['green','red','orange','yellow','pink'],
legendText:{
length:15,
fullword:false
}
legend config for the vertical legend at center
let legendConfig={
horizental:{
position:'top', //bottom top or random positionPoint 20,30
},
position:'top',
vertical:{
isRequired:true,
positionAlongX:450,//it should be width/2
positionAlongY:300,//it should be height/2
},
legendColor:['green','red','orange','yellow','pink'],
legendText:{
length:15,
fullword:false
}
}
for color config you can assign array of color or just simply used d3 method to generate array of color
let legendConfig={
horizental:{
position:'top', //bottom top or random positionPoint 20,30
},
position:'top',
vertical:{
isRequired:true,
positionAlongX:450,
positionAlongY:300
},
legendColor:d3.schemeCategory10,//used d3 method to get array of color
legendText:{
length:15,
fullword:false
}
}
if you don't want to display whole word if text is large and you want to display upto some length then set the as given below
legendText:{
length:15,//word size
fullword:false
}
if you want to dispaly whole word then set the property
legendText:{
length:15,
fullword:true
}
Top comments (0)