Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <!doctype html>
- <html>
- <head>
- <style>
- </style>
- <script src="https://d3js.org/d3.v7.min.js"></script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.25.6/d3-legend.min.js"></script>
- </head>
- <body id="svg_wrapper">
- <div id="sample"></div>
- <script>
- const data = [
- { name: 'Jan-Feb', sunshine: 0.74 },
- { name: 'Feb-Mar', sunshine: 37.5 },
- { name: 'Mar-Apr', sunshine: 14.97 },
- { name: 'Apr-May', sunshine: 30.6977 },
- { name: 'May-Jun', sunshine: 10.6762 },
- { name: 'Jun-Jul', sunshine: 2.2508 },
- { name: 'Jul-Aug', sunshine: 11.0063 },
- { name: 'Aug-Sept', sunshine: 20.1413 },
- { name: 'Sept-Oct', sunshine: 14.6018 },
- { name: 'Oct-Nov', sunshine: 41.4508 },
- { name: 'Nov-Dec', sunshine: 6.19 },
- ];
- function ramp(color, n = 256) {
- const canvas = document.createElement("canvas");
- canvas.width = n;
- canvas.height = 1;
- const context = canvas.getContext("2d");
- for (let i = 0; i < n; ++i) {
- context.fillStyle = color(i / (n - 1));
- context.fillRect(i, 0, 1, 1);
- }
- return canvas;
- }
- //Mike Bostock's Legend class implementation from https://observablehq.com/@d3/color-legend
- function Legend(color, {
- title,
- tickSize = 6,
- width = 320,
- height = 44 + tickSize,
- marginTop = 18,
- marginRight = 0,
- marginBottom = 16 + tickSize,
- marginLeft = 0,
- ticks = width / 64,
- tickFormat,
- tickValues
- } = {}) {
- function ramp(color, n = 256) {
- const canvas = document.createElement("canvas");
- canvas.width = n;
- canvas.height = 1;
- const context = canvas.getContext("2d");
- for (let i = 0; i < n; ++i) {
- context.fillStyle = color(i / (n - 1));
- context.fillRect(i, 0, 1, 1);
- }
- return canvas;
- }
- const svg = d3.create("svg")
- .attr("width", width)
- .attr("height", height)
- .attr("viewBox", [0, 0, width, height])
- .style("overflow", "visible")
- .style("display", "block");
- let tickAdjust = g => g.selectAll(".tick line").attr("y1", marginTop + marginBottom - height);
- let x;
- // Continuous
- if (color.interpolate) {
- const n = Math.min(color.domain().length, color.range().length);
- x = color.copy().rangeRound(d3.quantize(d3.interpolate(marginLeft, width - marginRight), n));
- svg.append("image")
- .attr("x", marginLeft)
- .attr("y", marginTop)
- .attr("width", width - marginLeft - marginRight)
- .attr("height", height - marginTop - marginBottom)
- .attr("preserveAspectRatio", "none")
- .attr("xlink:href", ramp(color.copy().domain(d3.quantize(d3.interpolate(0, 1), n))).toDataURL());
- }
- // Sequential
- else if (color.interpolator) {
- x = Object.assign(color.copy()
- .interpolator(d3.interpolateRound(marginLeft, width - marginRight)),
- { range() { return [marginLeft, width - marginRight]; } });
- svg.append("image")
- .attr("x", marginLeft)
- .attr("y", marginTop)
- .attr("width", width - marginLeft - marginRight)
- .attr("height", height - marginTop - marginBottom)
- .attr("preserveAspectRatio", "none")
- .attr("xlink:href", ramp(color.interpolator()).toDataURL());
- // scaleSequentialQuantile doesnโt implement ticks or tickFormat.
- if (!x.ticks) {
- if (tickValues === undefined) {
- const n = Math.round(ticks + 1);
- tickValues = d3.range(n).map(i => d3.quantile(color.domain(), i / (n - 1)));
- }
- if (typeof tickFormat !== "function") {
- tickFormat = d3.format(tickFormat === undefined ? ",f" : tickFormat);
- }
- }
- }
- // Threshold
- else if (color.invertExtent) {
- const thresholds
- = color.thresholds ? color.thresholds() // scaleQuantize
- : color.quantiles ? color.quantiles() // scaleQuantile
- : color.domain(); // scaleThreshold
- const thresholdFormat
- = tickFormat === undefined ? d => d
- : typeof tickFormat === "string" ? d3.format(tickFormat)
- : tickFormat;
- x = d3.scaleLinear()
- .domain([-1, color.range().length - 1])
- .rangeRound([marginLeft, width - marginRight]);
- svg.append("g")
- .selectAll("rect")
- .data(color.range())
- .join("rect")
- .attr("x", (d, i) => x(i - 1))
- .attr("y", marginTop)
- .attr("width", (d, i) => x(i) - x(i - 1))
- .attr("height", height - marginTop - marginBottom)
- .attr("fill", d => d);
- tickValues = d3.range(thresholds.length);
- tickFormat = i => thresholdFormat(thresholds[i], i);
- }
- // Ordinal
- else {
- x = d3.scaleBand()
- .domain(color.domain())
- .rangeRound([marginLeft, width - marginRight]);
- svg.append("g")
- .selectAll("rect")
- .data(color.domain())
- .join("rect")
- .attr("x", x)
- .attr("y", marginTop)
- .attr("width", Math.max(0, x.bandwidth() - 1))
- .attr("height", height - marginTop - marginBottom)
- .attr("fill", color);
- tickAdjust = () => { };
- }
- svg.append("g")
- .attr("transform", `translate(0,${height - marginBottom})`)
- .call(d3.axisBottom(x)
- .ticks(ticks, typeof tickFormat === "string" ? tickFormat : undefined)
- .tickFormat(typeof tickFormat === "function" ? tickFormat : undefined)
- .tickSize(tickSize)
- .tickValues(tickValues))
- .call(tickAdjust)
- .call(g => g.select(".domain").remove())
- .call(g => g.append("text")
- .attr("x", marginLeft)
- .attr("y", marginTop + marginBottom - height - 6)
- .attr("fill", "currentColor")
- .attr("text-anchor", "start")
- .attr("font-weight", "bold")
- .attr("class", "title")
- .text(title));
- return svg.node();
- }
- const width = 1200;
- const height = 450;
- const margin = { top: 50, bottom: 50, left: 50, right: 50 };
- const svg = d3.select("#sample")
- .append('svg')
- .attr('width', width - margin.left - margin.right)
- .attr('height', height - margin.top - margin.bottom)
- .attr("viewBox", [0, 0, width, height]);
- const x = d3.scaleBand()
- .domain(data.map(d => d.name))
- .range([margin.left, width - margin.right])
- .padding(0.1)
- const y = d3.scaleLinear()
- .domain([0, 50])
- .range([height - margin.bottom, margin.top])
- //var colorScale = d3.scaleLinear()
- //.domain([0, 100])
- //.range(["steelblue", "blue"]);
- //const legend = d3.legendColor().scale(colorScale)
- //Mike Bostock's continuous legend call
- const legend = Legend(d3.scaleQuantize([0, 50], d3.schemePurples[8]), {
- title: "Absolute value percentage change of sunshine (%)"
- })
- svg
- .append("g")
- .selectAll("rect")
- .data(data)
- .join("rect")
- .attr("fill", function (d) {
- d = d.sunshine
- if (d < 6.25) {
- return d3.schemePurples[8][1];
- } else if (d < 12.5) {
- return d3.schemePurples[8][1];
- }
- else if (d < 18.75) {
- return d3.schemePurples[8][2];
- }
- else if (d < 25) {
- return d3.schemePurples[8][3];
- }
- else if (d < 31.25) {
- return d3.schemePurples[8][4];
- }
- else if (d < 37.5) {
- return d3.schemePurples[8][5];
- }
- else if (d < 43.75) {
- return d3.schemePurples[8][6];
- }
- else {
- return d3.schemePurples[8][7];
- }
- })
- .attr("x", (d, i) => x(d.name))
- .attr("y", d => y(d.sunshine))
- .attr('title', (d) => d.sunshine)
- .attr("class", "rect")
- .attr("height", d => y(0) - y(d.sunshine))
- .attr("width", x.bandwidth())
- //Adding data values on the bar
- svg
- .selectAll("rect")
- .data(data)
- .enter()
- .append("text")
- .text((function (data) { return data.sunshine }))
- .attr("class", "text2")
- function yAxis(g) {
- g.attr("transform", `translate(${margin.left}, 0)`)
- .call(d3.axisLeft(y))
- .attr("font-size", '15px')
- svg.append("text")
- .attr("text-anchor", "end")
- .attr("transform", "rotate(-90)")
- .attr("y", -margin.left + 20)
- .attr("x", -margin.top)
- .text("Percentage Changes of Sunshine for 2 Consecutive Months")
- }
- function xAxis(g) {
- g.attr("transform", `translate(0,${height - margin.bottom})`)
- .call(d3.axisBottom(x))
- .attr("font-size", '20px')
- g.append("text")
- .attr("text-anchor", "end")
- .attr("y", height + margin.top + 100)
- .attr("x", width)
- .text("Months");
- }
- //(Attempt to) Add data to the top of rectangles
- svg.selectAll("rect")
- .data(data)
- .enter().append("rect")
- .attr("height", function (d, i) { return (d.sunshine * 10) })
- .attr("width", "40")
- .attr("x", function (d, i) { return (i * 60) + 25 })
- .attr("y", function (d, i) { return 400 - (d.sunshine * 10) });
- svg.append("g").call(xAxis);
- svg.append("g").call(yAxis);
- svg.append(() => legend)
- .attr("x", -margin.top + 100)
- //Attempt to add x-axis label but its not centered
- let textnode = document.createTextNode("Months in a Year");
- document.getElementById("sample").appendChild(textnode);
- svg.node();
- </script>
- </body>
- </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement