Commit 6828d011 authored by alain's avatar alain 🐙
Browse files

support log scale

parent 2297bdf0
......@@ -67,6 +67,7 @@ class DeckLayers extends React.Component {
data: layerData,
range: unit.range,
legend: unit.legend,
scale: unit.scale,
conversion: unit.conversion,
sides: source.sides,
angle: source.angle,
......
import { CompositeLayer } from '@deck.gl/core'
import { ColumnLayer } from '@deck.gl/layers'
import { scaleLinear } from "d3-scale"
import { scaleLinear, scaleLog } from "d3-scale"
import { color, getColorArray } from "../util/color.js"
import { setMetersOffset } from "../util/plot"
......@@ -16,6 +16,7 @@ const radiusScale = scaleLinear([mapControlSettings.zoomMax, mapControlSettings.
const heightMaxScale = scaleLinear([mapControlSettings.zoomMax, mapControlSettings.zoomMin], [mapItemSettings.elevationMaxMin, mapItemSettings.elevationMaxMax])
class StationLayer extends CompositeLayer {
getCoordinates(d, count, radius) {
......@@ -48,12 +49,12 @@ class StationLayer extends CompositeLayer {
renderLayers() {
const { id, count, data, range, legend, factor, zoom, sides } = this.props
const { id, count, data, range, legend, scale, factor, zoom, sides } = this.props
const radius = radiusScale(zoom) * factor * (count.total > 1 ? 0.5 : 1)
const getHeight = (value, zoom) => {
const renderValue = Math.min(value, range[1])
const elevationScale = scaleLinear(range, [0, heightMaxScale(zoom)])
const elevationScale = (scale === 'log' ? scaleLog(range, [0, heightMaxScale(zoom)]) : scaleLinear(range, [0, heightMaxScale(zoom)]))
return elevationScale(renderValue)
}
......@@ -90,7 +91,7 @@ class StationLayer extends CompositeLayer {
if(d.mean === null) {
return getColorArray("#ccc")
} else {
return getColorArray(color(d.mean, legend))
return getColorArray(color(d.mean, legend, (scale === 'log')))
}
},
updateTriggers: {
......
......@@ -3,6 +3,8 @@ import ReactHtmlParser from 'react-html-parser'
import { connect } from 'react-redux'
import { scaleLinear, scaleLog } from 'd3-scale'
import { ResponsiveContainer, ComposedChart, LineChart, Area, Line, XAxis, YAxis, Brush, Tooltip } from "recharts"
import ChartTooltip from "./ChartTooltip"
......@@ -19,6 +21,7 @@ const moment = extendMoment(Moment)
const start = getMonthsAgoHourISO(3)
const end = getNowISO()
//const scale = scaleLog()
class StationInfo extends React.Component {
constructor(props) {
......@@ -132,10 +135,13 @@ class StationInfo extends React.Component {
render() {
moment().locale("nl", localization)
if(!this.state.unit) return null
const { stationMeta, data, chartHeight, downloadForm, unit } = this.state
const { id, source } = this.props.clickedObject
const parameter = this.props.activeLayer
const yScale = (unit && unit.scale === 'log' ? scaleLog().domain(unit.range) : scaleLinear().domain(unit.range))
const lineStyle = (data && data[0].minmax ? { stroke:"#000000" } : { stroke:"url(#yaxis)" } )
const lineClass = (data && data[0].minmax ? "dashed" : "solid" )
......@@ -194,12 +200,16 @@ class StationInfo extends React.Component {
<ComposedChart data={data} margin={{ top: 0, right: 30, left: 0, bottom: 10 }}>
<defs>
<linearGradient id="yaxis" x1="0" y1="0" x2="0" y2={chartHeight - 80} gradientUnits="userSpaceOnUse">
{ Object.keys(unit.legend).sort((a,b) => b-a).map(s => <stop key={s} offset={`${(unit.range[1]-s)/unit.range[1] * 100}%`} stopColor={unit.legend[s].color} />) }
{
//Object.keys(unit.legend).sort((a,b) => b-a).map(s => <stop key={s} offset={`${(unit.range[1]-s)/unit.range[1] * 100}%`} stopColor={unit.legend[s].color} />)
Object.keys(unit.legend).sort((a,b) => b-a).map(s => <stop key={s} offset={`${100 - (yScale(s) * 100)}%`} stopColor={unit.legend[s].color} />)
}
</linearGradient>
</defs>
<XAxis type="number" scale="time" domain={['auto', 'auto']} dataKey="timestamp" padding={{ left: 6 }} tickFormatter={this.xAxisTickFormatter} tickSize={4} ticks={this.state.xAxisTicks} />
<YAxis type="number" strokeWidth="6" stroke="url(#yaxis)" width={30} height={chartHeight} domain={unit.range} tickSize={4} tickLine={{ strokeWidth: 1 }} allowDataOverflow={true} />
<YAxis type="number" strokeWidth="6" stroke="url(#yaxis)" width={100} ticks={(unit.ticks ? unit.ticks : Object.keys(unit.legend))} height={chartHeight} domain={unit.range} tickSize={4} tickLine={{ strokeWidth: 1 }} allowDataOverflow={true} scale={yScale} />
{/* <YAxis scale="log" /> */}
<Tooltip content={ ChartTooltip } animationDuration={0} unit={unit.label} />
......@@ -211,8 +221,8 @@ class StationInfo extends React.Component {
startIndex={ (data.length - 7*24 > 0 ? data.length - 7*24 : 0) }
tickFormatter={this.xAxisTickFormatter} >
<LineChart>
<Line type="natural" dataKey="value" stroke="#ccc" dot={false} />
<YAxis domain={unit.range} tick={false} width={0} />
<Line type="natural" dataKey="value" stroke="#aaa" dot={false} />
<YAxis domain={unit.range} tick={false} width={0} scale={yScale} />
</LineChart>
</Brush>
</ComposedChart>
......
import React from 'react'
import ReactHtmlParser from 'react-html-parser'
import { scaleLinear, scaleLog } from 'd3-scale'
const Legend = (props) => {
const { unit } = props
const scale = (unit && unit.scale === 'log' ? scaleLog().domain(unit.range) : scaleLinear().domain(unit.range))
return (
<div className="tooltip">
<div className="legend">
......@@ -15,7 +19,8 @@ const Legend = (props) => {
<defs>
<linearGradient id={`legend-${unit.id}`} x1="0" y1="0" x2="236" y2="8" gradientUnits="userSpaceOnUse">
{ Object.keys(unit.legend).sort((a,b) => a-b).map(s => {
return <stop key={s} offset={`${(s-unit.range[0])/(unit.range[1]-unit.range[0]) * 100}%`} stopColor={unit.legend[s].color} />
//return <stop key={s} offset={`${(s-unit.range[0])/(unit.range[1]-unit.range[0]) * 100}%`} stopColor={unit.legend[s].color} />
return <stop key={s} offset={`${(scale(s) * 100)}%`} stopColor={unit.legend[s].color} />
}) }
</linearGradient>
</defs>
......
import { rgb, hsl } from "d3-color"
import { scaleLinear } from "d3-scale"
import { scaleLinear, scaleLog } from "d3-scale"
import { interpolateCubehelix } from "d3-interpolate"
export const color = (value, legend) => {
export const color = (value, legend, log = false) => {
const domain = Object.keys(legend).sort((a,b) => a-b)
const range = domain.map(k => legend[k].color)
const scale = scaleLinear().domain(domain).interpolate(interpolateCubehelix.gamma(0.5)).range(range)
const scale = (log ? scaleLog().domain(domain).interpolate(interpolateCubehelix.gamma(0.5)).range(range) : scaleLinear().domain(domain).interpolate(interpolateCubehelix.gamma(0.5)).range(range))
return scale(value)
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment