Published unlisted
Edited
May 11, 2022
Insert cell
Insert cell
<div id='here'></div>
Insert cell
tbl =
[{ "Month": 1, "Value": 14841 }, { "Month": 2, "Value": 24467 }, { "Month": 3, "Value": 78423 }, { "Month": 4, "Value": 60213 }, { "Month": 5, "Value": 87257 }, { "Month": 6, "Value": 21543 }, { "Month": 7, "Value": 21373 }, { "Month": 8, "Value": 87363 }, { "Month": 9, "Value": 50378 }, { "Month": 10, "Value": 29714 }, { "Month": 11, "Value": 20171 }, { "Month": 12, "Value": 70059 }]
Insert cell
w = width // 1280
Insert cell
height = 720
Insert cell
{
//the chart X and Y Axis needs to start from 0
tbl.filter(a => (a.Month == 0)).length == 0 ? tbl.unshift({ "Month": 0, "Value": 0 }) : tbl

const monthCount = tbl.length - 1;

// const w = 1280;
// const height = 720;

//*-------2. DRAW CHART STRUCTURE (SVG HEIGHT,WIDTH, VBOX ETC)----------*//
const glblDim = {
height: height,
width: w,
margin: {
top: 20,
right: 20,
bottom: 35, // fontsize + 5
left: 50
}
}
glblDim.boundedWidth = glblDim.width - glblDim.margin.left - glblDim.margin.right;
glblDim.boundedHeight = glblDim.height - glblDim.margin.top - glblDim.margin.bottom;

//namespace
const svgns = 'http://www.w3.org/2000/svg'
let svg = d3.select('#here')
.append('svg')
.attr('xmlns', svgns)
.attr("viewBox", `0 0 ${w} ${height}`);

const bound = svg.append('g')
.attr('class', 'bound') //this is the inner portion where the drawing gets made
.style('transform', `translate(${glblDim.margin.left}px, ${glblDim.margin.top}px)`)

// //*--------------------------3. SCALE----------------------------------*//
//generate range X
const rangeX = d3.scaleLinear().range([0, glblDim.boundedWidth]);

//generate scale first X
var scaleX = rangeX.domain(d3.extent(tbl, d => d.Month))


//generate rangeY
const rangeY = d3.scaleLinear().range([glblDim.boundedHeight, 0]);

//generate scale first Y
var scaleY = rangeY.domain(d3.extent(tbl, d => d.Value))

// //*--------------------------3.COLOR SCALE----------------------------------*//
const interpolatorSequentialMultiHueName = [ 'd3.interpolateTurbo', 'd3.interpolateViridis', 'd3.interpolateInferno' ]
const xColorScale = d3.scaleSequential()
.domain(d3.extent(tbl, d => d.Month))
.interpolator(eval(`${interpolatorSequentialMultiHueName[1]}`))

//-----------------4.AXES----------------------------------------------//
//generate Y Axis
bound.append('g')
.call(d3.axisLeft(scaleY).tickSizeOuter(0)) //removes the outer tick of the axis
.attr('class', 'YAxis')
.call(d => d.select('.domain') //change Axis class name
.attr('class', 'yAxis'))
.call(d => d.selectAll('.tick') //change the tick class name
.attr('class', (d, i) => { return `yAxisTick${i}` }))
.call(d => d.select('.yAxisTick0') //change the opacity of the first tick to 0
.attr('opacity', 0.5))


//generate X Axis
bound.append('g')
.call(d3.axisBottom(scaleX).tickSizeOuter(0) /*.tickSizeInner(-(glblDim.boundedHeight))*/ ) //removes the outer tick of the axis
.attr('class', 'XAxis')
//.style('stroke-width', '0.5')
.style('transform', `translateY(${glblDim.boundedHeight}px)`)
.call(d => d.select('.domain') //change Axis class name
.attr('class', 'xAxis'))
.call(d => d.selectAll('.tick') //change the tick class name
.attr('class', (d, i) => { return `xAxisTick${i}` }))
.call(d => d.select('.xAxisTick0') //chnage the opacity of the first tick to 0
.attr('opacity', 0))
.call(a => a.selectAll("text")
.attr("fill", d => { return xColorScale(d) })
.style("font-size", '30px')
)


.call(a => a.append('g').attr('id','Rects')
.attr('class', 'bRect')
.selectAll('rect') //inherits class="XAxis" properties
.data(d3.range(0,12)) //d3.selectAll("[class^=xAxisTick]:not(:last-child)"))
.enter()
.append('rect')
.attr('x', '0')
.attr('y', '0')
.attr('height', `${glblDim.boundedHeight}`)
.attr('width', `${scaleX(1)}`)
.attr('class', (d, i) => { return `bgRect${i}` })
.style('fill', (d, i) => { return xColorScale(i + 1) })
.style('stroke', 'black')
.style('stroke-opacity', '0.1')
.attr('transform', (d, i) => {
const attributeX = d*scaleX(1) // d.getAttribute('transform').match(/(\d+\.\d+)(?=\,)|(\d+)(?=\,)/gm)
const attributeY = glblDim.boundedHeight * -1;
return `translate(${attributeX} ${attributeY})`
})
)
.call(a => a.selectAll("text")
.attr("fill", (d, i) => { return xColorScale(i) })
.style("font-size", '30px')
)

}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more