Published
Edited
Jan 27, 2021
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
interval = d3.timeMonth.every(1)
Insert cell
function barz() {
const height = 160;

const margin = { left: 225, right: 250, top: 0, bottom: 40 };
const svg = d3.create("svg").attr("viewBox", [0, 0, width, height]);

let minX = 0,
maxX = 0;
const brush = d3
.brushX()
.extent([
[margin.left, margin.top],
[width - margin.right, height - margin.bottom]
])
.on("brush end", brushed);

const x = d3
.scaleTime()
.range([margin.left, width - margin.right])
.domain([
d3.min(fakeData, d => d.monthly),
d3.timeMonth.ceil(+d3.max(fakeData, d => d.monthly) + 1)
]);

const xAxis = g =>
g
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x));

const y = d3
.scaleLinear()
.domain([0, maxSpeciesPerMonth])
.range([height - margin.bottom, margin.top]);

const yAxis = g =>
g.call(d3.axisLeft(y)).call(g => g.select(".domain").remove());

svg.append('g').call(xAxis);

svg.append('g').call(yAxis);

svg
.selectAll('rect')
// .data(fakeData)
.data(monthlySpeciesCount)
// .data(fakeData)
.enter()
.append('rect')
.attr('x', d => x(d.monthly))
.attr('y', d => {
return y(d.value);
})
.attr('width', d => x(d3.timeMonth.ceil(+d.monthly + 1)) - x(d.monthly) - 1)
.attr('height', d => y(0) - y(d.value))
.attr('fill', d => "rgb(201, 37, 41)");

let returnValue = Object.assign(svg.node(), {
value: {
range: [minX, maxX]
}
});

// add 1 month to make sure we include the latest month in initial brush
const end_date = _.clone(
monthlySpeciesCount[monthlySpeciesCount.length - 1].monthly
);

svg
.append("g")
.call(brush)
.call(
brush.move,
[
monthlySpeciesCount[0].monthly,
new Date(end_date.setMonth(end_date.getMonth() + 1))
].map(x)
);

function brushed(event) {
const selection = event.selection;
const node = svg.node();
if (selection === null) {
} else {
const d0 = selection.map(x.invert);
const d1 = d0.map(interval.round);

// If empty when rounded, use floor instead.
if (d1[0] >= d1[1]) {
d1[0] = interval.floor(d0[0]);
d1[1] = interval.offset(d1[0]);
}

node.val = d0;
output({
range: [d0[0], d0[1]]
});
}
}

function output(value) {
const node = svg.node();
node.value = value;

node.dispatchEvent(new CustomEvent('input'));
}

return returnValue;
}
Insert cell
date = _.clone(monthlySpeciesCount[3].monthly)
Insert cell
// heatData.filter(d => types.includes(d.class))
Insert cell
chart2 = function(types) {
// console.clear();
const n = types.length;
const width = 860;
// const height = 500;

// All speceis in types ploted
const Allspecies = [
...new Set(
heatData.filter(d => types.includes(d.class)).map(d => d.species)
)
];
// console.log(Allspecies.length * 20);
const height = Allspecies.length * 20;
// console.log("height", height);

//Calculate margins to use

const to_chart_species = [
...new Set(heatData.filter(d => d.class === types[0]).map(d => d.species))
];

// this will be the bottom of the top chart (based on proportion of species)
// const bh_top_chart = (height * to_chart_species.length) / Allspecies.length;
// console.log("bh_top_chart", bh_top_chart);

const margin1 = { top: 20, right: 40, bottom: 40, left: 140 }; //adjust bottom
const chart_width = width - margin1.left - margin1.right;
// const chart_height = height - margin1.top - margin1.bottom;

let margin_others;

// const zoom = d3
// .zoom()
// .scaleExtent([1, Infinity])
// .translateExtent([[0, 0], [chart_width, chart_bounds]])
// .extent([[0, 0], [chart_width, chart_bounds]]);

const svg = d3.select(DOM.svg(width, height));

const today = new Date();
const startExt = new Date();
const endExt = new Date();

startExt.setDate(today.getDate() - 1);
endExt.setDate(today.getDate() + 1);

// HERE I CREATE A CHART (FOCUS) FOR EACH VARIABLE.
let myVariables = {};
let myLines = {};
let myYs = {};
let myXs = {};
let y;

// let focus0;
const x = d3
.scaleTime()
.range([0, chart_width])
.domain([
d3.min(heatData, d => d.monthly),
d3.timeMonth.ceil(+d3.max(heatData, d => d.monthly) + 1)
]);

const xAxis = d3.axisBottom(x);
const top_margins = [];

types.forEach((vari, i) => {
let yside = "y" + i;

const species = [
...new Set(heatData.filter(d => d.class === vari).map(d => d.species))
];

let h_each_plot = (height * species.length) / Allspecies.length;
top_margins.push(h_each_plot);

let chart_bounds =
(height * species.length) / Allspecies.length -
margin1.top -
margin1.bottom;
// console.log(chart_bounds);

y = d3
.scaleBand()
.domain(species)
.range([chart_bounds, 0])
.padding(.2);

const yAxis = g =>
g.call(d3.axisLeft(y)).call(g => g.select(".domain").remove());

const mar_top =
i === 0
? 0
: i === 1
? top_margins[0]
: d3.sum(top_margins.slice(0, [i]));

margin_others = {
top: mar_top,
right: 20,
left: 140
}; //adjust top

let variableName = "focus" + i;

myVariables[variableName] = svg
.append("g")
.attr("class", "focus" + i)
.attr(
"transform",
`translate(${margin_others.left},${margin_others.top})`
);

myVariables[variableName]
.selectAll('rect')
.data(heatData.filter(d => d.class === vari))
.enter()
.append('rect')
.attr("class", "line" + i)
.attr('x', d => x(d.monthly))
.attr('y', d => {
return y(d.species);
})
.attr(
'width',
d => x(d3.timeMonth.ceil(+d.monthly + 1)) - x(d.monthly) - 4
)
.attr('height', y.bandwidth())
.attr('fill', d => {
return d.value > 0 ? "rgb(201, 37, 41)" : "#ddd";
})
// .attr("fill", "none")
.attr("clip-path", "url(#clip)");
// .style("stroke", "steelblue")
// .style("stroke-width", "1.5px");

myVariables[variableName]
.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + chart_bounds + ")")
.call(xAxis);

myVariables[variableName]
.append("g")
.attr("class", "axis axis--y")
.call(yAxis);
});

return svg.node();
}
Insert cell
heatData = fakeData.filter(d => {
return (
d.monthly >= d3.timeMonth(cc.range[0]) &&
d.monthly <= d3.timeMonth(cc.range[1])
);
})
Insert cell
cc.range
Insert cell
d3.timeMonth(cc.range[0])
Insert cell
cc.range
Insert cell
monthlySpeciesCount[0]
Insert cell
md`
### Group by count of species per month
`
Insert cell
speciesCountbyMonth = d3.rollup(
fakeData,
v =>
d3.sum(v, d => {
d.count;
d.value > 0 ? (d.count = 1) : (d.count = 0);
return d.count;
}),
d => +d.monthly
)
Insert cell
monthlySpeciesCount = Array.from(speciesCountbyMonth, ([key, values]) => {
return {
monthly: new Date(key),
// datestr: key,
value: values
};
})
Insert cell
maxSpeciesPerMonth = d3.max(
Array.from(speciesCountbyMonth, ([key, values]) => {
return values;
})
)
Insert cell
monthsAtSite = [...new Set(fakeData.map(d => d.monthly.toISOString()))]
Insert cell
chartData = flatData.filter(d => d.site === "Victoria")
Insert cell
fakeData = {
let out = _.cloneDeep(chartData);
let a = _.cloneDeep(chartData);
a.forEach(d => {
Number(d.monthly) === Number(d3.timeMonth.ceil(new Date("2019-07-01")))
? (d.monthly = d3.timeMonth.ceil(new Date("2019-01-01")))
: d.monthly,
Number(d.monthly) === Number(d3.timeMonth.ceil(new Date("2019-08-01")))
? (d.monthly = d3.timeMonth.ceil(new Date("2019-04-01")))
: d.monthly,
d.mmyy === "07/2019"
? (d.mmyy = "01/2019")
: d.mmyy === "08/2019"
? (d.mmyy = "03/2019")
: (d.mmyy = "04/2019");
d.mm === "07"
? (d.mm = "01")
: d.mm === "08"
? (d.mm = "03")
: (d.mm = "04");
out.push(d);
});

return out.sort((a, b) => Number(a.mm) - Number(b.mm));
}
Insert cell
Number(fakeData[0].monthly) ===
Number(d3.timeMonth.ceil(new Date("2019-07-01")))
Insert cell
d3.timeMonth.ceil(new Date("2019-01-01"))
Insert cell
import { rangeSlider } from "@bumbeishvili/utils"
Insert cell
flatData
Insert cell
_ = require("lodash")
Insert cell
import { flatData, speciesList, bcSiteLocs, uniqClass } from 'a918fce3c1f416e8'
Insert cell
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